# List of test case sources (Only these get parsed for test cases)
SET(TC_SOURCES
utc-Dali-PushButton.cpp
- utc-Dali-TextView-HelperAndDebug.cpp
- utc-Dali-TextView-Processor-Types.cpp
- utc-Dali-TextView-Processor.cpp
- utc-Dali-TextView-Relayout-Utilities.cpp
- utc-Dali-TextView.cpp
)
# Append list of test harness files (Won't get parsed for test cases)
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-
-#include <stdlib.h>
-#include <dali-toolkit-test-suite-utils.h>
-#include <dali-toolkit/dali-toolkit.h>
-
-// Internal headers are allowed here
-#include <dali-toolkit/internal/controls/text-view/split-by-new-line-char-policies.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-helper-functions.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-dbg.h>
-
-using namespace Dali;
-using namespace Dali::Toolkit;
-using namespace Dali::Toolkit::Internal;
-
-void dali_text_view_helper_and_debug_startup(void)
-{
- test_return_value = TET_UNDEF;
-}
-
-void dali_text_view_helper_and_debug_cleanup(void)
-{
- test_return_value = TET_PASS;
-}
-
-
-namespace
-{
-// Data structures used to create an 'experiment' in TET cases
-
-const Toolkit::Internal::TextView::LayoutParameters DEFAULT_LAYOUT_PARAMETERS;
-const Toolkit::Internal::TextView::VisualParameters DEFAULT_VISUAL_PARAMETERS;
-
-struct GetIndicesFromGlobalCharacterIndexTest
-{
- std::string description;
- std::string input;
- std::size_t position;
- std::size_t paragraphIndex;
- std::size_t wordIndex;
- std::size_t characterIndex;
-};
-
-/**
- * Gets the paragraph, word, and character indices for a given text and a given position and checks the results with the given indices.
- *
- * If the test fails it prints a short description and the line where this function was called.
- *
- * @param description Short description of the experiment.
- * @param input The input text.
- * @param position Global position of the character. i.e in a text with with 1000 characters, position could be any value from 0 to 1000.
- * @param resultParagraphIndex Index to the paragraph where the character is located.
- * @param resultWordIndex Index to the word within the paragraph where the character is located.
- * @param resultCharacterIndex Index to the character within the word where the character is located.
- * @param location Where this function has been called.
- *
- * @return \e true if the experiment is successful. Otherwise returns \e false.
- */
-bool TestGetIndicesFromGlobalCharacterIndex( const std::string& description,
- const std::string& input,
- const std::size_t position,
- const std::size_t resultParagraphIndex,
- const std::size_t resultWordIndex,
- const std::size_t resultCharacterIndex,
- const char* location )
-{
- tet_printf( "%s", description.c_str() );
-
- // Create natural size, layout and text-actor info for the input word.
- Toolkit::Internal::TextView::RelayoutData relayoutData;
- TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray inputStyledText;
- MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
-
- TextViewProcessor::CreateTextInfo( inputStyledText,
- DEFAULT_LAYOUT_PARAMETERS,
- relayoutData );
-
- TextViewProcessor::TextInfoIndices indices;
- TextViewProcessor::GetIndicesFromGlobalCharacterIndex( position,
- inputLayout,
- indices );
-
- if( indices.mParagraphIndex != resultParagraphIndex )
- {
- tet_printf( "Fail. different paragraph index. %s", location );
- return false;
- }
- if( indices.mWordIndex != resultWordIndex )
- {
- tet_printf( "Fail. different word index. %s", location );
- return false;
- }
- if( indices.mCharacterIndex != resultCharacterIndex )
- {
- tet_printf( "Fail. different character index. %s", location );
- return false;
- }
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////
-} // namespace
-
-
-int UtcDaliTextViewGetIndicesFromGlobalCharacterIndex(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewGetIndicesFromGlobalCharacterIndex : ");
- struct GetIndicesFromGlobalCharacterIndexTest getIndicesFromGlobalCharacterIndexTests[] =
- {
- {
- std::string( "Test position 0" ),
- std::string( "text te<font size='30'>xt text te</font>xt text\n"
- "text t<font size='30'>ext טקסט טקסט te</font>xt\n"
- "text text text text text\n"
- "\n" ),
- 0,
- 0,
- 0,
- 0
- },
- {
- std::string( "Test position 76. (just after the last \\n)" ),
- std::string( "t<font size='30'>ext text te</font>xt text text\n"
- "text text טקסט טקסט text\n"
- "text text te<font size='30'>xt text</font> text\n"
- "\n" ),
- 76,
- 4,
- 0,
- 0
- },
- {
- std::string( "Test position 73. (the last \\n)" ),
- std::string( "text te<font size='30'>xt text text </font>text\n"
- "text text טק<font size='30'>סט טקס</font>ט text\n"
- "text text text text text\n"
- "\n" ),
- 75,
- 3,
- 0,
- 0
- },
- {
- std::string( "Test position 35. (first hebrew character)" ),
- std::string( "text text text text text\n"
- "text text טקסט טקסט text\n"
- "text text text text text\n"
- "\n" ),
- 35,
- 1,
- 4,
- 0
- },
- {
- std::string( "Test position 3. (end of the first word)" ),
- std::string( "text te<font size='30'>xt text text text\n</font>"
- "text text טק<font size='30'>סט טקסט </font>text\n"
- "text te<font size='30'>xt text text</font> text\n"
- "\n" ),
- 3,
- 0,
- 0,
- 3
- },
- {
- std::string( "Test position 33. (end of the second word of the second paragraph)" ),
- std::string( "text te<font size='30'>xt text text text\n</font>"
- "text text טק<font size='30'>סט טקסט </font>text\n"
- "text te<font size='30'>xt text text</font> text\n"
- "\n" ),
- 33,
- 1,
- 2,
- 3
- },
- {
- std::string( "Test position 43. (last hebrew character)" ),
- std::string( "text te<font size='30'>xt text text text\n</font>"
- "text text טק<font size='30'>סט טקסט </font>text\n"
- "text te<font size='30'>xt text text</font> text\n"
- "\n" ),
- 43,
- 1,
- 6,
- 3
- },
- };
- const std::size_t numberOfTests( 7 );
-
- for( std::size_t index = 0; index < numberOfTests; ++index )
- {
- const GetIndicesFromGlobalCharacterIndexTest& test = getIndicesFromGlobalCharacterIndexTests[index];
-
- if( !TestGetIndicesFromGlobalCharacterIndex( test.description, test.input, test.position, test.paragraphIndex, test.wordIndex, test.characterIndex, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewDebugCouts(void)
-{
- /////////////////////////////////////////////////////
- // Text debug functions to not to penalize coverage
- /////////////////////////////////////////////////////
-
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewDebugCouts : ");
-
- Toolkit::Internal::TextView::RelayoutData relayoutData;
-
- MarkupProcessor::StyledTextArray inputStyledText;
- MarkupProcessor::GetStyledTextArray( std::string( "Hello world\nhello world" ), inputStyledText, true );
-
- TextViewProcessor::CreateTextInfo( inputStyledText,
- DEFAULT_LAYOUT_PARAMETERS,
- relayoutData );
-
- Actor dummy = Actor::New();
- Toolkit::Internal::SplitByNewLineChar::Relayout( dummy,
- Toolkit::Internal::TextView::RELAYOUT_ALL,
- DEFAULT_LAYOUT_PARAMETERS,
- DEFAULT_VISUAL_PARAMETERS,
- relayoutData );
-
- TextViewProcessor::dbgPrint( relayoutData.mTextLayoutInfo );
-
- TextStyle textStyle;
- TextViewProcessor::dbgPrint( textStyle );
-
- TextViewProcessor::TextInfoIndices indices;
- TextViewProcessor::dbgPrint( indices );
-
- TextViewProcessor::dbgPrint( inputStyledText );
-
- tet_result( TET_PASS );
- END_TEST;
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-#include <stdlib.h>
-#include <dali-toolkit-test-suite-utils.h>
-#include <dali-toolkit/dali-toolkit.h>
-
-
-// Internal headers are allowed here
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-types.h>
-
-using namespace Dali;
-using namespace Dali::Toolkit;
-using namespace Dali::Toolkit::Internal;
-
-void dali_text_view_processor_types_startup(void)
-{
- test_return_value = TET_UNDEF;
-}
-
-void dali_text_view_processor_types_cleanup(void)
-{
- test_return_value = TET_PASS;
-}
-
-
-namespace
-{
-// Data structures used to create an 'experiment' in TET cases
-
-//////////////////////////////////////////////////////////////////
-} // namespace
-
-
-int UtcDaliTextViewDefaultConstructorDestructor_PT(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewDefaultConstructorDestructor : ");
-
- TextViewProcessor::TextInfoIndices indices;
- DALI_TEST_EQUALS( indices.mParagraphIndex, 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( indices.mWordIndex, 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( indices.mCharacterIndex, 0u, TEST_LOCATION );
-
- TextViewProcessor::CharacterLayoutInfo characterLayoutInfo;
- DALI_TEST_EQUALS( characterLayoutInfo.mSize, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mBearing, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mPosition, Vector3::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mOffset, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mAscender, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mUnderlineThickness, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mUnderlinePosition, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_CHECK( !characterLayoutInfo.mGlyphActor );
- DALI_TEST_EQUALS( characterLayoutInfo.mColorAlpha, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_CHECK( NULL == characterLayoutInfo.mGradientInfo );
- DALI_TEST_CHECK( characterLayoutInfo.mIsVisible );
- DALI_TEST_CHECK( !characterLayoutInfo.mSetText );
- DALI_TEST_CHECK( !characterLayoutInfo.mSetStyle );
-
- TextViewProcessor::WordLayoutInfo wordLayoutInfo;
- DALI_TEST_EQUALS( wordLayoutInfo.mSize, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( wordLayoutInfo.mAscender, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( wordLayoutInfo.mType, TextViewProcessor::NoSeparator, TEST_LOCATION );
- DALI_TEST_EQUALS( wordLayoutInfo.mCharactersLayoutInfo.size(), 0u, TEST_LOCATION );
-
- TextViewProcessor::ParagraphLayoutInfo paragraphLayoutInfo;
- DALI_TEST_EQUALS( paragraphLayoutInfo.mSize, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( paragraphLayoutInfo.mAscender, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( paragraphLayoutInfo.mLineHeightOffset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( paragraphLayoutInfo.mWordsLayoutInfo.size(), 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( paragraphLayoutInfo.mNumberOfCharacters, 0u, TEST_LOCATION );
-
- TextViewProcessor::TextLayoutInfo textLayoutInfo;
- DALI_TEST_EQUALS( textLayoutInfo.mWholeTextSize, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mMaxWordWidth, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mParagraphsLayoutInfo.size(), 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mNumberOfCharacters, 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mMaxItalicsOffset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mEllipsizeLayoutInfo.mSize, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mEllipsizeLayoutInfo.mAscender, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mEllipsizeLayoutInfo.mType, TextViewProcessor::NoSeparator, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mEllipsizeLayoutInfo.mCharactersLayoutInfo.size(), 0u, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliTextViewCopyConstructorOperator(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewCopyConstructorOperator : ");
-
- TextViewProcessor::CharacterLayoutInfo characterLayoutInfo;
- characterLayoutInfo.mSize = Vector2( 1.f, 1.f );
- characterLayoutInfo.mBearing = 1.f;
- characterLayoutInfo.mPosition = Vector3( 1.f, 1.f, 1.f );
- characterLayoutInfo.mOffset = Vector2( 1.f, 1.f );
- characterLayoutInfo.mAscender = 1.f;
- characterLayoutInfo.mUnderlineThickness = 1.f;
- characterLayoutInfo.mUnderlinePosition = 1.f;
-
- characterLayoutInfo.mGlyphActor = TextActor::New( "Hello" );
-
- TextViewProcessor::GradientInfo* info = new TextViewProcessor::GradientInfo();
- info->mGradientColor = Vector4( 1.f, 1.f, 1.f, 1.f );
- info->mStartPoint = Vector2( 1.f, 1.f );
- info->mEndPoint = Vector2( 1.f, 1.f );
-
- characterLayoutInfo.mColorAlpha = 0.f;
- characterLayoutInfo.mGradientInfo = info;
-
- characterLayoutInfo.mIsVisible = false;
- characterLayoutInfo.mSetText = false;
- characterLayoutInfo.mSetStyle = false;
-
- TextViewProcessor::CharacterLayoutInfo characterLayoutInfo1;
- characterLayoutInfo1 = characterLayoutInfo;
-
- DALI_TEST_EQUALS( characterLayoutInfo1.mBearing, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo1.mPosition, Vector3( 1.f, 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo1.mOffset, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo1.mSize, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo1.mAscender, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo1.mUnderlineThickness, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo1.mUnderlinePosition, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_CHECK( characterLayoutInfo1.mGlyphActor );
- DALI_TEST_EQUALS( characterLayoutInfo1.mColorAlpha, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo1.mGradientInfo->mGradientColor, Vector4( 1.f, 1.f, 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo1.mGradientInfo->mStartPoint, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo1.mGradientInfo->mEndPoint, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_CHECK( !characterLayoutInfo1.mIsVisible );
- DALI_TEST_CHECK( !characterLayoutInfo1.mSetText );
- DALI_TEST_CHECK( !characterLayoutInfo1.mSetStyle );
-
- TextViewProcessor::CharacterLayoutInfo characterLayoutInfo2( characterLayoutInfo );
- DALI_TEST_EQUALS( characterLayoutInfo2.mBearing, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo2.mPosition, Vector3( 1.f, 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo2.mOffset, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo2.mSize, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo2.mAscender, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo2.mUnderlineThickness, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo2.mUnderlinePosition, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_CHECK( characterLayoutInfo2.mGlyphActor );
- DALI_TEST_EQUALS( characterLayoutInfo2.mColorAlpha, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo2.mGradientInfo->mGradientColor, Vector4( 1.f, 1.f, 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo2.mGradientInfo->mStartPoint, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo2.mGradientInfo->mEndPoint, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_CHECK( !characterLayoutInfo2.mIsVisible );
- DALI_TEST_CHECK( !characterLayoutInfo2.mSetText );
- DALI_TEST_CHECK( !characterLayoutInfo2.mSetStyle );
-
- // Increases coverage.
- characterLayoutInfo2.mGlyphActor.Reset();
- characterLayoutInfo1 = characterLayoutInfo2;
- DALI_TEST_CHECK( !characterLayoutInfo1.mGlyphActor );
-
- TextViewProcessor::WordLayoutInfo wordLayoutInfo;
- wordLayoutInfo.mSize = Vector2( 1.f, 1.f );
- wordLayoutInfo.mAscender = 1.f;
- wordLayoutInfo.mType = TextViewProcessor::ParagraphSeparator;
-
- TextViewProcessor::WordLayoutInfo wordLayoutInfo1;
- wordLayoutInfo1 = wordLayoutInfo;
-
- DALI_TEST_EQUALS( wordLayoutInfo1.mSize, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( wordLayoutInfo1.mAscender, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( wordLayoutInfo1.mType, TextViewProcessor::ParagraphSeparator, TEST_LOCATION );
-
- TextViewProcessor::WordLayoutInfo wordLayoutInfo2( wordLayoutInfo );
-
- DALI_TEST_EQUALS( wordLayoutInfo2.mSize, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( wordLayoutInfo2.mAscender, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( wordLayoutInfo2.mType, TextViewProcessor::ParagraphSeparator, TEST_LOCATION );
-
- TextViewProcessor::ParagraphLayoutInfo paragraphLayoutInfo;
- paragraphLayoutInfo.mSize = Vector2( 1.f, 1.f );
- paragraphLayoutInfo.mAscender = 1.f;
- paragraphLayoutInfo.mLineHeightOffset = 1.f;
- paragraphLayoutInfo.mNumberOfCharacters = 1u;
-
- TextViewProcessor::ParagraphLayoutInfo paragraphLayoutInfo1;
- paragraphLayoutInfo1 = paragraphLayoutInfo;
-
- DALI_TEST_EQUALS( paragraphLayoutInfo1.mSize, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( paragraphLayoutInfo1.mAscender, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( paragraphLayoutInfo1.mLineHeightOffset, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( paragraphLayoutInfo1.mNumberOfCharacters, 1u, TEST_LOCATION );
-
- TextViewProcessor::ParagraphLayoutInfo paragraphLayoutInfo2( paragraphLayoutInfo );
-
- DALI_TEST_EQUALS( paragraphLayoutInfo2.mSize, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( paragraphLayoutInfo2.mAscender, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( paragraphLayoutInfo2.mLineHeightOffset, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( paragraphLayoutInfo2.mNumberOfCharacters, 1u, TEST_LOCATION );
-
- TextViewProcessor::TextLayoutInfo textLayoutInfo;
- textLayoutInfo.mWholeTextSize = Vector2( 1.f, 1.f );
- textLayoutInfo.mMaxWordWidth = 1.f;
- textLayoutInfo.mNumberOfCharacters = 1u;
- textLayoutInfo.mMaxItalicsOffset = 1.f;
-
- TextViewProcessor::TextLayoutInfo textLayoutInfo1;
- textLayoutInfo1 = textLayoutInfo;
-
- DALI_TEST_EQUALS( textLayoutInfo1.mWholeTextSize, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo1.mMaxWordWidth, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo1.mNumberOfCharacters, 1u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo1.mMaxItalicsOffset, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
- TextViewProcessor::TextLayoutInfo textLayoutInfo2( textLayoutInfo );
-
- DALI_TEST_EQUALS( textLayoutInfo2.mWholeTextSize, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo2.mMaxWordWidth, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo2.mNumberOfCharacters, 1u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo2.mMaxItalicsOffset, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliTextViewEqualityOperator(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewEqualityOperator : ");
-
- TextViewProcessor::TextInfoIndices indices;
- TextViewProcessor::TextInfoIndices indices1( 1u, 1u, 1u );
-
- DALI_TEST_CHECK( !( indices == indices1 ) );
-
- indices = indices1;
-
- DALI_TEST_CHECK( indices == indices1 );
- END_TEST;
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-#include <stdlib.h>
-#include <dali-toolkit-test-suite-utils.h>
-#include <dali-toolkit/dali-toolkit.h>
-
-// Internal headers are allowed here
-#include <dali-toolkit/internal/controls/text-view/text-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
-
-using namespace Dali;
-using namespace Dali::Toolkit;
-using namespace Dali::Toolkit::Internal;
-
-void dali_text_view_processor_startup(void)
-{
- test_return_value = TET_UNDEF;
-}
-
-void dali_text_view_processor_cleanup(void)
-{
- test_return_value = TET_PASS;
-}
-
-
-namespace
-{
-// Data structures used to create an 'experiment' in TET cases
-
-//////////////////////////////////////////////////////////////////
-
-struct BeginsRightToLeftCharacterTest
-{
- std::string description;
- std::string input;
- bool result;
-};
-
-bool TestBeginsRightToLeftCharacter( const std::string& description, const std::string& input, const bool result, const char* location )
-{
- // Creates a text with the string.
- Text text( input );
-
- const bool ret = ( result == TextProcessor::BeginsRightToLeftCharacter( text ) );
-
- if( !ret )
- {
- tet_printf( "Fail. %s", location );
- tet_printf( "Input : %s", input.c_str() );
- }
-
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////
-
-struct ContainsRightToLeftCharacterTest
-{
- std::string description;
- std::string input;
- bool result;
-};
-
-bool TestContainsRightToLeftCharacter( const std::string& description, const std::string& input, const bool result, const char* location )
-{
- // Creates a text with the string.
- Text text( input );
-
- const bool ret = ( result == TextProcessor::ContainsRightToLeftCharacter( text ) );
-
- if( !ret )
- {
- tet_printf( "Fail. %s", location );
- tet_printf( "Input : %s", input.c_str() );
- }
-
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////
-
-struct FindNearestWordTest
-{
- std::string description;
- std::string input;
- std::size_t offset;
- std::size_t start;
- std::size_t end;
-};
-
-bool TestFindNearestWord( const std::string& description, const std::string& input, const std::size_t offset, const std::size_t startResult, const std::size_t endResult, const char* location )
-{
- // Creates a styled text with the markup or plain string.
- MarkupProcessor::StyledTextArray styledText;
- MarkupProcessor::GetStyledTextArray( input, styledText, true );
-
- std::size_t start;
- std::size_t end;
- TextProcessor::FindNearestWord( styledText, offset, start, end );
-
- const bool ret = ( start == startResult ) && ( end == endResult );
-
- if( !ret )
- {
- tet_printf( "Fail. %s", location );
- tet_printf( "Input : %s, offset %d, start %d, end %d", input.c_str(), offset, start, end );
- }
-
- return ret;
-}
-
-//////////////////////////////////////////////////////////////////
-
-struct SplitInParagraphsTest
-{
- std::string inputText;
-
- std::size_t resultNumberOfParagraphs;
-};
-
-bool TestSplitInParagraphs( const SplitInParagraphsTest& test, const char* location )
-{
- // Creates a styled text with the markup or plain string.
- MarkupProcessor::StyledTextArray styledText;
- MarkupProcessor::GetStyledTextArray( test.inputText, styledText, true );
-
- std::vector<Text> paragraphs;
- std::vector< Vector<TextStyle*> > styles;
-
- TextProcessor::SplitInParagraphs( styledText,
- paragraphs,
- styles );
-
- if( paragraphs.size() != test.resultNumberOfParagraphs )
- {
- tet_printf( "Fail. %s", location );
- tet_printf( "Different number of paragraphs, result %d, expected result %d", paragraphs.size(), test.resultNumberOfParagraphs );
-
- return false;
- }
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////
-
-struct SplitInWordsTest
-{
- std::string inputText;
-
- std::size_t resultNumberOfSeparators;
-};
-
-bool TestSplitInWords( const SplitInWordsTest& test, const char* location )
-{
- // Creates a text with the string.
- Text text( test.inputText );
-
- Vector<std::size_t> positions;
-
- TextProcessor::SplitInWords( text,
- positions );
-
- if( positions.Count() != test.resultNumberOfSeparators )
- {
- tet_printf( "Fail. %s", location );
- tet_printf( "Different number of separators, result %d, expected result %d", positions.Count(), test.resultNumberOfSeparators );
-
- return false;
- }
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////
-
-} // namespace
-
-
-int UtcDaliTextViewSplitInParagraphs(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewSplitInParagraphs : ");
-
- struct SplitInParagraphsTest splitInParagraphsTest[] =
- {
- {
- std::string( "Hello world\nhello world." ),
- 2
- },
- {
- std::string( "Hello world\nhello world.\n\n" ),
- 4
- }
- };
- const std::size_t numberOfTests( 2 );
-
- for( std::size_t index = 0; index < numberOfTests; ++index )
- {
- const SplitInParagraphsTest& test = splitInParagraphsTest[index];
-
- if( !TestSplitInParagraphs( test, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewSplitInWords(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewSplitInWords : ");
-
- struct SplitInWordsTest splitInWordsTest[] =
- {
- {
- std::string( "Hello world, hello word!" ),
- 3u
- },
- {
- std::string( "Hello world\n" ),
- 2u
- }
- };
- const std::size_t numberOfTests( 2u );
-
- for( std::size_t index = 0; index < numberOfTests; ++index )
- {
- const SplitInWordsTest& test = splitInWordsTest[index];
-
- if( !TestSplitInWords( test, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewBeginsRightToLeftCharacter(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewBeginsRightToLeftCharacter : ");
-
- struct BeginsRightToLeftCharacterTest beginsRightToLeftCharacterTest[] =
- {
- {
- std::string( "Test if it begins with a right to left character. Should return false." ),
- std::string( "Hello world مرحبا العالم." ),
- false
- },
- {
- std::string( "Test if it begins with a right to left character. Should return true." ),
- std::string( "مرحبا العالم Hola mundo." ),
- true
- }
- };
- const std::size_t numberOfTests( 2 );
-
- for( std::size_t index = 0; index < numberOfTests; ++index )
- {
- const BeginsRightToLeftCharacterTest& test = beginsRightToLeftCharacterTest[index];
-
- if( !TestBeginsRightToLeftCharacter( test.description, test.input, test.result, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewContainsRightToLeftCharacter(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewContainsRightToLeftCharacter : ");
-
- struct ContainsRightToLeftCharacterTest containsRightToLeftCharacterTest[] =
- {
- {
- std::string( "Test if it contains a right to left character. Should return true." ),
- std::string( "Hello world مرحبا العالم." ),
- true
- },
- {
- std::string( "Test if it contains a right to left character. Should return true." ),
- std::string( "مرحبا العالم Hola mundo." ),
- true
- },
- {
- std::string( "Test if it contains a right to left character. Should return false." ),
- std::string( "Hello world." ),
- false
- },
- {
- std::string( "Test if it contains a right to left character. Should return true." ),
- std::string( "مرحبا العالم." ),
- true
- }
- };
- const std::size_t numberOfTests( 4 );
-
- for( std::size_t index = 0; index < numberOfTests; ++index )
- {
- const ContainsRightToLeftCharacterTest& test = containsRightToLeftCharacterTest[index];
-
- if( !TestContainsRightToLeftCharacter( test.description, test.input, test.result, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewFindNearestWord(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewFindNearestWord : ");
-
- struct FindNearestWordTest findNearestWordTest[] =
- {
- {
- std::string( "" ),
- std::string( "Hello world, hola mundo" ),
- 0u,
- 0u,
- 5u
- },
- {
- std::string( "" ),
- std::string( "Hello world, hola mundo" ),
- 7u,
- 6u,
- 12u
- },
- {
- std::string( "" ),
- std::string( "Hello world, hola mundo" ),
- 11u,
- 6u,
- 12u
- },
- {
- std::string( "" ),
- std::string( "Hello world, hola mundo" ),
- 23u,
- 18u,
- 23u
- },
- {
- std::string( "" ),
- std::string( "Hello world, hola mundo" ),
- 5u,
- 0u,
- 5u
- },
- {
- std::string( "" ),
- std::string( "Hello world, hola mundo مرحبا العالم" ),
- 24u,
- 25u,
- 30u
- }
- };
-
- const std::size_t numberOfTests( 6 );
-
- for( std::size_t index = 0; index < numberOfTests; ++index )
- {
- const FindNearestWordTest& test = findNearestWordTest[index];
-
- if( !TestFindNearestWord( test.description, test.input, test.offset, test.start, test.end, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-
-#include <stdlib.h>
-#include <dali-toolkit-test-suite-utils.h>
-#include <dali-toolkit/dali-toolkit.h>
-
-// Internal headers are allowed here
-#include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
-
-using namespace Dali;
-using namespace Dali::Toolkit;
-using namespace Dali::Toolkit::Internal;
-
-void dali_text_view_relayout_utils_startup(void)
-{
- test_return_value = TET_UNDEF;
-}
-
-void dali_text_view_relayout_utils_cleanup(void)
-{
- test_return_value = TET_PASS;
-}
-
-namespace
-{
-
-const Toolkit::Internal::TextView::LayoutParameters DEFAULT_LAYOUT_PARAMETERS;
-
-// Data structures used to create an 'experiment' in TET cases
-
-
-bool TestEqual( float x, float y )
-{
- return ( fabsf( x - y ) < Math::MACHINE_EPSILON_1000 );
-}
-
-//////////////////////////////////////////////////////////////////
-
-struct CalculateLineLayoutTest
-{
- std::string description;
- std::string inputParagraph;
- float parentWidth;
- std::size_t wordIndex;
- std::size_t characterIndex;
- std::size_t characterParagraphIndex;
- TextViewRelayout::HorizontalWrapType splitPolicy;
- float shrinkFactor;
-
- float resultLineLength;
- float resultMaxCharHeight;
- float resultMaxAscender;
-};
-
-bool TestCalculateLineLayout( const CalculateLineLayoutTest& test, const char* location )
-{
- tet_printf( "%s", test.description.c_str() );
-
- // Create styled text.
- MarkupProcessor::StyledTextArray inputStyledText;
- MarkupProcessor::GetStyledTextArray( test.inputParagraph, inputStyledText, true );
-
- // Create styled text layout info.
- Toolkit::Internal::TextView::RelayoutData relayoutData;
- TextViewProcessor::CreateTextInfo( inputStyledText,
- DEFAULT_LAYOUT_PARAMETERS,
- relayoutData );
-
- // Prepare input parameters and the result structure and call the function to be tested.
-
- // Creaqte indices.
- TextViewProcessor::TextInfoIndices indices( 0u, test.wordIndex, test.characterIndex );
- indices.mCharacterParagraphIndex = test.characterParagraphIndex;
-
- // Get the input paragraph.
- TextViewProcessor::ParagraphLayoutInfo inputParagraphLayout;
-
- if( !relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
- {
- inputParagraphLayout = *relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin();
- }
-
- // Result struct.
- TextViewRelayout::LineLayoutInfo resultLayoutInfo;
-
- CalculateLineLayout( test.parentWidth,
- indices,
- inputParagraphLayout,
- test.splitPolicy,
- test.shrinkFactor,
- resultLayoutInfo );
-
- // Check results.
- if( !TestEqual( test.resultLineLength, resultLayoutInfo.mLineLength ) )
- {
- tet_printf( "Fail. different line length %f == %f. %s", test.resultLineLength, resultLayoutInfo.mLineLength, location );
- return false;
- }
-
- if( !TestEqual( test.resultMaxCharHeight, resultLayoutInfo.mMaxCharHeight ) )
- {
- tet_printf( "Fail. different max character height %f == %f. %s", test.resultMaxCharHeight, resultLayoutInfo.mMaxCharHeight, location );
- return false;
- }
-
- if( !TestEqual( test.resultMaxAscender, resultLayoutInfo.mMaxAscender ) )
- {
- tet_printf( "Fail. different max ascender %f == %f. %s", test.resultMaxAscender, resultLayoutInfo.mMaxAscender, location );
- return false;
- }
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////
-
-struct AlignmentOffsetTest
-{
- Toolkit::Alignment::Type alignment;
- float parentSize;
- float wholeTextSize;
-
- float resultOffset;
-};
-
-bool TestAlignmentOffset( const AlignmentOffsetTest& test, const char* location )
-{
- float offset = 0.f;
-
- switch( test.alignment )
- {
- case Toolkit::Alignment::HorizontalLeft:
- case Toolkit::Alignment::HorizontalCenter:
- case Toolkit::Alignment::HorizontalRight:
- {
- offset = TextViewRelayout::CalculateXoffset( test.alignment, test.parentSize, test.wholeTextSize );
- break;
- }
- case Toolkit::Alignment::VerticalTop:
- case Toolkit::Alignment::VerticalCenter:
- case Toolkit::Alignment::VerticalBottom:
- {
- offset = TextViewRelayout::CalculateYoffset( test.alignment, test.parentSize, test.wholeTextSize );
- break;
- }
- }
-
- // Check results.
- if( !TestEqual( test.resultOffset, offset ) )
- {
- tet_printf( "Fail. different offset %f == %f. %s", test.resultOffset, offset, location );
- return false;
- }
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////
-
-struct JustificationOffsetTest
-{
- Toolkit::TextView::LineJustification justification;
- float wholeTextWidth;
- float lineLength;
-
- float resultOffset;
-};
-
-bool TestJustificationOffset( const JustificationOffsetTest& test, const char* location )
-{
- float offset = TextViewRelayout::CalculateJustificationOffset( test.justification, test.wholeTextWidth, test.lineLength );
-
- // Check results.
- if( !TestEqual( test.resultOffset, offset ) )
- {
- tet_printf( "Fail. different offset %f == %f. %s", test.resultOffset, offset, location );
- return false;
- }
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////
-
-struct CalculateVisibilityTest
-{
- Vector3 position;
- Size size;
- Size parentSize;
- TextViewRelayout::VisibilityTestType type;
-
- bool resultVisible;
-};
-
-bool TestCalculateVisibility( const CalculateVisibilityTest& test, const char* location )
-{
- if( test.resultVisible != TextViewRelayout::IsVisible( test.position, test.size, test.parentSize, test.type ) )
- {
- tet_printf( "Fail. different visibility. Type %d, %s", test.type, location );
- return false;
- }
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////
-
-} // namespace
-
-
-int UtcDaliTextViewDefaultConstructorDestructor_RU(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewDefaultConstructorDestructor : ");
-
- // Test RelayoutParameters defaults.
- TextViewRelayout::RelayoutParameters relayoutParameters;
-
- DALI_TEST_EQUALS( relayoutParameters.mPositionOffset, Vector3::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( relayoutParameters.mParagraphSize, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( relayoutParameters.mWordSize, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( relayoutParameters.mCharacterSize, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( relayoutParameters.mIndices.mParagraphIndex, 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( relayoutParameters.mIndices.mWordIndex, 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( relayoutParameters.mIndices.mCharacterIndex, 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( relayoutParameters.mCharacterGlobalIndex, 0u, TEST_LOCATION );
- DALI_TEST_CHECK( !relayoutParameters.mIsFirstCharacter );
- DALI_TEST_CHECK( !relayoutParameters.mIsFirstCharacterOfWord );
- DALI_TEST_CHECK( !relayoutParameters.mIsNewLine );
- DALI_TEST_CHECK( !relayoutParameters.mIsNewParagraphCharacter );
- DALI_TEST_CHECK( !relayoutParameters.mIsWhiteSpace );
- DALI_TEST_CHECK( !relayoutParameters.mIsVisible );
-
- // Test FadeParameter defaults
- TextViewRelayout::FadeParameters fadeParameters;
-
- DALI_TEST_EQUALS( fadeParameters.mRightFadeBoundary, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mRightFadeThreshold, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mRightFadeBoundaryOffset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mRightFadeThresholdOffset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mRightAlphaCoeficients, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mLeftFadeBoundary, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mLeftFadeThreshold, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mLeftFadeBoundaryOffset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mLeftFadeThresholdOffset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mLeftAlphaCoeficients, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mTopFadeBoundary, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mTopFadeThreshold, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mTopFadeBoundaryOffset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mTopFadeThresholdOffset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mTopAlphaCoeficients, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mBottomFadeBoundary, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mBottomFadeThreshold, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mBottomFadeBoundaryOffset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mBottomFadeThresholdOffset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeParameters.mBottomAlphaCoeficients, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_CHECK( !fadeParameters.mIsPartiallyVisible );
-
- // Test EllipsizeParameters defaults
- TextViewRelayout::EllipsizeParameters ellipsizeParameters;
-
- DALI_TEST_EQUALS( ellipsizeParameters.mPosition, Vector3::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( ellipsizeParameters.mLineDescender, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( ellipsizeParameters.mLineWidth, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( ellipsizeParameters.mEllipsizeBoundary, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( ellipsizeParameters.mFirstIndex, 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( ellipsizeParameters.mLastIndex, 0u, TEST_LOCATION );
- DALI_TEST_CHECK( !ellipsizeParameters.mEllipsizeLine );
- DALI_TEST_CHECK( !ellipsizeParameters.mIsLineWidthFullyVisible );
- DALI_TEST_CHECK( !ellipsizeParameters.mIsLineHeightFullyVisible );
- DALI_TEST_CHECK( !ellipsizeParameters.mIsNextLineFullyVisibleHeight );
- DALI_TEST_CHECK( !ellipsizeParameters.mCreateEllipsizedTextActors );
- DALI_TEST_CHECK( !ellipsizeParameters.mLineFits );
- DALI_TEST_CHECK( !ellipsizeParameters.mWordFits );
-
- // Test UnderlineInfo defaults
- TextViewRelayout::UnderlineInfo underlineInfo;
-
- DALI_TEST_EQUALS( underlineInfo.mMaxHeight, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( underlineInfo.mMaxThickness, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( underlineInfo.mPosition, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
- // Test TextUnderlineStatus defaults
- TextViewRelayout::TextUnderlineStatus textUnderlineStatus;
-
- DALI_TEST_CHECK( textUnderlineStatus.mUnderlineInfo.empty() );
- DALI_TEST_EQUALS( textUnderlineStatus.mCharacterGlobalIndex, 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( textUnderlineStatus.mLineGlobalIndex, 0u, TEST_LOCATION );
- DALI_TEST_CHECK( !textUnderlineStatus.mCurrentUnderlineStatus );
-
- // Test LineLayoutInfo defaults
- TextViewRelayout::LineLayoutInfo lineLayoutInfo;
-
- DALI_TEST_EQUALS( lineLayoutInfo.mLineLength, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( lineLayoutInfo.mMaxCharHeight, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( lineLayoutInfo.mMaxAscender, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliTextViewCalculateLineLayout(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewCalculateLineLayout : ");
-
- struct CalculateLineLayoutTest calculateLineLayoutTest[] =
- {
- //WrapByCharacter
- {
- "The paragraph is wraped by character. All characters have the same size.",
- "Hello world", // input paragraph
- 100.f, // parent width
- 0, // indices
- 0,
- 0,
- TextViewRelayout::WrapByCharacter, // split policy
- 1.f,
- // results
- 91.041672f, // line length. (only fits 8 characters 8x11.38)
- 11.380209f, // max character height
- 10.242188f // max ascender
- },
- {
- "The paragraph is wraped by character. There are characters with different sizes.",
- "Hello <font size='14'>world</font>", // input paragraph
- 100.f, // parent width
- 0, // indices
- 0,
- 0,
- TextViewRelayout::WrapByCharacter, // split policy
- 1.f,
- // results
- 94.835075f, // line length. (only fits 8 characters 6x11.38 + 2x13.27)
- 13.276911f, // max character height
- 11.949220f // max ascender
- },
- {
- "The paragraph is wraped by character. There are characters with different sizes. It calculates the layout for the second line.",
- "Hello <font size='14'>wo</font>rld hell<font size='14'>o world</font>", // input paragraph
- 100.f, // parent width
- 2, // indices. The third character of the third word starts in a new line.
- 2,
- 8,
- TextViewRelayout::WrapByCharacter, // split policy
- 1.f,
- // results
- 91.041672f, // line length. (only fits 8 characters 8x11.38)
- 11.380209f, // max character height
- 10.242188f // max ascender
- },
- {
- "The paragraph is wraped by character. There are characters with different sizes. It calculates the layout for the third line.",
- "Hello <font size='14'>wo</font>rld hell<font size='14'>o world</font>", // input paragraph
- 100.f, // parent width
- 4, // indices. The fifth character of the fifth word starts in a new line.
- 4,
- 16,
- TextViewRelayout::WrapByCharacter, // split policy
- 1.f,
- // results
- 92.938377f, // line length. (only fits 8 characters 8x11.38)
- 13.276911f, // max character height
- 11.949220f // max ascender
- },
-
- //WrapByWord
- {
- "The paragraph is wraped by word. All characters have the same size.",
- "Hello world", // input paragraph
- 100.f, // parent width
- 0, // indices. It shouldn't use the index character so 9999999 shouldn't make it crash.
- 9999999,
- 9999999,
- TextViewRelayout::WrapByWord, // split policy
- 1.f,
- // results
- 56.901047f, // line length. (only fits 5 characters 5x11.38, white space is not counted)
- 11.380209f, // max character height
- 10.242188f // max ascender
- },
- {
- "The paragraph is wraped by word. There are characters with different sizes.",
- "Hell<font size='14'>o</font> world", // input paragraph
- 100.f, // parent width
- 0, // indices.
- 0,
- 0,
- TextViewRelayout::WrapByWord, // split policy
- 1.f,
- // results
- 58.797747f, // line length. (only fits 5 characters 4x11.38 + 13.276911, white space is not counted)
- 13.276911f, // max character height
- 11.949220f // max ascender
- },
- {
- "The paragraph is wraped by word. There are characters with different sizes. It calculates the layout for the second line.",
- "Hello <font size='14'>wo</font>rld <font size='16'>hello world</font>", // input paragraph
- 100.f, // parent width
- 2, // indices. The third word starts in a new line.
- 0,
- 6,
- TextViewRelayout::WrapByWord, // split policy
- 1.f,
- // results
- 60.694449f, // line length. (only fits 5 characters 2x13.276911 + 3x11.38)
- 13.276911f, // max character height
- 11.949220f // max ascender
- },
- {
- "The paragraph is wraped by word. The word doen't fit.",
- "Hello world", // input paragraph
- 40.f, // parent width
- 0, // indices. The third word starts in a new line.
- 0,
- 0,
- TextViewRelayout::WrapByWord, // split policy
- 1.f,
- // results
- 0.f, // line length. (The word doesn't fit)
- 11.380209f, // max character height
- 10.242188f // max ascender
- },
-
- //WrapByWordAndSplit
- {
- "The paragraph is wraped by word and by character. All characters have the same size. There is not a long word.",
- "Hello world hello world", // input paragraph
- 100.f, // parent width
- 0, // indices.
- 0,
- 0,
- TextViewRelayout::WrapByWordAndSplit, // split policy
- 1.f,
- // results
- 56.901047f, // line length. (only fits 5 characters 5x11.38, white space is not counted)
- 11.380209f, // max character height
- 10.242188f // max ascender
- },
- {
- "The paragraph is wraped by word and by character. All characters have the same size. There is a long word.",
- "Helloooooooo world", // input paragraph
- 100.f, // parent width
- 0, // indices.
- 0,
- 0,
- TextViewRelayout::WrapByWordAndSplit, // split policy
- 1.f,
- // results
- 91.041672f, // line length. (only fits 8 characters 8x11.38)
- 11.380209f, // max character height
- 10.242188f // max ascender
- },
- {
- "The paragraph is wraped by word and by character. There are characters with different sizes. There is a long word. It calculates the layout for the second line.",
- "Helloooooooo <font size='14'>world</font>", // input paragraph
- 100.f, // parent width
- 0, // indices.
- 8,
- 8,
- TextViewRelayout::WrapByWordAndSplit, // split policy
- 1.f,
- // results
- 45.520836f, // line length. (only fits 8 characters 8x11.38)
- 11.380209f, // max character height
- 10.242188f // max ascender
- },
- {
- "The paragraph is wraped by word and by character. There are characters with different sizes. There is a shrink factor.",
- "Helloooooooo<font size='14'> world</font>", // input paragraph
- 100.f, // parent width
- 0, // indices.
- 8,
- 8,
- TextViewRelayout::WrapByWordAndSplit, // split policy
- 0.7f,
- // results
- 95.593755f, // line length. (only fits 12 characters 8x11.38)
- 7.9661463f, // max character height
- 7.169531f // max ascender
- },
-
- //WrapByParagraphCharacterAndSplit
- {
- "The paragraph is wraped by end of paragraph and by character. All characters have the same size.",
- "Hello world", // input paragraph
- 100.f, // parent width
- 0, // indices
- 0,
- 0,
- TextViewRelayout::WrapByParagraphCharacterAndSplit, // split policy
- 1.f,
- // results
- 91.041672f, // line length. (only fits 8 characters 8x11.38)
- 11.380209f, // max character height
- 10.242188f // max ascender
- },
- {
- "The paragraph fits in the width.",
- "Hello", // input paragraph
- 100.f, // parent width
- 0, // indices
- 0,
- 0,
- TextViewRelayout::WrapByParagraphCharacterAndSplit, // split policy
- 1.f,
- // results
- 56.901047f, // line length. (only fits 5 characters 5x11.38)
- 11.380209f, // max character height
- 10.242188f // max ascender
- },
- {
- "The paragraph is wraped by end of paragraph and by character. All characters have the same size. It calculates the layout for the second line.",
- "Hello world, hello world", // input paragraph
- 100.f, // parent width
- 2, // indices
- 2,
- 8,
- TextViewRelayout::WrapByParagraphCharacterAndSplit, // split policy
- 1.f,
- // results
- 91.041672f, // line length. (only fits 8 characters 8x11.38)
- 11.380209f, // max character height
- 10.242188f // max ascender
- },
- };
- const std::size_t numberOfTests( 15 );
-
- for( std::size_t index = 0; index < numberOfTests; ++index )
- {
- const CalculateLineLayoutTest& test = calculateLineLayoutTest[index];
-
- if( !TestCalculateLineLayout( test, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewCalculateAlignmentOffsets(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewCalculateAlignmentOffsets : ");
-
- struct AlignmentOffsetTest alignmentOffsetTest[] =
- {
- {
- Toolkit::Alignment::HorizontalLeft,
- 100.f,
- 75.f,
- 0.f
- },
- {
- Toolkit::Alignment::HorizontalCenter,
- 100.f,
- 75.f,
- 12.5f
- },
- {
- Toolkit::Alignment::HorizontalRight,
- 100.f,
- 75.f,
- 25.f
- },
- {
- Toolkit::Alignment::VerticalTop,
- 100.f,
- 75.f,
- 0.f
- },
- {
- Toolkit::Alignment::VerticalCenter,
- 100.f,
- 75.f,
- 12.5f
- },
- {
- Toolkit::Alignment::VerticalBottom,
- 100.f,
- 75.f,
- 25.f
- }
- };
- const std::size_t numberOfTests( 6 );
-
- for( std::size_t index = 0; index < numberOfTests; ++index )
- {
- const AlignmentOffsetTest& test = alignmentOffsetTest[index];
-
- if( !TestAlignmentOffset( test, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewCalculateJustificationOffsets(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewCalculateJustificationOffsets : ");
-
- struct JustificationOffsetTest justificationOffsetTest[] =
- {
- {
- Toolkit::TextView::Left,
- 100.f,
- 75.f,
- 0.f
- },
- {
- Toolkit::TextView::Justified,
- 100.f,
- 75.f,
- 0.f
- },
- {
- Toolkit::TextView::Center,
- 100.f,
- 150.f,
- -25.f
- },
- {
- Toolkit::TextView::Right,
- 100.f,
- 75.f,
- 25.f
- },
- };
- const std::size_t numberOfTests( 4 );
-
- for( std::size_t index = 0; index < numberOfTests; ++index )
- {
- const JustificationOffsetTest& test = justificationOffsetTest[index];
-
- if( !TestJustificationOffset( test, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-
-int UtcDaliTextViewCalculateVisibility(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewCalculateVisibility : ");
-
- struct CalculateVisibilityTest calculateVisibilityTest[] =
- {
- {
- Vector3( 0.f, 10.f, 0.f ),
- Size( 10.f, 10.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::FULLY_VISIBLE,
- true
- },
- {
- Vector3( 10.f, 10.f, 0.f ),
- Size( 10.f, 10.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::FULLY_VISIBLE,
- true
- },
- {
- Vector3( 0.f, 10.f, 0.f ),
- Size( 150.f, 10.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::FULLY_VISIBLE,
- false
- },
- {
- Vector3( 0.f, 10.f, 0.f ),
- Size( 10.f, 10.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::FULLY_VISIBLE_WIDTH,
- true
- },
- {
- Vector3( 95.f, 10.f, 0.f ),
- Size( 10.f, 10.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::FULLY_VISIBLE_WIDTH,
- false
- },
- {
- Vector3( 0.f, 10.f, 0.f ),
- Size( 10.f, 10.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::FULLY_VISIBLE_HEIGHT,
- true
- },
- {
- Vector3( 0.f, 0.f, 0.f ),
- Size( 10.f, 10.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::FULLY_VISIBLE_HEIGHT,
- false
- },
- {
- Vector3( -10.f, 10.f, 0.f ),
- Size( 150.f, 150.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::PARTIALLY_VISIBLE,
- true
- },
- {
- Vector3( -100.f, -100.f, 0.f ),
- Size( 10.f, 10.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::PARTIALLY_VISIBLE,
- false
- },
- {
- Vector3( -10.f, 10.f, 0.f ),
- Size( 50.f, 10.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::PARTIALLY_VISIBLE_WIDTH,
- true
- },
- {
- Vector3( 110.f, 10.f, 0.f ),
- Size( 10.f, 10.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::PARTIALLY_VISIBLE_WIDTH,
- false
- },
- {
- Vector3( 0.f, 20.f, 0.f ),
- Size( 10.f, 50.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::PARTIALLY_VISIBLE_HEIGHT,
- true
- },
- {
- Vector3( 0.f, -10.f, 0.f ),
- Size( 10.f, 10.f ),
- Size( 100.f, 100.f ),
- TextViewRelayout::PARTIALLY_VISIBLE_HEIGHT,
- false
- },
- };
- const std::size_t numberOfTests( 13 );
-
- for( std::size_t index = 0; index < numberOfTests; ++index )
- {
- const CalculateVisibilityTest& test = calculateVisibilityTest[index];
-
- if( !TestCalculateVisibility( test, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewMiscelaneousAsserts(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewMiscelaneousAsserts : ");
-
- float offset = 0.f;
-
- bool assert1 = false;
- bool assert2 = false;
- try
- {
- offset = Toolkit::Internal::TextViewRelayout::CalculateXoffset( Toolkit::Alignment::VerticalTop, 100.f, 50.f );
- }
- catch( Dali::DaliException& e )
- {
- DALI_TEST_PRINT_ASSERT( e );
- DALI_TEST_EQUALS( e.condition, "!\"TextViewRelayout::CalculateXoffset: Wrong horizontal text alignment. Did you set a vertical one?\"", TEST_LOCATION );
- assert1 = true;
- }
- catch( ... )
- {
- tet_result( TET_FAIL );
- }
- DALI_TEST_EQUALS( offset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
- try
- {
- offset = Toolkit::Internal::TextViewRelayout::CalculateYoffset( Toolkit::Alignment::HorizontalRight, 100.f, 50.f );
- }
- catch( Dali::DaliException& e )
- {
- DALI_TEST_PRINT_ASSERT( e );
- DALI_TEST_EQUALS( e.condition, "!\"TextViewRelayout::CalculateXoffset: Wrong vertical text alignment. Did you set an horizontal one?\"", TEST_LOCATION );
- assert2 = true;
- }
- catch( ... )
- {
- tet_result( TET_FAIL );
- }
- DALI_TEST_EQUALS( offset, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
- DALI_TEST_CHECK( assert1 && assert2 );
-
- END_TEST;
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-#include <stdlib.h>
-#include <dali-toolkit-test-suite-utils.h>
-#include <dali-toolkit/dali-toolkit.h>
-
-
-// Internal headers are allowed here
-#include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-dbg.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-paragraph-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
-#include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
-
-using namespace Dali;
-using namespace Dali::Toolkit;
-using namespace Dali::Toolkit::Internal;
-
-void dali_text_view_startup(void)
-{
- test_return_value = TET_UNDEF;
-}
-
-void dali_text_view_cleanup(void)
-{
- test_return_value = TET_PASS;
-}
-
-
-namespace
-{
-
-const Toolkit::Internal::TextView::LayoutParameters DEFAULT_LAYOUT_PARAMETERS;
-const Toolkit::Internal::TextView::VisualParameters DEFAULT_VISUAL_PARAMETERS;
-
-// Data structures used to create an 'experiment' in TET cases
-
-struct SplitWordTest
-{
- std::string description;
- std::string input;
- std::size_t position;
- std::string firstResult;
- std::string lastResult;
-};
-
-struct SplitParagraphTest
-{
- std::string description;
- std::string input;
- std::size_t wordIndex;
- std::size_t characterIndex;
- std::size_t characterParagraphIndex;
- float lineHeightOffset;
- std::string firstResult;
- std::string lastResult;
-};
-
-struct MergeWordsTest
-{
- std::string description;
- std::string inputFirst;
- std::string inputLast;
- std::string result;
-};
-
-struct MergeParagraphsTest
-{
- std::string description;
- std::string inputFirst;
- std::string inputLast;
- float lineHeightOffset;
- std::string result;
-};
-
-struct RemoveCharactersFromWordTest
-{
- std::string description;
- std::string input;
- std::size_t position;
- std::size_t numberOfCharacters;
- std::string result;
-};
-
-struct RemoveWordsFromParagraphTest
-{
- std::string description;
- std::string input;
- std::size_t wordIndex;
- std::size_t numberOfWords;
- float lineHeightOffset;
- std::string result;
-};
-
-enum UpdateTextInfoOperation
-{
- Insert,
- Remove,
- Replace
-};
-
-struct UpdateTextInfoTest
-{
- std::string description;
- UpdateTextInfoOperation operation;
- std::string input;
- std::size_t position;
- std::size_t numberOfCharacters;
- std::string inputText;
- float lineHeightOffset;
- std::string result;
-};
-
-// Useful Print functions when something goes wrong.
-
-void Print( const TextViewProcessor::CharacterLayoutInfo& character )
-{
- std::cout << " height : " << character.mSize.height << std::endl;
- std::cout << " advance : " << character.mSize.width << std::endl;
- std::cout << " bearing : " << character.mBearing << std::endl;
- std::cout << " ascender : " << character.mAscender << std::endl;
- std::cout << " position : " << character.mPosition << std::endl;
-
- TextActor textActor = TextActor::DownCast( character.mGlyphActor );
- if( textActor )
- {
- std::cout << "[" << textActor.GetText() << "]";
- }
-}
-
-void Print( const TextViewProcessor::WordLayoutInfo& word )
-{
- std::cout << "[";
- std::cout << " mSize : " << word.mSize << std::endl;
- std::cout << " mAscender : " << word.mAscender << std::endl;
- std::cout << " mType : " << word.mType << std::endl;
- std::cout << "mNumberOfCharacters : " << word.mCharactersLayoutInfo.size() << std::endl;
- std::cout << "[";
- for( TextViewProcessor::CharacterLayoutInfoContainer::const_iterator it = word.mCharactersLayoutInfo.begin(), endIt = word.mCharactersLayoutInfo.end(); it != endIt; ++it )
- {
- Print( *it );
- }
- std::cout << "]"; std::cout << std::endl;
- std::cout << "]"; std::cout << std::endl;
-}
-
-void Print( const TextViewProcessor::ParagraphLayoutInfo& paragraph )
-{
- std::cout << "<";
- std::cout << " mSize : " << paragraph.mSize << std::endl;
- std::cout << " mAscender : " << paragraph.mAscender << std::endl;
- std::cout << "mNumberOfCharacters : " << paragraph.mNumberOfCharacters << std::endl;
- for( TextViewProcessor::WordLayoutInfoContainer::const_iterator it = paragraph.mWordsLayoutInfo.begin(), endIt = paragraph.mWordsLayoutInfo.end(); it != endIt; ++it )
- {
- Print( *it );
- }
- std::cout << ">" << std::endl;
-}
-
-void Print( const TextViewProcessor::TextLayoutInfo& text )
-{
- std::cout << "||";
- for( TextViewProcessor::ParagraphLayoutInfoContainer::const_iterator it = text.mParagraphsLayoutInfo.begin(), endIt = text.mParagraphsLayoutInfo.end(); it != endIt; ++it )
- {
- Print( *it );
- }
- std::cout << "||" << std::endl;
-}
-
-std::string GetText( const TextViewProcessor::WordLayoutInfo& word, const Text& paragraphText )
-{
- Text text;
-
- paragraphText.GetSubText( word.mFirstCharacter, word.mFirstCharacter + word.mCharactersLayoutInfo.size() - 1u, text );
-
- return text.GetText();
-}
-
-std::string GetText( const TextViewProcessor::ParagraphLayoutInfo& paragraph )
-{
- std::string text;
-
- for( TextViewProcessor::WordLayoutInfoContainer::const_iterator it = paragraph.mWordsLayoutInfo.begin(), endIt = paragraph.mWordsLayoutInfo.end(); it != endIt; ++it )
- {
- text += GetText( *it, paragraph.mText );
- }
-
- return text;
-}
-
-// Test functions used to check if two data structures are equal.
-
-bool TestEqual( float x, float y )
-{
- return ( fabsf( x - y ) < 0.001f );
-}
-
-bool TestEqual( const TextViewProcessor::CharacterLayoutInfo& character1,
- const TextViewProcessor::CharacterLayoutInfo& character2 )
-{
- if( !TestEqual( character1.mSize.height, character2.mSize.height ) )
- {
- return false;
- }
- if( !TestEqual( character1.mSize.width, character2.mSize.width ) )
- {
- return false;
- }
- if( !TestEqual( character1.mBearing, character2.mBearing ) )
- {
- return false;
- }
-
- if( !TestEqual( character1.mPosition.x, character2.mPosition.x ) )
- {
- return false;
- }
- if( !TestEqual( character1.mPosition.y, character2.mPosition.y ) )
- {
- return false;
- }
-
- if( !TestEqual( character1.mAscender, character2.mAscender ) )
- {
- return false;
- }
-
- if( character1.mGlyphActor && !character2.mGlyphActor )
- {
- return false;
- }
-
- if( !character1.mGlyphActor && character2.mGlyphActor )
- {
- return false;
- }
-
- std::string text1;
- std::string text2;
- TextStyle style1;
- TextStyle style2;
-
- TextActor textActor1 = TextActor::DownCast( character1.mGlyphActor );
- TextActor textActor2 = TextActor::DownCast( character2.mGlyphActor );
- if( textActor1 )
- {
- text1 = textActor1.GetText();
- style1 = textActor1.GetTextStyle();
-
- text2 = textActor2.GetText();
- style2 = textActor2.GetTextStyle();
- }
-
- if( text1 != text2 )
- {
- return false;
- }
-
- if( style1 != style2 )
- {
- return false;
- }
-
- return true;
-}
-
-bool TestEqual( const TextViewProcessor::WordLayoutInfo& word1,
- const TextViewProcessor::WordLayoutInfo& word2 )
-{
- if( !TestEqual( word1.mSize.x, word2.mSize.x ) )
- {
- return false;
- }
- if( !TestEqual( word1.mSize.y, word2.mSize.y ) )
- {
- return false;
- }
-
- if( !TestEqual( word1.mAscender, word2.mAscender ) )
- {
- return false;
- }
-
- if( word1.mType != word2.mType )
- {
- return false;
- }
-
- if( word1.mCharactersLayoutInfo.size() != word2.mCharactersLayoutInfo.size() )
- {
- return false;
- }
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::const_iterator it1 = word1.mCharactersLayoutInfo.begin(), endIt1 = word1.mCharactersLayoutInfo.end(),
- it2 = word2.mCharactersLayoutInfo.begin(), endIt2 = word2.mCharactersLayoutInfo.end();
- ( it1 != endIt1 ) && ( it2 != endIt2 );
- ++it1, ++it2 )
- {
- if( !TestEqual( *it1, *it2 ) )
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool TestEqual( const TextViewProcessor::ParagraphLayoutInfo& paragraph1,
- const TextViewProcessor::ParagraphLayoutInfo& paragraph2 )
-{
- if( !TestEqual( paragraph1.mSize.x, paragraph2.mSize.x ) )
- {
- return false;
- }
- if( !TestEqual( paragraph1.mSize.y, paragraph2.mSize.y ) )
- {
- return false;
- }
-
- if( !TestEqual( paragraph1.mAscender, paragraph2.mAscender ) )
- {
- return false;
- }
-
- if( paragraph1.mNumberOfCharacters != paragraph2.mNumberOfCharacters )
- {
- return false;
- }
-
- if( paragraph1.mWordsLayoutInfo.size() != paragraph2.mWordsLayoutInfo.size() )
- {
- return false;
- }
-
- for( TextViewProcessor::WordLayoutInfoContainer::const_iterator it1 = paragraph1.mWordsLayoutInfo.begin(), endIt1 = paragraph1.mWordsLayoutInfo.end(),
- it2 = paragraph2.mWordsLayoutInfo.begin(), endIt2 = paragraph2.mWordsLayoutInfo.end();
- ( it1 != endIt1 ) && ( it2 != endIt2 );
- ++it1, ++it2 )
- {
- if( !TestEqual( *it1, *it2 ) )
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool TestEqual( const TextViewProcessor::TextLayoutInfo& text1,
- const TextViewProcessor::TextLayoutInfo& text2 )
-{
- if( !TestEqual( text1.mWholeTextSize.x, text2.mWholeTextSize.x ) )
- {
- return false;
- }
- if( !TestEqual( text1.mWholeTextSize.y, text2.mWholeTextSize.y ) )
- {
- return false;
- }
-
- if( !TestEqual( text1.mMaxWordWidth, text2.mMaxWordWidth ) )
- {
- return false;
- }
-
- if( text1.mNumberOfCharacters != text2.mNumberOfCharacters )
- {
- return false;
- }
-
- if( text1.mParagraphsLayoutInfo.size() != text2.mParagraphsLayoutInfo.size() )
- {
- return false;
- }
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::const_iterator it1 = text1.mParagraphsLayoutInfo.begin(), endIt1 = text1.mParagraphsLayoutInfo.end(),
- it2 = text2.mParagraphsLayoutInfo.begin(), endIt2 = text2.mParagraphsLayoutInfo.end();
- ( it1 != endIt1 ) && ( it2 != endIt2 );
- ++it1, ++it2 )
- {
- if( !TestEqual( *it1, *it2 ) )
- {
- return false;
- }
- }
-
- return true;
-}
-
-/**
- * Splits the \e input word in two by the given \e position and checks the results with \e firstResult and \e lastResult.
- *
- * If the test fails it prints a short description and the line where this function was called.
- *
- * @param description Short description of the experiment. i.e. "Split the word from the beginning. (position 0)".
- * @param input The input word.
- * @param position Where to split the word.
- * @param firstResult First part of the split word.
- * @param lastResult Last part of the split word.
- * @param location Where this function has been called.
- *
- * @return \e true if the experiment is successful. Otherwise returns \e false.
- */
-bool TestSplitWord( const std::string& description, const std::string& input, const size_t position, const std::string& firstResult, const std::string& lastResult, const char* location )
-{
- tet_printf( "%s\n", description.c_str() );
-
- // Create layout info for the input word.
- Toolkit::Internal::TextView::RelayoutData relayoutData;
- TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray inputStyledText;
- MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
-
- TextViewProcessor::CreateTextInfo( inputStyledText,
- DEFAULT_LAYOUT_PARAMETERS,
- relayoutData );
-
- // Get the input word
- TextViewProcessor::WordLayoutInfo inputWordLayout;
-
- if( !inputLayout.mParagraphsLayoutInfo.empty() )
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraph( *inputLayout.mParagraphsLayoutInfo.begin() );
- if( !paragraph.mWordsLayoutInfo.empty() )
- {
- inputWordLayout = *( *inputLayout.mParagraphsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
- }
- }
-
- // Create layout info for the first part of the result (after split the word)
-
- Toolkit::Internal::TextView::RelayoutData firstRelayoutData;
- TextViewProcessor::TextLayoutInfo& firstResultLayout( firstRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray firstResultStyledText;
- MarkupProcessor::GetStyledTextArray( firstResult, firstResultStyledText, true );
-
- TextViewProcessor::CreateTextInfo( firstResultStyledText,
- DEFAULT_LAYOUT_PARAMETERS,
- firstRelayoutData );
-
- // Get the first result word
- TextViewProcessor::WordLayoutInfo firstResultWordLayout;
-
- if( !firstResultLayout.mParagraphsLayoutInfo.empty() )
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraph( *firstResultLayout.mParagraphsLayoutInfo.begin() );
- if( !paragraph.mWordsLayoutInfo.empty() )
- {
- firstResultWordLayout = *( *firstResultLayout.mParagraphsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
- }
- }
-
- // Create layout info for the last part of the result (after split the word)
-
- Toolkit::Internal::TextView::RelayoutData lastRelayoutData;
- TextViewProcessor::TextLayoutInfo& lastResultLayout( lastRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray lastResultStyledText;
- MarkupProcessor::GetStyledTextArray( lastResult, lastResultStyledText, true );
-
- TextViewProcessor::CreateTextInfo( lastResultStyledText,
- DEFAULT_LAYOUT_PARAMETERS,
- lastRelayoutData );
-
- // Get the last result word
- TextViewProcessor::WordLayoutInfo lastResultWordLayout;
-
- if( !lastResultLayout.mParagraphsLayoutInfo.empty() )
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraph( *lastResultLayout.mParagraphsLayoutInfo.begin() );
- if( !paragraph.mWordsLayoutInfo.empty() )
- {
- lastResultWordLayout = *( *lastResultLayout.mParagraphsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
- }
- }
-
- // Split the word.
-
- TextViewProcessor::WordLayoutInfo lastWordLayoutInfo;
-
- SplitWord( position,
- inputWordLayout,
- lastWordLayoutInfo );
-
- // Test results
- if( !TestEqual( inputWordLayout, firstResultWordLayout ) )
- {
- tet_printf( "Fail. different layout info. %s\n", location );
- return false;
- }
-
- if( !TestEqual( lastWordLayoutInfo, lastResultWordLayout ) )
- {
- tet_printf( "Fail. different layout info. %s\n", location );
- return false;
- }
-
- return true;
-}
-
-/**
- * Splits the \e input paragraph in two by the given \e wordIndex and \e characterIndex and checks the results with \e firstResult and \e lastResult.
- *
- * If the test fails it prints a short description and the line where this function was called.
- *
- * @param description Short description of the experiment. i.e. "Split the paragraph from the beginning. (wordIndex 0 and characterIndex 0)".
- * @param input The input word.
- * @param wordIndex Index to the word within the paragraph where to split it.
- * @param characterIndex Where to split the word.
- * @param characterIndex Character index within the paragraph.
- * @param lineHeightOffset Offset between lines.
- * @param firstResult First part of the split paragraph.
- * @param lastResult Last part of the split paragraph.
- * @param location Where this function has been called.
- *
- * @return \e true if the experiment is successful. Otherwise returns \e false.
- */
-bool TestSplitParagraph( const std::string& description,
- const std::string& input,
- size_t wordIndex,
- size_t characterIndex,
- size_t characterParagraphIndex,
- float lineHeightOffset,
- const std::string& firstResult,
- const std::string& lastResult,
- const char* location )
-{
- tet_printf( "%s\n", description.c_str() );
-
- // Create layout info for the input paragraph.
- Toolkit::Internal::TextView::RelayoutData relayoutData;
- TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray inputStyledText;
- MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
-
- TextViewProcessor::CreateTextInfo( inputStyledText,
- Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Center,
- PointSize( lineHeightOffset ),
- true ),
- relayoutData );
-
- // Get the input paragraph
- TextViewProcessor::ParagraphLayoutInfo inputParagraphLayout;
-
- if( !inputLayout.mParagraphsLayoutInfo.empty() )
- {
- inputParagraphLayout = *inputLayout.mParagraphsLayoutInfo.begin();
- }
-
- // Create layout info for the first part of the result (after split the paragraph)
-
- Toolkit::Internal::TextView::RelayoutData firstRelayoutData;
- TextViewProcessor::TextLayoutInfo& firstResultLayout( firstRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray firstResultStyledText;
- MarkupProcessor::GetStyledTextArray( firstResult, firstResultStyledText, true );
-
- TextViewProcessor::CreateTextInfo( firstResultStyledText,
- Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Center,
- PointSize( lineHeightOffset ),
- true ),
- firstRelayoutData );
-
- // Get the first result paragraph
- TextViewProcessor::ParagraphLayoutInfo firstResultParagraphLayout;
-
- if( !firstResultLayout.mParagraphsLayoutInfo.empty() )
- {
- firstResultParagraphLayout = *firstResultLayout.mParagraphsLayoutInfo.begin();
- }
-
- // Create layout info for the last part of the result (after split the paragraph)
-
- Toolkit::Internal::TextView::RelayoutData lastRelayoutData;
- TextViewProcessor::TextLayoutInfo& lastResultLayout( lastRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray lastResultStyledText;
- MarkupProcessor::GetStyledTextArray( lastResult, lastResultStyledText, true );
-
- TextViewProcessor::CreateTextInfo( lastResultStyledText,
- Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Center,
- PointSize( lineHeightOffset ),
- true ),
- lastRelayoutData );
-
- // Get the last result paragraph
- TextViewProcessor::ParagraphLayoutInfo lastResultParagraphLayout;
-
- if( !lastResultLayout.mParagraphsLayoutInfo.empty() )
- {
- lastResultParagraphLayout = *lastResultLayout.mParagraphsLayoutInfo.begin();
- }
-
- // Split the paragraph.
-
- TextViewProcessor::ParagraphLayoutInfo lastParagraphLayoutInfo;
-
- TextViewProcessor::TextInfoIndices indices( 0, wordIndex, characterIndex );
- indices.mCharacterParagraphIndex = characterParagraphIndex;
-
- SplitParagraph( indices,
- PointSize( lineHeightOffset ),
- inputParagraphLayout,
- lastParagraphLayoutInfo );
-
- // Test results
- if( !TestEqual( inputParagraphLayout, firstResultParagraphLayout ) )
- {
- tet_printf( "Fail. different first layout info. %s\n", location );
- return false;
- }
-
- if( !TestEqual( lastParagraphLayoutInfo, lastResultParagraphLayout ) )
- {
- tet_printf( "Fail. different last layout info. %s\n", location );
- return false;
- }
-
- return true;
-}
-
-/**
- * Merges the \e inputFirst word and the \e inputLast word, and checks the results with \e result.
- *
- * If the test fails it prints a short description and the line where this function was called.
- *
- * @param description Short description of the experiment. i.e. "Merge two words with same style".
- * @param inputFirst The first part of the word.
- * @param inputLast The last part of the word.
- * @param result The merged word.
- * @param location Where this function has been called.
- *
- * @return \e true if the experiment is successful. Otherwise returns \e false.
- */
-bool TestMergeWords( const std::string& description, const std::string& inputFirst, const std::string& inputLast, const std::string& result, const char* location )
-{
- tet_printf( "%s\n", description.c_str() );
-
- // Create layout info for the inputFirst word.
- Toolkit::Internal::TextView::RelayoutData firstRelayoutData;
- TextViewProcessor::TextLayoutInfo& inputFirstLayout( firstRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray inputFirstStyledText;
- MarkupProcessor::GetStyledTextArray( inputFirst, inputFirstStyledText, true );
-
- TextViewProcessor::CreateTextInfo( inputFirstStyledText,
- DEFAULT_LAYOUT_PARAMETERS,
- firstRelayoutData );
-
- // Get the input word
- TextViewProcessor::WordLayoutInfo inputFirstWordLayout;
-
- if( !inputFirstLayout.mParagraphsLayoutInfo.empty() )
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraph( *inputFirstLayout.mParagraphsLayoutInfo.begin() );
- if( !paragraph.mWordsLayoutInfo.empty() )
- {
- inputFirstWordLayout = *( *inputFirstLayout.mParagraphsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
- }
- }
-
- // Create layout info for the inputLast word.
- Toolkit::Internal::TextView::RelayoutData lastRelayoutData;
- TextViewProcessor::TextLayoutInfo& inputLastLayout( lastRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray inputLastStyledText;
- MarkupProcessor::GetStyledTextArray( inputLast, inputLastStyledText, true );
-
- TextViewProcessor::CreateTextInfo( inputLastStyledText,
- DEFAULT_LAYOUT_PARAMETERS,
- lastRelayoutData );
-
- // Get the input word
- TextViewProcessor::WordLayoutInfo inputLastWordLayout;
-
- if( !inputLastLayout.mParagraphsLayoutInfo.empty() )
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraph( *inputLastLayout.mParagraphsLayoutInfo.begin() );
- if( !paragraph.mWordsLayoutInfo.empty() )
- {
- inputLastWordLayout = *( *inputLastLayout.mParagraphsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
- }
- }
-
- // Create layout info for the result word.
- Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
- TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray resultStyledText;
- MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
-
- TextViewProcessor::CreateTextInfo( resultStyledText,
- DEFAULT_LAYOUT_PARAMETERS,
- resultRelayoutData );
-
- // Get the result word
- TextViewProcessor::WordLayoutInfo resultWordLayout;
-
- if( !resultLayout.mParagraphsLayoutInfo.empty() )
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraph( *resultLayout.mParagraphsLayoutInfo.begin() );
- if( !paragraph.mWordsLayoutInfo.empty() )
- {
- resultWordLayout = *( *resultLayout.mParagraphsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
- }
- }
-
- MergeWord( inputFirstWordLayout,
- inputLastWordLayout );
-
- if( !TestEqual( inputFirstWordLayout, resultWordLayout ) )
- {
- tet_printf( "Fail. different layout info. %s\n", location );
- return false;
- }
-
- return true;
-}
-
-/**
- * Merges the \e inputFirst paragraph and the \e inputLast paragraph, and checks the results with \e result.
- *
- * If the test fails it prints a short description and the line where this function was called.
- *
- * @param description Short description of the experiment.
- * @param inputFirst The first part of the paragraph.
- * @param inputLast The last part of the paragraph.
- * @param lineHeightOffset Offset between lines.
- * @param result The merged paragraph.
- * @param location Where this function has been called.
- *
- * @return \e true if the experiment is successful. Otherwise returns \e false.
- */
-bool TestMergeParagraphs( const std::string& description, const std::string& inputFirst, const std::string& inputLast, const float lineHeightOffset, const std::string& result, const char* location )
-{
- tet_printf( "%s\n", description.c_str() );
-
- // Create layout info for the inputFirst paragraph.
- Toolkit::Internal::TextView::RelayoutData firstRelayoutData;
- TextViewProcessor::TextLayoutInfo& inputFirstLayout( firstRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray inputFirstStyledText;
- MarkupProcessor::GetStyledTextArray( inputFirst, inputFirstStyledText, true );
-
- TextViewProcessor::CreateTextInfo( inputFirstStyledText,
- Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Center,
- PointSize( lineHeightOffset ),
- true ),
- firstRelayoutData );
-
- // Get the input word
- TextViewProcessor::ParagraphLayoutInfo inputFirstParagraphLayout;
-
- if( !inputFirstLayout.mParagraphsLayoutInfo.empty() )
- {
- inputFirstParagraphLayout = *inputFirstLayout.mParagraphsLayoutInfo.begin();
- }
-
- // Create layout info for the inputLast paragraph.
- Toolkit::Internal::TextView::RelayoutData lastRelayoutData;
- TextViewProcessor::TextLayoutInfo& inputLastLayout( lastRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray inputLastStyledText;
- MarkupProcessor::GetStyledTextArray( inputLast, inputLastStyledText, true );
-
- TextViewProcessor::CreateTextInfo( inputLastStyledText,
- Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Center,
- PointSize( lineHeightOffset ),
- true ),
- lastRelayoutData );
-
- // Get the input word
- TextViewProcessor::ParagraphLayoutInfo inputLastParagraphLayout;
-
- if( !inputLastLayout.mParagraphsLayoutInfo.empty() )
- {
- inputLastParagraphLayout = *inputLastLayout.mParagraphsLayoutInfo.begin();
- }
-
- // Create layout info for the result word.
- Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
- TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray resultStyledText;
- MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
-
- TextViewProcessor::CreateTextInfo( resultStyledText,
- Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Center,
- PointSize( lineHeightOffset ),
- true ),
- resultRelayoutData );
-
- // Get the result word
- TextViewProcessor::ParagraphLayoutInfo resultParagraphLayout;
-
- if( !resultLayout.mParagraphsLayoutInfo.empty() )
- {
- resultParagraphLayout = *resultLayout.mParagraphsLayoutInfo.begin();
- }
-
- MergeParagraph( inputFirstParagraphLayout,
- inputLastParagraphLayout );
-
- if( !TestEqual( inputFirstParagraphLayout, resultParagraphLayout ) )
- {
- tet_printf( "Fail. different layout info. %s\n", location );
- return false;
- }
-
- return true;
-}
-
-/**
- * Removes from the \e input word the \e numberOfCharacters characters starting from the given \e position and checks the results with \e result.
- *
- * If the test fails it prints a short description and the line where this function was called.
- *
- * @param description Short description of the experiment. i.e. "Remove a whole word. Merge".
- * @param input The input word.
- * @param position Where to start to remove characters
- * @param numberOfCharacters The number of characters to remove.
- * @param result The word without the removed characters.
- * @param location Where this function has been called.
- *
- * @return \e true if the experiment is successful. Otherwise returns \e false.
- */
-bool TestRemoveCharactersFromWord( const std::string& description, const std::string& input, const std::size_t position, const std::size_t numberOfCharacters, const std::string& result, const char* location )
-{
- tet_printf( "%s\n", description.c_str() );
-
- // Create layout info for the input word.
- Toolkit::Internal::TextView::RelayoutData relayoutData;
- TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray inputStyledText;
- MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
-
- TextViewProcessor::CreateTextInfo( inputStyledText,
- DEFAULT_LAYOUT_PARAMETERS,
- relayoutData );
-
- // Get the input word
- TextViewProcessor::WordLayoutInfo inputWordLayout;
-
- if( !inputLayout.mParagraphsLayoutInfo.empty() )
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraph( *inputLayout.mParagraphsLayoutInfo.begin() );
- if( !paragraph.mWordsLayoutInfo.empty() )
- {
- inputWordLayout = *( *inputLayout.mParagraphsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
- }
- }
-
- // Create layout info for the result word.
- Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
- TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray resultStyledText;
- MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
-
- TextViewProcessor::CreateTextInfo( resultStyledText,
- DEFAULT_LAYOUT_PARAMETERS,
- resultRelayoutData );
-
- // Get the result word
- TextViewProcessor::WordLayoutInfo resultWordLayout;
-
- if( !resultLayout.mParagraphsLayoutInfo.empty() )
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraph( *resultLayout.mParagraphsLayoutInfo.begin() );
- if( !paragraph.mWordsLayoutInfo.empty() )
- {
- resultWordLayout = *( *resultLayout.mParagraphsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
- }
- }
-
- RemoveCharactersFromWord( position,
- numberOfCharacters,
- inputWordLayout );
-
- if( !TestEqual( inputWordLayout, resultWordLayout ) )
- {
- tet_printf( "Fail. different layout info. %s\n", location );
- return false;
- }
-
- return true;
-}
-
-/**
- * Removes from the \e input paragraph the \e numberOfWords words starting from the given \e wordIndex and checks the results with \e result.
- *
- * If the test fails it prints a short description and the line where this function was called.
- *
- * @param description Short description of the experiment.
- * @param input The input paragraph.
- * @param wordIndex Index within the paragraph where to start to remove words.
- * @param numberOfWords The number of words to remove.
- * @param lineHeightOffset Offset between lines.
- * @param result The paragraph without the removed words.
- * @param location Where this function has been called.
- *
- * @return \e true if the experiment is successful. Otherwise returns \e false.
- */
-bool TestRemoveWordsFromParagraph( const std::string& description, const std::string& input, const std::size_t wordIndex, const std::size_t numberOfWords, const float lineHeightOffset, const std::string& result, const char* location )
-{
- tet_printf( "%s\n", description.c_str() );
-
- // Create layout info for the input paragraph.
- Toolkit::Internal::TextView::RelayoutData relayoutData;
- TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray inputStyledText;
- MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
-
- TextViewProcessor::CreateTextInfo( inputStyledText,
- Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Center,
- PointSize( lineHeightOffset ),
- true ),
- relayoutData );
-
- // Get the input paragraph
- TextViewProcessor::ParagraphLayoutInfo inputParagraphLayout;
-
- if( !inputLayout.mParagraphsLayoutInfo.empty() )
- {
- inputParagraphLayout = *inputLayout.mParagraphsLayoutInfo.begin();
- }
-
- // Create layout info for the result paragraph.
- Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
- TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray resultStyledText;
- MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
-
- TextViewProcessor::CreateTextInfo( resultStyledText,
- Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Center,
- PointSize( lineHeightOffset ),
- true ),
- resultRelayoutData );
-
- // Get the result paragraph
- TextViewProcessor::ParagraphLayoutInfo resultParagraphLayout;
-
- if( !resultLayout.mParagraphsLayoutInfo.empty() )
- {
- resultParagraphLayout = *resultLayout.mParagraphsLayoutInfo.begin();
- }
-
- RemoveWordsFromParagraph( wordIndex,
- numberOfWords,
- lineHeightOffset,
- inputParagraphLayout );
-
- if( !TestEqual( inputParagraphLayout, resultParagraphLayout ) )
- {
- tet_printf( "Fail. different layout info. %s\n", location );
- tet_printf( " input : [%s]\n", input.c_str() );
- tet_printf( " result : [%s]\n", GetText( resultParagraphLayout ).c_str() );
- tet_printf( " expected result : [%s]\n\n", result.c_str() );
-
- Print(inputParagraphLayout); std::cout << std::endl << std::endl;
- Print(resultParagraphLayout); std::cout << std::endl;
- return false;
- }
-
- return true;
-}
-
-/**
- * Tests inserts, removes and updates operation in the given \e input text and checks with the given \e result.
- *
- * If the test fails it prints a short description and the line where this function was called.
- *
- * @param description Short description of the experiment.
- * @param operation Type of update operation (insert, remove, replace)
- * @param input The input text.
- * @param position Where to insert, remove or replace text.
- * @param numberOfCharacters Number of characters to remove or replace.
- * @param inputText Inserted or updated text.
- * @param lineHeightOffset Offset between lines.
- * @param result Expected result.
- * @param location Where this function has been called.
- *
- * @return \e true if the experiment is successful. Otherwise returns \e false.
- */
-bool TestUpdateTextInfo( const std::string& description,
- UpdateTextInfoOperation operation,
- const std::string& input,
- std::size_t position,
- std::size_t numberOfCharacters,
- const std::string& inputText,
- float lineHeightOffset,
- const std::string& result,
- const char* location )
-{
- tet_printf( "%s\n", description.c_str() );
-
- // Create layout info for the input.
- Toolkit::Internal::TextView::RelayoutData relayoutData;
- TextViewProcessor::TextLayoutInfo& inputLayout( relayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray inputStyledText;
- MarkupProcessor::GetStyledTextArray( input, inputStyledText, true );
-
- TextViewProcessor::CreateTextInfo( inputStyledText,
- Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Center,
- PointSize( lineHeightOffset ),
- true ),
- relayoutData );
-
- // Create layout info for the result.
- Toolkit::Internal::TextView::RelayoutData resultRelayoutData;
- TextViewProcessor::TextLayoutInfo& resultLayout( resultRelayoutData.mTextLayoutInfo );
-
- MarkupProcessor::StyledTextArray resultStyledText;
- MarkupProcessor::GetStyledTextArray( result, resultStyledText, true );
-
- TextViewProcessor::CreateTextInfo( resultStyledText,
- Toolkit::Internal::TextView::LayoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Center,
- PointSize( lineHeightOffset ),
- true ),
- resultRelayoutData );
-
- // Choose operation and call appropiate UpdateTextInfo() method.
- const Toolkit::Internal::TextView::LayoutParameters layoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Center,
- PointSize( lineHeightOffset ),
- true );
-
- switch( operation )
- {
- case Insert:
- {
- MarkupProcessor::StyledTextArray inputStyledText;
- MarkupProcessor::GetStyledTextArray( inputText, inputStyledText, true );
-
- TextViewProcessor::UpdateTextInfo( position,
- inputStyledText,
- layoutParameters,
- relayoutData );
- break;
- }
- case Remove:
- {
- TextViewProcessor::UpdateTextInfo( position,
- numberOfCharacters,
- layoutParameters,
- relayoutData,
- TextViewProcessor::CLEAR_TEXT );
- break;
- }
- case Replace:
- {
- MarkupProcessor::StyledTextArray inputStyledText;
- MarkupProcessor::GetStyledTextArray( inputText, inputStyledText, true );
-
- TextViewProcessor::UpdateTextInfo( position,
- numberOfCharacters,
- inputStyledText,
- layoutParameters,
- relayoutData );
- break;
- }
- default:
- {
- tet_printf( "TestUpdateTextInfo: unknown update operation. %s\n", location );
- return false;
- }
- }
-
- if( !TestEqual( inputLayout, resultLayout ) )
- {
- tet_printf( "Fail. different layout info. %s\n", location );
-
- // std::cout << " result : "; Print( inputLayout );
- // std::cout << " expected result : "; Print( resultLayout );
- return false;
- }
-
- return true;
-}
-
-} // namespace
-
-
-int UtcDaliTextViewCreateTextInfo(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewCreateTextInfo : ");
-
- // Metrics for characters
-
- // Font size = 10
- // size : [9.48351, 9.48351]
- // advance : 9.48351
- // bearing : 8.53516
- // ascender : 8.53516
-
- // Font size = 12
- // size : [11.3802, 11.3802]
- // advance : 11.3802
- // bearing : 10.2422
- // ascender : 10.2422
-
- // Font size = 14
- // size : [13.2769, 13.2769]
- // advance : 13.2769
- // bearing : 11.9492
- // ascender : 11.9492
-
- const float HEIGHT_10( 9.48351f );
- const float ADVANCE_10( 9.48351f );
- const float BEARING_10( 8.53516f );
- const float ASCENDER_10( 8.53516f );
-
- const float HEIGHT_12( 11.3802f );
- const float ADVANCE_12( 11.3802f );
- const float BEARING_12( 10.2422f );
- const float ASCENDER_12( 10.2422f );
-
-
- // Generate a text.
- Toolkit::Internal::TextView::RelayoutData relayoutData;
- TextViewProcessor::TextLayoutInfo& textLayoutInfo( relayoutData.mTextLayoutInfo );
-
- std::string text( "Hel<font size='10'>lo wo</font>rld!\n"
- "\n" );
-
- MarkupProcessor::StyledTextArray styledText;
- MarkupProcessor::GetStyledTextArray( text, styledText, true );
-
- TextViewProcessor::CreateTextInfo( styledText,
- DEFAULT_LAYOUT_PARAMETERS,
- relayoutData );
-
-
- // Build the text info with metric values.
-
- // Characters
-
- TextViewProcessor::CharacterLayoutInfo layoutInfo10; // ( [lo wo])
- layoutInfo10.mSize.height = HEIGHT_10;
- layoutInfo10.mSize.width = ADVANCE_10;
- layoutInfo10.mBearing = BEARING_10;
- layoutInfo10.mAscender = ASCENDER_10;
- TextViewProcessor::CharacterLayoutInfo layoutInfo12; // ( [Hel], [rld!] and [CR])
- layoutInfo12.mSize.height = HEIGHT_12;
- layoutInfo12.mSize.width = ADVANCE_12;
- layoutInfo12.mBearing = BEARING_12;
- layoutInfo12.mAscender = ASCENDER_12;
-
- // Words
-
- TextViewProcessor::WordLayoutInfo wordLayout1, wordLayout2, wordLayout3, wordLayout4;
-
- // Hello
- wordLayout1.mSize = Size( 3.f * ADVANCE_12 + 2.f * ADVANCE_10, HEIGHT_12 );
- wordLayout1.mAscender = ASCENDER_12;
- wordLayout1.mType = TextViewProcessor::NoSeparator;
-
- wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo12 ); // H
- wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo12 ); // e
- wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo12 ); // l
- wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo10 ); // l
- wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo10 ); // o
-
- // (white space)
- wordLayout2.mSize = Size( ADVANCE_10, HEIGHT_10 );
- wordLayout2.mAscender = ASCENDER_10;
- wordLayout2.mType = TextViewProcessor::WordSeparator;
- wordLayout2.mCharactersLayoutInfo.push_back( layoutInfo10 ); // (white space)
-
- // world!
- wordLayout3.mSize = Size( 2.f * ADVANCE_10 + 4.f * ADVANCE_12, HEIGHT_12 );
- wordLayout3.mAscender = ASCENDER_12;
- wordLayout3.mType = TextViewProcessor::NoSeparator;
- wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo10 ); // w
- wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo10 ); // o
- wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // r
- wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // l
- wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // d
- wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // !
-
- // (new paragraph character)
- wordLayout4.mSize = Size( 0.f, HEIGHT_12 );
- wordLayout4.mAscender = ASCENDER_12;
- wordLayout4.mType = TextViewProcessor::ParagraphSeparator;
- layoutInfo12.mSize.width = 0.f;
- wordLayout4.mCharactersLayoutInfo.push_back( layoutInfo12 ); // (new paragraph char)
-
- // Paragraphs
-
- TextViewProcessor::ParagraphLayoutInfo paragraphLayout1, paragraphLayout2, paragraphLayout3;
-
- paragraphLayout1.mSize = Size( 5.f * ADVANCE_10 + 7.f * ADVANCE_12, HEIGHT_12 );
- paragraphLayout1.mAscender = ASCENDER_12;
- paragraphLayout1.mNumberOfCharacters = 13;
- paragraphLayout1.mWordsLayoutInfo.push_back( wordLayout1 );
- paragraphLayout1.mWordsLayoutInfo.push_back( wordLayout2 );
- paragraphLayout1.mWordsLayoutInfo.push_back( wordLayout3 );
- paragraphLayout1.mWordsLayoutInfo.push_back( wordLayout4 );
-
- paragraphLayout2.mSize = Size( 0.f, HEIGHT_12 );
- paragraphLayout2.mAscender = ASCENDER_12;
- paragraphLayout2.mNumberOfCharacters = 1;
- paragraphLayout2.mWordsLayoutInfo.push_back( wordLayout4 );
-
- paragraphLayout3.mSize = Size( 0.f, HEIGHT_12 );
-
- // Text (layout)
- TextViewProcessor::TextLayoutInfo textLayout;
-
- textLayout.mWholeTextSize = Size( 5.f * ADVANCE_10 + 7.f * ADVANCE_12, 3.f * HEIGHT_12 );
- textLayout.mMaxWordWidth = 2.f * ADVANCE_10 + 4.f * ADVANCE_12;
- textLayout.mNumberOfCharacters = 14;
- textLayout.mParagraphsLayoutInfo.push_back( paragraphLayout1 );
- textLayout.mParagraphsLayoutInfo.push_back( paragraphLayout2 );
- textLayout.mParagraphsLayoutInfo.push_back( paragraphLayout3 );
-
- if(!TestEqual( textLayout, textLayoutInfo ))
- {
- std::cout << "Layout fails" << std::endl;
- Print(textLayout); std::cout << std::endl;
- Print(textLayoutInfo); std::cout << std::endl;
- }
-
- DALI_TEST_CHECK( TestEqual( textLayout, textLayoutInfo ) );
- END_TEST;
-}
-
-int UtcDaliTextViewSplitWord(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewSplitWord : ");
-
- struct SplitWordTest splitWordTests[] =
- {
- {
- std::string( "Split word, position 0." ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
- 0,
- std::string( "" ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
- },
- {
- std::string( "Split word, position 8." ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
- 8,
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
- std::string( "" ),
- },
- {
- std::string( "Split word, position 2." ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
- 2,
- std::string( "<font size='10'>He</font>" ),
- std::string( "<font size='12'>ll</font><font size='10'>oooo</font>" ),
- },
- {
- std::string( "Split word, position 3." ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
- 3,
- std::string( "<font size='10'>He</font><font size='12'>l</font>" ),
- std::string( "<font size='12'>l</font><font size='10'>oooo</font>" ),
- },
- {
- std::string( "Split word, position 4." ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo</font>" ),
- 4,
- std::string( "<font size='10'>He</font><font size='12'>ll</font>" ),
- std::string( "<font size='10'>oooo</font>" ),
- },
- };
- const std::size_t numberOfTests( 5u );
-
- for( std::size_t index = 0u; index < numberOfTests; ++index )
- {
- const SplitWordTest& test = splitWordTests[index];
-
- if( !TestSplitWord( test.description, test.input, test.position, test.firstResult, test.lastResult, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewUpdateTextInfo(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewUpdateTextInfo : ");
-
- struct UpdateTextInfoTest updateTextInfoTest[] =
- {
- // Remove operations
-
- {
- std::string( "Remove from new paragraph character to first character next paragraph." ),
- Remove,
- std::string("Hello world\nhello world."),
- 11,
- 2,
- std::string(""),
- 0.f,
- std::string("Hello worldello world."),
- },
- {
- std::string( "Replace style from new paragraph character to first character next paragraph." ),
- Replace,
- std::string("Hello world\nhello world."),
- 11,
- 2,
- std::string("<b>\nh</b>"),
- 0.f,
- std::string("Hello world<b>\nh</b>ello world."),
- },
- {
- std::string( "Remove from the beginning to the middle of last word." ),
- Remove,
- std::string("Hello world, hello world."),
- 0,
- 22,
- std::string(), // Not used.
- 0.f,
- std::string("ld."),
- },
- {
- std::string( "Remove from the beginning to the middle of the text." ),
- Remove,
- std::string("Hello world hello world."),
- 0,
- 12,
- std::string(), // Not used.
- 0.f,
- std::string("hello world."),
- },
- // Remove within the same word:
- // * within the same group of characters with same style.
- {
- std::string( "Remove within the same word, within the same group of characters with same style" ),
- Remove,
- std::string("Hello <font size='30'>world\nhello</font> world"),
- 7,
- 3,
- std::string(), // Not used.
- 0.f,
- std::string( "Hello <font size='30'>wd\nhello</font> world" )
- },
- // * whole group of characters (merge adjacent group of characters)
- {
- std::string( "Remove within the same word, whole group of characters (merge adjacent group of characters)" ),
- Remove,
- std::string("Hello <font size='30'>w<font size='20'>orl</font>d\nhello</font> world"),
- 7,
- 3,
- std::string(), // Not used.
- 0.f,
- std::string( "Hello <font size='30'>wd\nhello</font> world" )
- },
- // * whole group of characters (don't merge adjacent gtoup of characters)
- {
- std::string( "Remove within the same word, whole group of characters (don't merge adjacent gtoup of characters)" ),
- Remove,
- std::string("Hello <font size='30'>w</font>orl<font size='10'>d\nhello</font> world"),
- 7,
- 3,
- std::string(), // Not used.
- 0.f,
- std::string( "Hello <font size='30'>w</font><font size='10'>d\nhello</font> world" )
- },
- // * Remove whole word (merge words)
- {
- std::string( "Remove within the same word, whole word (merge words)" ),
- Remove,
- std::string("Hello <font size='30'>w</font>orl<font size='10'>d\nhello</font> world"),
- 5,
- 1,
- std::string(), // Not used.
- 0.f,
- std::string( "Hello<font size='30'>w</font>orl<font size='10'>d\nhello</font> world" )
- },
- // * Remove whole word (don't merge words)
- {
- std::string( "Remove within the same word, whole word (don't merge words)" ),
- Remove,
- std::string("Hello <font size='30'>w</font>orl<font size='10'>d\nhello</font> world"),
- 6,
- 5,
- std::string(), // Not used.
- 0.f,
- std::string( "Hello <font size='10'>\nhello</font> world" )
- },
- // * Remove whole word (merge paragraphs)
- {
- std::string( "Remove within the same word, whole word (merge paragraphs)" ),
- Remove,
- std::string("Hello <font size='30'>w</font>orl<font size='10'>d\nhello</font> world"),
- 11,
- 1,
- std::string(), // Not used.
- 0.f,
- std::string( "Hello <font size='30'>w</font>orl<font size='10'>dhello</font> world" )
- },
- // * Remove RTL text within LTR
- {
- std::string( "Remove within the same paragraph, RTL text within LTR." ),
- Remove,
- std::string("Hello world, שלום עולם, hello world"),
- 10,
- 15,
- std::string(), // Not used.
- 0.f,
- std::string( "Hello worlello world" )
- },
- // * Remove whole paragraph
- {
- std::string( "Remove whole paragraph" ),
- Remove,
- std::string("Hello world, hello world\n"
- "Hello world, hello world\n"
- "Hello world, hello world\n"
- "Hello world, hello world\n"),
- 25,
- 25,
- std::string(), // Not used.
- 0.f,
- std::string("Hello world, hello world\n"
- "Hello world, hello world\n"
- "Hello world, hello world\n"),
- },
- {
- std::string( "Remove whole paragraph" ),
- Remove,
- std::string("Hello world, hello world\n"
- "H"),
- 25,
- 1,
- std::string(), // Not used.
- 0.f,
- std::string("Hello world, hello world\n"),
- },
-
-
- // Insert operations
- {
- std::string( "insert some text" ),
- Insert,
- std::string("inpuext"),
- 4,
- 0, // Not used
- std::string( "t t" ),
- 0.f,
- std::string( "input text" )
- },
- {
- std::string( "Insert text at the end" ),
- Insert,
- std::string("touch "),
- 6,
- 0,
- std::string("me\nhello"),
- 0.f,
- std::string("touch me\nhello")
- },
-
- // Replace operations.
- {
- std::string( "Replace style from the beginning to some point in the middle of the text." ),
- Replace,
- std::string( "Hello <font color='green'>world</font>" ),
- 0,
- 7,
- std::string( "<font color='red'>Hello w</font>" ),
- 0.f,
- std::string( "<font color='red'>Hello w</font><font color='green'>orld</font>" )
- },
- {
- std::string( "Replace style from the middle of the text to the end." ),
- Replace,
- std::string( "Touch me\nhello" ),
- 6,
- 8,
- std::string( "<b>me\nhello</b>" ),
- 0.f,
- std::string( "Touch <b>me\nhello</b>" )
- },
- {
- std::string( "Remove characters from text. Previous next test:Replace style from the middle of the text 1." ),
- Remove,
- std::string( "Touch me\nhello\nworld" ),
- 6,
- 8,
- std::string( "" ),
- 0.f,
- std::string( "Touch \nworld" )
- },
- {
- std::string( "Insert styled text in the middle of a text. Previous: Replace style from the middle of the text 1." ),
- Insert,
- std::string( "Touch \nworld" ),
- 6,
- 0,
- std::string( "<b>me\nhello</b>" ),
- 0.f,
- std::string( "Touch <b>me\nhello</b>\nworld" )
- },
- {
- std::string( "Replace style from the middle of the text 1." ),
- Replace,
- std::string( "Touch me\nhello\nworld" ),
- 6,
- 8,
- std::string( "<b>me\nhello</b>" ),
- 0.f,
- std::string( "Touch <b>me\nhello</b>\nworld" )
- },
- {
- std::string( "Remove characters from text. Previous next test:Replace style from the middle of the text 2." ),
- Remove,
- std::string( "Touch me\nhello\nworld" ),
- 6,
- 9,
- std::string( "" ),
- 0.f,
- std::string( "Touch world" )
- },
- {
- std::string( "Replace style from the middle of the text 2." ),
- Replace,
- std::string( "Touch me\nhello\nworld" ),
- 6,
- 9,
- std::string( "<b>me\nhello\n</b>" ),
- 0.f,
- std::string( "Touch <b>me\nhello\n</b>world" )
- },
- };
- const std::size_t numberOfTests( 22u );
-
- for( std::size_t index = 0u; index < numberOfTests; ++index )
- {
- const UpdateTextInfoTest& test = updateTextInfoTest[index];
-
- if( !TestUpdateTextInfo( test.description, test.operation, test.input, test.position, test.numberOfCharacters, test.inputText, test.lineHeightOffset, test.result, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewSplitParagraph(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewSplitParagraph : ");
-
- struct SplitParagraphTest splitParagraphTests[] =
- {
- {
- std::string( "Split paragraph, wordPosition 0, position 0." ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
- 0,
- 0,
- 0,
- 3.f,
- std::string( "" ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
- },
- {
- std::string( "Split paragraph, wordPosition 10, position 4." ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
- 10,
- 4,
- 36,
- 0.f,
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
- std::string( "" ),
- },
- {
- std::string( "Split paragraph, wordPosition 2, position 4." ),
- std::string("<font size='10'>Hello </font>wor<font size='12'>ld, hello wo</font>rld"),
- 2,
- 4,
- 10,
- 0.f,
- std::string("<font size='10'>Hello </font>wor<font size='12'>l</font>"),
- std::string("<font size='12'>d, hello wo</font>rld")
- },
- {
- std::string( "Split paragraph, wordPosition 6, position 0." ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
- 6,
- 0,
- 21,
- 0.f,
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום " ),
- std::string( "עולם text text" ),
- },
- {
- std::string( "Split paragraph, wordPosition 4, position 0." ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
- 4,
- 0,
- 17,
- 0.f,
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> " ),
- std::string( "שלום עולם text text" ),
- },
- {
- std::string( "Split paragraph2, wordPosition 8, position 0." ),
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
- 8,
- 0,
- 27,
- 6.f,
- std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם " ),
- std::string( "text text" ),
- },
- };
- const std::size_t numberOfTests( 6u );
-
- for( std::size_t index = 0u; index < numberOfTests; ++index )
- {
- const SplitParagraphTest& test = splitParagraphTests[index];
-
- if( !TestSplitParagraph( test.description,
- test.input,
- test.wordIndex,
- test.characterIndex,
- test.characterParagraphIndex,
- test.lineHeightOffset,
- test.firstResult,
- test.lastResult,
- TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewMergeWord01(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewMergeWord01 : ");
-
- struct MergeWordsTest mergeWordsTests[] =
- {
- {
- std::string( "Merge words with same style." ),
- std::string( "Hel" ),
- std::string( "lo" ),
- std::string( "Hello" ),
- },
- {
- std::string( "Merge words with different styles." ),
- std::string( "<font size='10>Hel</font>" ),
- std::string( "<font size='20'>lo</font>" ),
- std::string( "<font size='10'>Hel</font><font size='20'>lo</font>" )
- },
- };
- const std::size_t numberOfTests( 2u );
-
- for( std::size_t index = 0u; index < numberOfTests; ++index )
- {
- const MergeWordsTest& test = mergeWordsTests[index];
-
- if( !TestMergeWords( test.description, test.inputFirst, test.inputLast, test.result, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewMergeWord02(void)
-{
- // Negative test.
- // It test white spaces and new paragraph characters can't be merged to other words.
-
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewMergeWord02 : ");
-
- // Generate three words
-
- Toolkit::Internal::TextView::RelayoutData relayoutData01;
- Toolkit::Internal::TextView::RelayoutData relayoutData02;
- Toolkit::Internal::TextView::RelayoutData relayoutData03;
- TextViewProcessor::TextLayoutInfo& textLayoutInfo01( relayoutData01.mTextLayoutInfo );
- TextViewProcessor::TextLayoutInfo& textLayoutInfo02( relayoutData02.mTextLayoutInfo );
- TextViewProcessor::TextLayoutInfo& textLayoutInfo03( relayoutData03.mTextLayoutInfo );
-
- std::string text01( " " );
- std::string text02( "\n" );
- std::string text03( "a" );
- MarkupProcessor::StyledTextArray styledText01;
- MarkupProcessor::StyledTextArray styledText02;
- MarkupProcessor::StyledTextArray styledText03;
- MarkupProcessor::GetStyledTextArray( text01, styledText01, true );
- MarkupProcessor::GetStyledTextArray( text02, styledText02, true );
- MarkupProcessor::GetStyledTextArray( text03, styledText03, true );
-
- TextViewProcessor::CreateTextInfo( styledText01,
- DEFAULT_LAYOUT_PARAMETERS,
- relayoutData01 );
-
- TextViewProcessor::WordLayoutInfo wordLayoutInfo01;
-
- wordLayoutInfo01 = *( *textLayoutInfo01.mParagraphsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
-
- TextViewProcessor::CreateTextInfo( styledText02,
- DEFAULT_LAYOUT_PARAMETERS,
- relayoutData02 );
-
- TextViewProcessor::WordLayoutInfo wordLayoutInfo02;
-
- wordLayoutInfo02 = *( *textLayoutInfo02.mParagraphsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
-
- TextViewProcessor::CreateTextInfo( styledText03,
- DEFAULT_LAYOUT_PARAMETERS,
- relayoutData03 );
-
- TextViewProcessor::WordLayoutInfo wordLayoutInfo03;
-
- wordLayoutInfo03 = *( *textLayoutInfo03.mParagraphsLayoutInfo.begin() ).mWordsLayoutInfo.begin();
-
- // Test MergeWord() asserts if white spaces or new paragraph chars are merged.
- bool assert1 = false;
- bool assert2 = false;
- bool assert3 = false;
- bool assert4 = false;
- bool assert5 = false;
- bool assert6 = false;
-
- try
- {
- MergeWord( wordLayoutInfo01,
- wordLayoutInfo02 );
- }
- catch( Dali::DaliException& e )
- {
- DALI_TEST_PRINT_ASSERT( e );
- DALI_TEST_EQUALS( e.condition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new paragraph characters can't be merged with other words.\"", TEST_LOCATION );
- assert1 = true;
- }
- try
- {
- MergeWord( wordLayoutInfo01,
- wordLayoutInfo03 );
- }
- catch( Dali::DaliException& e )
- {
- DALI_TEST_PRINT_ASSERT( e );
- DALI_TEST_EQUALS( e.condition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new paragraph characters can't be merged with other words.\"", TEST_LOCATION );
- assert2 = true;
- }
- try
- {
- MergeWord( wordLayoutInfo02,
- wordLayoutInfo01 );
- }
- catch( Dali::DaliException& e )
- {
- DALI_TEST_PRINT_ASSERT( e );
- DALI_TEST_EQUALS( e.condition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new paragraph characters can't be merged with other words.\"", TEST_LOCATION );
- assert3 = true;
- }
- try
- {
- MergeWord( wordLayoutInfo02,
- wordLayoutInfo03 );
- }
- catch( Dali::DaliException& e )
- {
- DALI_TEST_PRINT_ASSERT( e );
- DALI_TEST_EQUALS( e.condition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new paragraph characters can't be merged with other words.\"", TEST_LOCATION );
- assert4 = true;
- }
- try
- {
- MergeWord( wordLayoutInfo03,
- wordLayoutInfo01 );
- }
- catch( Dali::DaliException& e )
- {
- DALI_TEST_PRINT_ASSERT( e );
- DALI_TEST_EQUALS( e.condition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new paragraph characters can't be merged with other words.\"", TEST_LOCATION );
- assert5 = true;
- }
- try
- {
- MergeWord( wordLayoutInfo03,
- wordLayoutInfo02 );
- }
- catch( Dali::DaliException& e )
- {
- DALI_TEST_PRINT_ASSERT( e );
- DALI_TEST_EQUALS( e.condition, "!\"TextViewProcessor::MergeWord(). ERROR: White spaces or new paragraph characters can't be merged with other words.\"", TEST_LOCATION );
- assert6 = true;
- }
-
- if( assert1 && assert2 && assert3 && assert4 && assert5 && assert6 )
- {
- tet_result( TET_PASS );
- }
- else
- {
- tet_result( TET_FAIL );
- }
- END_TEST;
-}
-
-int UtcDaliTextViewMergeParagraph01(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewMergeParagraph01 : ");
-
- struct MergeParagraphsTest mergeParagraphsTests[] =
- {
- {
- std::string( "Merge a void first paragraph." ),
- std::string( "" ),
- std::string( "Hello world, this is a whole paragraph" ),
- 2.f,
- std::string( "Hello world, this is a whole paragraph" )
- },
- {
- std::string( "Merge a void last paragraph." ),
- std::string( "Hello world, this is a whole paragraph" ),
- std::string( "" ),
- 0.f,
- std::string( "Hello world, this is a whole paragraph" )
- },
- {
- std::string( "Merge paragraphs: last starting with RTL text and first ending with RTL" ),
- std::string( "Hello world, שלום" ),
- std::string( " עולם, hello world." ),
- 6.f,
- std::string( "Hello world, שלום עולם, hello world." )
- },
- {
- std::string( "Merge paragraphs and don't merge last and first words." ),
- std::string( "Hello world, " ),
- std::string( "שלום עולם, hello world." ),
- 3.f,
- std::string( "Hello world, שלום עולם, hello world." )
- },
- {
- std::string( "Merge paragraphs. Don't merge words" ),
- std::string( "Hello world," ),
- std::string( " this is a whole paragraph" ),
- 0.f,
- std::string( "Hello world, this is a whole paragraph" )
- },
- {
- std::string( "Merge paragraphs. Merge words" ),
- std::string( "Hello world, th" ),
- std::string( "is is a whole paragraph" ),
- 0.f,
- std::string( "Hello world, this is a whole paragraph" )
- },
- };
- const std::size_t numberOfTests( 6u );
-
- for( std::size_t index = 0u; index < numberOfTests; ++index )
- {
- const MergeParagraphsTest& test = mergeParagraphsTests[index];
-
- if( !TestMergeParagraphs( test.description, test.inputFirst, test.inputLast, test.lineHeightOffset, test.result, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewMergeParagraph02(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewMergeParagraph02 : ");
-
- Toolkit::Internal::TextView::RelayoutData relayoutData01;
- Toolkit::Internal::TextView::RelayoutData relayoutData02;
- TextViewProcessor::TextLayoutInfo& textLayoutInfo01( relayoutData01.mTextLayoutInfo );
- TextViewProcessor::TextLayoutInfo& textLayoutInfo02( relayoutData02.mTextLayoutInfo );
-
- std::string text01( "Hello world\n" );
- std::string text02( "hello world" );
- MarkupProcessor::StyledTextArray styledText01;
- MarkupProcessor::StyledTextArray styledText02;
- MarkupProcessor::GetStyledTextArray( text01, styledText01, true );
- MarkupProcessor::GetStyledTextArray( text02, styledText02, true );
-
- TextViewProcessor::CreateTextInfo( styledText01,
- DEFAULT_LAYOUT_PARAMETERS,
- relayoutData01 );
-
- TextViewProcessor::ParagraphLayoutInfo paragraphLayoutInfo01;
-
- paragraphLayoutInfo01 = *textLayoutInfo01.mParagraphsLayoutInfo.begin();
-
- TextViewProcessor::CreateTextInfo( styledText02,
- DEFAULT_LAYOUT_PARAMETERS,
- relayoutData02 );
-
- TextViewProcessor::ParagraphLayoutInfo paragraphLayoutInfo02;
-
- paragraphLayoutInfo02 = *textLayoutInfo02.mParagraphsLayoutInfo.begin();
-
- bool assert1 = false;
-
- try
- {
- MergeParagraph( paragraphLayoutInfo01,
- paragraphLayoutInfo02 );
- }
- catch( Dali::DaliException& e )
- {
- DALI_TEST_PRINT_ASSERT( e );
- DALI_TEST_EQUALS( e.condition, "!\"TextViewProcessor::MergeParagraph(). ERROR: A paragraph can't be merged to another paragraph which finishes with a new paragraph character.\"", TEST_LOCATION );
- assert1 = true;
- }
-
- if( assert1 )
- {
- tet_result( TET_PASS );
- }
- else
- {
- tet_result( TET_FAIL );
- }
- END_TEST;
-}
-
-int UtcDaliTextViewRemoveCharactersFromWord(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewMergeWord02 : ");
-
- struct RemoveCharactersFromWordTest removeCharactersFromWordTests[] =
- {
- {
- std::string( "Delete 0 characters." ),
- std::string( "Hello" ),
- 3,
- 0,
- std::string( "Hello" ),
- },
- {
- std::string( "Delete within the same group of characters. Starting from the beginning" ),
- std::string( "Hello" ),
- 0,
- 3,
- std::string( "lo" ),
- },
- {
- std::string( "Delete within the same group of characters. Somewhere in the middle" ),
- std::string( "Hello" ),
- 2,
- 2,
- std::string( "Heo" ),
- },
- {
- std::string( "Delete within the same group of characters. Starting somewhere in the middle to the end" ),
- std::string( "Hello" ),
- 3,
- 2,
- std::string( "Hel" ),
- },
- {
- std::string( "Delete within the same group of characters. Finish just before a new one." ),
- std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
- 1,
- 2,
- std::string( "<font size='10'>H</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
- },
- {
- std::string( "Delete starting in one group of characters and finishing in a different one. No merge of groups." ),
- std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
- 2,
- 3,
- std::string( "<font size='10'>He</font><font size='20'>Wo</font><font size='30'>rld</font>" ),
- },
- {
- std::string( "Delete within the same group of characters. Starting just after a different one." ),
- std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
- 7,
- 2,
- std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>d</font>" ),
- },
- {
- std::string( "Delete whole group of characters. No merge" ),
- std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
- 3,
- 4,
- std::string( "<font size='10'>Hel</font><font size='30'>rld</font>" ),
- },
- {
- std::string( "Delete whole group of characters and part of the adjacent ones. No merge" ),
- std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='30'>rld</font>" ),
- 2,
- 6,
- std::string( "<font size='10'>He</font><font size='30'>ld</font>" ),
- },
- {
- std::string( "Delete whole group of characters. Merge" ),
- std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='10'>rld</font>" ),
- 3,
- 4,
- std::string( "<font size='10'>Helrld</font>" ),
- },
- {
- std::string( "Delete whole group of characters and part of the adjacent ones. Merge" ),
- std::string( "<font size='10'>Hel</font><font size='20'>loWo</font><font size='10'>rld</font>" ),
- 2,
- 6,
- std::string( "<font size='10'>Held</font>" ),
- },
- };
- const std::size_t numberOfTests( 11u );
-
- for( std::size_t index = 0u; index < numberOfTests; ++index )
- {
- const RemoveCharactersFromWordTest& test = removeCharactersFromWordTests[index];
-
- if( !TestRemoveCharactersFromWord( test.description, test.input, test.position, test.numberOfCharacters, test.result, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
-
-int UtcDaliTextViewRemoveWordsFromParagraph(void)
-{
- // Note: Currently RemoveWordsFromParagraph() function is only used to remove a number of words from the beginning, or
- // from a given index to the end.
-
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextViewRemoveWordsFromParagraph : ");
- struct RemoveWordsFromParagraphTest removeWordsFromParagraphTest[] =
- {
- {
- std::string( "Delete 0 words." ),
- std::string( "Hello hello, שלום עולם hello hello" ),
- 0,
- 0,
- 2.f,
- std::string( "Hello hello, שלום עולם hello hello" ),
- },
- {
- std::string( "Delete from the middle to the end." ),
- std::string( "Hello hello, שלום עולם hello hello" ),
- 4,
- 7,
- 0.f,
- std::string( "Hello hello, " ),
- },
- {
- std::string( "Delete from the beginning to the middle." ),
- std::string( "Hello hello, שלום עולם hello hello" ),
- 0,
- 8,
- 6.f,
- std::string( "hello hello" ),
- },
- };
- const std::size_t numberOfTests( 3u );
-
- for( std::size_t index = 0u; index < numberOfTests; ++index )
- {
- const RemoveWordsFromParagraphTest& test = removeWordsFromParagraphTest[index];
-
- if( !TestRemoveWordsFromParagraph( test.description, test.input, test.wordIndex, test.numberOfWords, test.lineHeightOffset, test.result, TEST_LOCATION ) )
- {
- tet_result( TET_FAIL );
- }
- }
-
- tet_result( TET_PASS );
- END_TEST;
-}
utc-Dali-ItemLayout.cpp
utc-Dali-ItemView.cpp
utc-Dali-KeyboardFocusManager.cpp
- utc-Dali-MarkupProcessor.cpp
utc-Dali-MaskEffect.cpp
utc-Dali-NinePatchMaskEffect.cpp
utc-Dali-Popup.cpp
utc-Dali-StyleManager.cpp
utc-Dali-SuperBlurView.cpp
utc-Dali-SwirlEffect.cpp
- utc-Dali-TextInput.cpp
- utc-Dali-TextView.cpp
)
# Append list of test harness files (Won't get parsed for test cases)
void DALI_TEST_EQUALS( const char* str1, const std::string &str2, const char* location);
/**
- * Test whether two UTF32 strings are equal.
- * @param[in] str1 The first string
- * @param[in] str2 The second string
- * @param[in] location The TEST_LOCATION macro should be used here
- */
-template<>
-inline void DALI_TEST_EQUALS<const Integration::TextArray&>( const Integration::TextArray& str1, const Integration::TextArray& str2, const char* location)
-{
- if( !std::equal( str1.Begin(), str1.End(), str2.Begin() ) )
- {
- fprintf(stderr, "%s, checking '", location);
-
- for( unsigned int i = 0; i < str1.Count(); ++i )
- {
- fprintf(stderr, "%c", str1[i]);
- }
-
- fprintf(stderr, "' == '");
-
- for( unsigned int i = 0; i < str2.Count(); ++i )
- {
- fprintf(stderr, "%c", str2[i]);
- }
-
- fprintf(stderr, "'\n");
-
- tet_result(TET_FAIL);
- }
- else
- {
- tet_result(TET_PASS);
- }
-}
-
-/**
* Test whether one unsigned integer value is greater than another.
* Test succeeds if value1 > value2
* @param[in] value1 The first value
mTrace.PushCall("GetClosestImageSize", "");
}
-
/**
* @copydoc PlatformAbstraction::LoadResource()
*/
void TestPlatformAbstraction::LoadResource(const Integration::ResourceRequest& request)
{
std::ostringstream out;
- out << "Type:";
- if( request.GetType()->id == Integration::ResourceText )
- {
- out << "Text";
- }
- else
- {
- out << request.GetType()->id;
- }
- out << ", Path: " << request.GetPath() << std::endl ;
+ out << "Type:" << request.GetType()->id << ", Path: " << request.GetPath() << std::endl;
mTrace.PushCall("LoadResource", out.str());
if(mRequest != NULL)
}
/**
- * @copydoc PlatformAbstraction::GetDefaultFontFamily()
- */
-const std::string& TestPlatformAbstraction::GetDefaultFontFamily() const
-{
- mTrace.PushCall("GetDefaultFontFamily", "");
- return mGetDefaultFontFamilyResult;
-}
-
-/**
- * @copydoc PlatformAbstraction::GetDefaultFontSize()
- */
-float TestPlatformAbstraction::GetDefaultFontSize() const
-{
- mTrace.PushCall("GetDefaultFontSize", "");
- return mGetDefaultFontSizeResult;
-}
-
-PixelSize TestPlatformAbstraction::GetFontLineHeightFromCapsHeight(const std::string& fontFamily, const std::string& fontStyle, CapsHeight capsHeight) const
-{
- mTrace.PushCall("GetFontLineHeightFromCapsHeight", "");
- // LineHeight will be bigger than CapsHeight, so return capsHeight + 1
- return PixelSize(capsHeight + 1);
-}
-
-/**
- * @copydoc PlatformAbstraction::GetGlyphData()
- */
-
-Integration::GlyphSet* TestPlatformAbstraction::GetGlyphData ( const Integration::TextResourceType& textRequest,
- const std::string& fontFamily,
- bool getBitmap) const
-{
- if( getBitmap )
- {
- mTrace.PushCall("GetGlyphData", "getBitmap:true");
- }
- else
- {
- mTrace.PushCall("GetGlyphData", "getBitmap:false");
- }
-
- // It creates fake metrics for the received characters.
-
- Integration::GlyphSet* set = new Dali::Integration::GlyphSet();
- Integration::BitmapPtr bitmapData;
-
- std::set<uint32_t> characters;
-
- for( Integration::TextResourceType::CharacterList::const_iterator it = textRequest.mCharacterList.begin(), endIt = textRequest.mCharacterList.end(); it != endIt; ++it )
- {
- if( characters.find( it->character ) == characters.end() )
- {
- characters.insert( it->character );
- Integration::GlyphMetrics character = {it->character, Integration::GlyphMetrics::LOW_QUALITY, 10.0f, 10.0f, 9.0f, 1.0f, 10.0f, it->xPosition, it->yPosition };
-
- if( getBitmap )
- {
- bitmapData = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD);
- bitmapData->GetPackedPixelsProfile()->ReserveBuffer(Pixel::A8, 64, 64);
- PixelBuffer* pixelBuffer = bitmapData->GetBuffer();
- memset( pixelBuffer, it->character, 64*64 );
- }
-
- set->AddCharacter(bitmapData, character);
- }
- }
-
- set->mLineHeight = 10.0f;
- set->mAscender = 9.0f;
- set->mUnitsPerEM = 2048.0f/64.0f;
- set->SetAtlasResourceId( textRequest.mTextureAtlasId );
- set->mFontHash = textRequest.mFontHash;
-
- return set;
-}
-
-/**
- * @copydoc PlatformAbstraction::GetCachedGlyphData()
- */
-
-Integration::GlyphSet* TestPlatformAbstraction::GetCachedGlyphData( const Integration::TextResourceType& textRequest,
- const std::string& fontFamily ) const
-{
- mTrace.PushCall("GetCachedGlyphData", "");
-
- // It creates fake metrics and bitmap for received numeric characters '0' through '9'.
- Integration::GlyphSet* set = new Dali::Integration::GlyphSet();
- Integration::BitmapPtr bitmapData;
-
- std::set<uint32_t> characters;
-
- for( Integration::TextResourceType::CharacterList::const_iterator it = textRequest.mCharacterList.begin(), endIt = textRequest.mCharacterList.end(); it != endIt; ++it )
- {
- if( it->character >= '0' && it->character <= '9' && characters.find( it->character ) == characters.end() )
- {
- characters.insert( it->character );
- Integration::GlyphMetrics character = {it->character, Integration::GlyphMetrics::HIGH_QUALITY, 10.0f, 10.0f, 9.0f, 1.0f, 10.0f, it->xPosition, it->yPosition };
-
- bitmapData = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD);
- bitmapData->GetPackedPixelsProfile()->ReserveBuffer(Pixel::A8, 64, 64);
- PixelBuffer* pixelBuffer = bitmapData->GetBuffer();
- memset( pixelBuffer, it->character, 64*64 );
- set->AddCharacter(bitmapData, character);
- }
- }
-
- set->mLineHeight = 10.0f;
- set->mAscender = 9.0f;
- set->mUnitsPerEM = 2048.0f/64.0f;
- set->SetAtlasResourceId( textRequest.mTextureAtlasId );
- set->mFontHash = textRequest.mFontHash;
-
- return set;
-}
-
-
-/**
- * @copydoc PlatformAbstraction::GetGlobalMetrics()
- */
-void TestPlatformAbstraction::GetGlobalMetrics( const std::string& fontFamily,
- const std::string& fontStyle,
- Integration::GlobalMetrics& globalMetrics ) const
-{
- globalMetrics.lineHeight = 10.0f;
- globalMetrics.ascender = 9.0f;
- globalMetrics.unitsPerEM = 2048.0f/64.0f;
- globalMetrics.underlineThickness = 2.f;
- globalMetrics.underlinePosition = 1.f;
-}
-
-/**
- * @copydoc PlatformAbstraction::GetFontPath()
- */
-std::string TestPlatformAbstraction::GetFontPath(const std::string& family, bool bold, bool italic) const
-{
- mTrace.PushCall("GetFontPath", "");
- return mGetFontPathResult;
-
- // Do nothing with arguments
-}
-
-/**
* @copydoc PlatformAbstraction::SetDpi()
*/
void TestPlatformAbstraction::SetDpi (unsigned int dpiHorizontal, unsigned int dpiVertical)
}
/**
- * @copydoc PlatformAbstraction::GetFontFamilyForChars()
- */
-const std::string& TestPlatformAbstraction::GetFontFamilyForChars(const Integration::TextArray& charsRequested) const
-{
- mTrace.PushCall("GetFontFamilyForChars", "");
- return mGetDefaultFontFamilyResult;
-}
-
-/**
- * @copydoc PlatformAbstraction::AllGlyphsSupported()
- */
-bool TestPlatformAbstraction::AllGlyphsSupported(const std::string& name, const std::string& fontStyle, const Integration::TextArray& text) const
-{
- mTrace.PushCall("AllGlyphsSupported", "");
- return true;
-}
-
-/**
- * @copydoc PlatformAbstraction::ValidateFontFamilyName()
- */
-bool TestPlatformAbstraction::ValidateFontFamilyName(const std::string& fontFamily, const std::string& fontStyle, bool& isDefaultSystemFont, std::string& closestMatch, std::string& closestStyleMatch) const
-{
- mTrace.PushCall("ValidateFontFamilyName", "");
- return true;
-}
-
-/**
- * @copydoc PlatformAbstraction::GetFontList()
- */
-void TestPlatformAbstraction::GetFontList( PlatformAbstraction::FontListMode mode, std::vector<std::string>& fonstList ) const
-{
- mFontListMode = mode;
- mTrace.PushCall("ValidateGetFontList", "");
-}
-
-/**
* @copydoc PlatformAbstraction::LoadFile()
*/
bool TestPlatformAbstraction::LoadFile( const std::string& filename, std::vector< unsigned char >& buffer ) const
mTrace.PushCall("JoinLoaderThreads", "");
}
-void TestPlatformAbstraction::UpdateDefaultsFromDevice()
-{
- mTrace.PushCall("UpdateDefaultsFromDevice", "");
- mGetDefaultFontFamilyResult+=1.0f;
-}
-
Integration::DynamicsFactory* TestPlatformAbstraction::GetDynamicsFactory()
{
mTrace.PushCall("GetDynamicsFactory", "");
return NULL;
}
-bool TestPlatformAbstraction::ReadGlobalMetricsFromCache( const std::string& fontFamily,
- const std::string& fontStyle,
- Integration::GlobalMetrics& globalMetrics )
-{
- mTrace.PushCall("ReadGlobalMetricsFromCacheFile", "");
- globalMetrics = mReadGlobalMetrics; // Want to copy contents...
- return mReadGlobalMetricsResult; // Default false (will be set to true on subsequent write)
-}
-
-void TestPlatformAbstraction::WriteGlobalMetricsToCache( const std::string& fontFamily,
- const std::string& fontStyle,
- const Integration::GlobalMetrics& globalMetrics )
-{
- // Copy so next read uses written values. TODO: Could add method
- // to turn this behaviour off for more extensive testing.
- mReadGlobalMetrics = globalMetrics;
- mReadGlobalMetricsResult = true;
-
- mTrace.PushCall("WriteGlobalMetricsToCacheFile", "");
-}
-
-bool TestPlatformAbstraction::ReadMetricsFromCache( const std::string& fontFamily,
- const std::string& fontStyle,
- std::vector<Integration::GlyphMetrics>& glyphMetricsContainer )
-{
- mTrace.PushCall("ReadMetricsFromCacheFile", "");
- glyphMetricsContainer = mReadMetrics;
- return mReadMetricsResult; // Default false (will be set to true on subsequent write)
-}
-
-void TestPlatformAbstraction::WriteMetricsToCache( const std::string& fontFamily,
- const std::string& fontStyle,
- const Integration::GlyphSet& glyphSet )
-{
- // Copy so next read uses written values. TODO: Could add method
- // to turn this behaviour off for more extensive testing.
- const Integration::GlyphSet::CharacterList& charList = glyphSet.GetCharacterList();
- mReadMetrics.clear();
- for(std::size_t i=0, end=charList.size(); i<end; ++i)
- {
- mReadMetrics.push_back(charList[i].second);
- }
- mReadMetricsResult = true;
-
- mTrace.PushCall("WriteMetricsToCacheFile", "");
-}
-
-
-void TestPlatformAbstraction::GetFileNamesFromDirectory( const std::string& directoryName,
- std::vector<std::string>& fileNames )
-{
- fileNames.push_back( std::string( "u1f004.png" ) );
- fileNames.push_back( std::string( "u1f0cf.png" ) );
- fileNames.push_back( std::string( "u1f170.png" ) );
- fileNames.push_back( std::string( "u1f601.png" ) );
-}
-
-
-Integration::BitmapPtr TestPlatformAbstraction::GetGlyphImage( const std::string& fontFamily, const std::string& fontStyle, float fontSize, uint32_t character ) const
-{
- Integration::BitmapPtr image = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
- image->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 1, 1 );
-
- mTrace.PushCall("GetGlyphImage", "");
-
- return image;
-}
-
-
/** Call this every test */
void TestPlatformAbstraction::Initialize()
{
mTrace.Reset();
mTrace.Enable(true);
memset(&mResources, 0, sizeof(Resources));
- memset(&mReadGlobalMetrics, 0, sizeof(Integration::GlobalMetrics));
mSeconds=0;
mMicroSeconds=0;
mIsLoadingResult=false;
- mGetDefaultFontFamilyResult = "HelveticaNeue";
- mGetDefaultFontSizeResult=12.0f;
- mGetFontPathResult="helvetica-12";
- mReadMetricsResult=false;
- mReadGlobalMetricsResult=false;
if(mRequest)
{
case CancelLoadFunc: return mTrace.FindMethod("CancelLoad");
case GetResourcesFunc: return mTrace.FindMethod("GetResources");
case IsLoadingFunc: return mTrace.FindMethod("IsLoading");
- case GetDefaultFontFamilyFunc: return mTrace.FindMethod("GetDefaultFontFamily");
- case GetDefaultFontSizeFunc: return mTrace.FindMethod("GetDefaultFontSize");
- case GetFontLineHeightFromCapsHeightFunc: return mTrace.FindMethod("GetFontLineHeightFromCapsHeight");
- case GetGlyphDataFunc: return mTrace.FindMethod("GetGlyphData");
- case GetCachedGlyphDataFunc: return mTrace.FindMethod("GetCachedGlyphData");
- case GetFontPathFunc: return mTrace.FindMethod("GetFontPath");
case SetDpiFunc: return mTrace.FindMethod("SetDpi");
case JoinLoaderThreadsFunc: return mTrace.FindMethod("JoinLoaderThreads");
- case GetFontFamilyForCharsFunc: return mTrace.FindMethod("GetFontFamilyForChars");
- case AllGlyphsSupportedFunc: return mTrace.FindMethod("AllGlyphsSupported");
- case ValidateFontFamilyNameFunc: return mTrace.FindMethod("ValidateFontFamilyName");
- case UpdateDefaultsFromDeviceFunc: return mTrace.FindMethod("UpdateDefaultsFromDevice");
case GetDynamicsFactoryFunc: return mTrace.FindMethod("GetDynamicsFactory");
- case ValidateGetFontListFunc: return mTrace.FindMethod("ValidateGetFontList");
- case ReadGlobalMetricsFromCacheFileFunc: return mTrace.FindMethod("ReadGlobalMetricsFromCacheFile");
- case WriteGlobalMetricsToCacheFileFunc: return mTrace.FindMethod("WriteGlobalMetricsToCacheFile");
- case ReadMetricsFromCacheFileFunc: return mTrace.FindMethod("ReadMetricsFromCacheFile");
- case WriteMetricsToCacheFileFunc: return mTrace.FindMethod("WriteMetricsToCacheFile");
}
return false;
}
mIsLoadingResult = result;
}
-void TestPlatformAbstraction::SetGetDefaultFontFamilyResult(std::string result)
-{
- mGetDefaultFontFamilyResult = result;
-}
-
-void TestPlatformAbstraction::SetGetDefaultFontSizeResult(float result)
-{
- mGetDefaultFontSizeResult = result;
-}
-
-void TestPlatformAbstraction::SetGetFontPathResult(std::string& result)
-{
- mGetFontPathResult = result;
-}
-
void TestPlatformAbstraction::ClearReadyResources()
{
memset(&mResources, 0, sizeof(Resources));
mSaveFileResult = result;
}
-Integration::PlatformAbstraction::FontListMode TestPlatformAbstraction::GetLastFontListMode( )
-{
- return mFontListMode;
-}
-
-void TestPlatformAbstraction::SetReadGlobalMetricsResult( bool success, Integration::GlobalMetrics& globalMetrics )
-{
- mReadGlobalMetricsResult = success;
- mReadGlobalMetrics = globalMetrics;
-}
-
-void TestPlatformAbstraction::SetReadMetricsResult( bool success, std::vector<Integration::GlyphMetrics>& glyphMetricsContainer )
-{
- mReadMetricsResult = success;
- mReadMetrics = glyphMetricsContainer; // copy
-}
-
} // namespace Dali
#include <dali/public-api/common/set-wrapper.h>
#include <dali/integration-api/platform-abstraction.h>
-#include <dali/integration-api/glyph-set.h>
#include "test-trace-call-stack.h"
virtual bool IsLoading();
/**
- * @copydoc PlatformAbstraction::GetDefaultFontFamily()
- */
- virtual const std::string& GetDefaultFontFamily() const;
-
- /**
- * @copydoc PlatformAbstraction::GetDefaultFontSize()
- */
- virtual float GetDefaultFontSize() const;
-
- /**
- * @copydoc PlatformAbstraction::GetFontLineHeightFromCapsHeight()
- */
- virtual Dali::PixelSize GetFontLineHeightFromCapsHeight(const std::string& fontFamily, const std::string& fontStyle, CapsHeight capsHeight) const;
-
- /**
- * @copydoc PlatformAbstraction::GetGlyphData()
- */
- virtual Integration::GlyphSet* GetGlyphData ( const Integration::TextResourceType& textRequest,
- const std::string& fontFamily,
- bool getBitmap) const;
-
- /**
- * @copydoc PlatformAbstraction::GetCachedGlyphData()
- */
- virtual Integration::GlyphSet* GetCachedGlyphData( const Integration::TextResourceType& textRequest,
- const std::string& fontFamily ) const;
-
-
- /**
- * @copydoc PlatformAbstraction::GetGlobalMetrics()
- */
- virtual void GetGlobalMetrics( const std::string& fontFamily,
- const std::string& fontStyle,
- Integration::GlobalMetrics& globalMetrics ) const;
-
- /**
- * @copydoc PlatformAbstraction::GetFontPath()
- */
- virtual std::string GetFontPath(const std::string& family, bool bold, bool italic) const;
-
- /**
* @copydoc PlatformAbstraction::SetDpi()
*/
virtual void SetDpi (unsigned int dpiHorizontal, unsigned int dpiVertical);
-
- /**
- * @copydoc PlatformAbstraction::GetFontFamilyForChars()
- */
- virtual const std::string& GetFontFamilyForChars(const Integration::TextArray& charsRequested) const;
-
- /**
- * @copydoc PlatformAbstraction::AllGlyphsSupported()
- */
- virtual bool AllGlyphsSupported(const std::string& name, const std::string& fontStyle, const Integration::TextArray& text) const;
-
- /**
- * @copydoc PlatformAbstraction::ValidateFontFamilyName()
- */
- virtual bool ValidateFontFamilyName(const std::string& fontFamily, const std::string& fontStyle, bool& isDefaultSystemFont, std::string& closestMatch, std::string& closestStyleMatch) const;
-
- /**
- * @copydoc PlatformAbstraction::GetFontList()
- */
- virtual void GetFontList( PlatformAbstraction::FontListMode mode, std::vector<std::string>& fontList ) const;
-
/**
* @copydoc PlatformAbstraction::LoadFile()
*/
virtual void JoinLoaderThreads();
- virtual void UpdateDefaultsFromDevice();
-
virtual Integration::DynamicsFactory* GetDynamicsFactory();
- virtual bool ReadGlobalMetricsFromCache( const std::string& fontFamily,
- const std::string& fontStyle,
- Integration::GlobalMetrics& globalMetrics );
-
- virtual void WriteGlobalMetricsToCache( const std::string& fontFamily,
- const std::string& fontStyle,
- const Integration::GlobalMetrics& globalMetrics );
-
- virtual bool ReadMetricsFromCache( const std::string& fontFamily,
- const std::string& fontStyle,
- std::vector<Integration::GlyphMetrics>& glyphMetricsContainer );
- virtual void WriteMetricsToCache( const std::string& fontFamily,
- const std::string& fontStyle,
- const Integration::GlyphSet& glyphSet );
-
-
- virtual void GetFileNamesFromDirectory( const std::string& directoryName,
- std::vector<std::string>& fileNames );
-
- virtual Integration::BitmapPtr GetGlyphImage( const std::string& fontFamily, const std::string& fontStyle, float fontSize, uint32_t character ) const;
-
public: // TEST FUNCTIONS
// Enumeration of Platform Abstraction methods
CancelLoadFunc,
GetResourcesFunc,
IsLoadingFunc,
- GetDefaultFontFamilyFunc,
- GetDefaultFontSizeFunc,
- GetFontLineHeightFromCapsHeightFunc,
- GetGlyphDataFunc,
- GetCachedGlyphDataFunc,
SetDpiFunc,
- GetFontPathFunc,
JoinLoaderThreadsFunc,
- GetFontFamilyForCharsFunc,
- AllGlyphsSupportedFunc,
- ValidateFontFamilyNameFunc,
- UpdateDefaultsFromDeviceFunc,
GetDynamicsFactoryFunc,
- ValidateGetFontListFunc,
- ReadGlobalMetricsFromCacheFileFunc,
- WriteGlobalMetricsToCacheFileFunc,
- ReadMetricsFromCacheFileFunc,
- WriteMetricsToCacheFileFunc,
} TestFuncEnum;
/** Call this every test */
void SetSaveFileResult( bool result );
- PlatformAbstraction::FontListMode GetLastFontListMode( );
-
- void SetReadGlobalMetricsResult( bool success, Integration::GlobalMetrics& globalMetrics );
-
- void SetReadMetricsResult( bool success, std::vector<Integration::GlyphMetrics>& glyphMetricsContainer );
-
-
private:
mutable TraceCallStack mTrace;
size_t mSeconds;
size_t mMicroSeconds;
bool mIsLoadingResult;
- std::string mGetDefaultFontFamilyResult;
- float mGetDefaultFontSizeResult;
- std::string mGetFontPathResult;
Resources mResources;
Integration::ResourceRequest* mRequest;
Vector2 mSize;
Vector2 mClosestSize;
- bool mReadGlobalMetricsResult;
- bool mReadMetricsResult;
- Integration::GlobalMetrics mReadGlobalMetrics;
- std::vector<Integration::GlyphMetrics> mReadMetrics;
LoadFileResult mLoadFileResult;
bool mSaveFileResult;
- mutable FontListMode mFontListMode;
};
} // Dali
namespace
{
-//
-// Note: To avoid escaping double quotes single quotes are used and then replaced
-// before parsing. JSON uses double quotes
-//
-
- std::string JSON_TEXT_ACTOR("\
-{ \
- 'templates': \
- { \
- 'basic-text': \
- { \
- 'type':'TextActor', \
- 'text':'Template Hello', \
- 'size': [150,170,1], \
- 'position':[-10,10,0] \
- } \
- }, \
- 'styles': \
- { \
- 'basic-text': \
- { \
- 'text':'Hello', \
- 'font':'', \
- 'parent-origin':[0.0,0.0,0], \
- 'anchor-point' :[0.5,0.5,0], \
- 'size': [150,170,1], \
- 'position':[-10,10,0] \
- } \
- }, \
- 'animations': \
- { \
- 'rotate': \
- { \
- 'duration': 10, \
- 'properties': \
- [ \
- { \
- 'actor':'text', \
- 'property':'rotation', \
- 'value':[0, 3, 0, 0], \
- 'alpha-function': 'EASE_IN_OUT', \
- 'time-period': {'delay': 0, 'duration': 3 } \
- } \
- ] \
- } \
- }, \
- 'stage': \
- [ \
- { \
- 'name':'text', \
- 'type':'basic-text', \
- 'text':'Hello' \
- }, \
- { \
- 'name':'text2', \
- 'type':'basic-text', \
- 'text':'Hello', \
- 'signals': \
- [ \
- { 'name': 'on-stage', 'action':'set', 'actor':'text2', 'property':'text', 'value':'Jaylo' } \
- ] \
- } \
- ], \
- 'other': \
- [ \
- { \
- 'name':'other-text', \
- 'type':'basic-text', \
- 'text':'Hello' \
- } \
- ] \
-} \
-");
-
-
- std::string JSON_CORE_ACTOR_TREE("\
-{ \
- 'templates': \
- { \
- 'my-camera': { \
- 'type':'CameraActor', \
- 'camera-type':'FreeLook', \
- 'field-of-view': 0.125, \
- 'aspect-ratio':5.0, \
- 'near-plane-distance': 100, \
- 'far-plane-distance': 200 \
- }, \
- 'basic-text': { \
- 'type':'TextActor', \
- 'text':'Hello', \
- 'font':'Freesans', \
- 'smooth-edge':0.2, \
- 'position': [-10.0, 10.0, -1000.0], \
- 'size': [300.0, 250.0, 0.0] \
- } \
- }, \
- 'styles': \
- { \
- 'theme2-text': { \
- 'type':'TextActor', \
- 'text':'Hello', \
- 'font':'Freesans', \
- 'smooth-edge':0.8 \
- } \
- }, \
- 'stage': \
- [ \
- {'name':'txt1', \
- 'type':'TextActor', \
- 'text':'Hello World', \
- 'font':'freesans', \
- 'parent-origin':'CENTER', \
- 'actors': \
- [ \
- { 'type':'basic-text', 'text':'Hello', 'position-y':50 }, \
- { 'type':'basic-text', 'text':'Hello', 'position-y':100 }, \
- { 'type':'basic-text', 'text':'Hello', 'position-y':150 }, \
- { 'type':'basic-text', 'text':'Hello', 'position-y':200 }, \
- { 'type':'basic-text', 'text':'Hello', 'position-y':250 } \
- ] \
- } \
- ] \
-} \
-");
-
std::string ReplaceQuotes(const std::string &in_s)
{
test_return_value = TET_PASS;
}
-int UtcDaliBuilderTextActorCreate(void)
-{
- ToolkitTestApplication application;
- Stage stage = Stage::GetCurrent();
-
- tet_infoline(" UtcDaliBuilderTextActorCreate");
-
- Builder builder = Builder::New();
-
- builder.LoadFromString(ReplaceQuotes(JSON_TEXT_ACTOR));
-
- TextActor actor( TextActor::DownCast( builder.Create("basic-text") ) );
-
- DALI_TEST_CHECK( actor );
-
- stage.GetRootLayer().Add( actor );
-
- application.SendNotification();
- application.Render();
-
- Vector3 v;
-
- v = actor.GetCurrentPosition();
- DALI_TEST_CHECK(v.x == -10.0);
- DALI_TEST_CHECK(v.y == 10.0);
- DALI_TEST_CHECK(v.z == 0.0);
-
- v = actor.GetCurrentSize();
- DALI_TEST_CHECK(v.x == 150.0);
- DALI_TEST_CHECK(v.y == 170.0);
- DALI_TEST_CHECK(v.z == 1.0);
-
- DALI_TEST_CHECK(actor.GetText() == "Template Hello");
-
- actor = TextActor::DownCast( builder.Create("*(&^") );
- DALI_TEST_CHECK(!actor);
-
- END_TEST;
-}
-
-int UtcDaliBuilderTextActorCreateAnimation(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliBuilderTextActorCreateAnimation");
-
- Builder builder = Builder::New();
-
- builder.LoadFromString(ReplaceQuotes(JSON_TEXT_ACTOR));
-
- builder.AddActors( Stage::GetCurrent().GetRootLayer() );
-
- Animation anim = builder.CreateAnimation("rotate");
- DALI_TEST_CHECK( anim );
-
- DALI_TEST_CHECK( 10.0f == anim.GetDuration() );
-
- END_TEST;
-}
-
-int UtcDaliBuilderTextActorApplyFromStyle(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliBuilderTextActorApplyFromStyle");
-
- Builder builder = Builder::New();
-
- builder.LoadFromString(ReplaceQuotes(JSON_TEXT_ACTOR));
-
- TextActor actor = TextActor::New("a");
-
- builder.ApplyStyle("basic-text", actor);
-
- DALI_TEST_CHECK( actor );
-
- Stage::GetCurrent().GetRootLayer().Add( actor );
-
- application.SendNotification();
- application.Render();
-
- Vector3 v;
-
- v = actor.GetCurrentPosition();
- DALI_TEST_CHECK(v.x == -10.0);
- DALI_TEST_CHECK(v.y == 10.0);
- DALI_TEST_CHECK(v.z == 0.0);
-
- v = actor.GetCurrentSize();
- DALI_TEST_CHECK(v.x == 150.0);
- DALI_TEST_CHECK(v.y == 170.0);
- DALI_TEST_CHECK(v.z == 1.0);
-
- DALI_TEST_CHECK(actor.GetText() == "Hello");
-
- END_TEST;
-}
-
-int UtcDaliBuilderAddActors(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliBuilderAddActors");
-
- Builder builder = Builder::New();
-
- builder.LoadFromString(ReplaceQuotes(JSON_TEXT_ACTOR));
-
- builder.AddActors( Stage::GetCurrent().GetRootLayer() );
-
- application.SendNotification();
- application.Render();
-
- TextActor actor = TextActor::DownCast( Stage::GetCurrent().GetRootLayer().FindChildByName("text") );
-
- DALI_TEST_CHECK( actor );
- DALI_TEST_CHECK(actor.GetText() == "Hello");
-
- END_TEST;
-}
-
-int UtcDaliBuilderAddActorsOther(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliBuilderAddActorsOther");
-
- Actor rootActor = Stage::GetCurrent().GetRootLayer();
-
- Builder builder = Builder::New();
-
- builder.LoadFromString(ReplaceQuotes(JSON_TEXT_ACTOR));
-
- builder.AddActors( "other", rootActor );
-
- application.SendNotification();
- application.Render();
-
- TextActor actor = TextActor::DownCast( Stage::GetCurrent().GetRootLayer().FindChildByName("other-text") );
-
- DALI_TEST_CHECK( actor );
- DALI_TEST_CHECK(actor.GetText() == "Hello");
-
- END_TEST;
-}
-
-
-int UtcDaliBuilderStyles(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliBuilderStyles");
-
- Builder builder = Builder::New();
-
- builder.LoadFromString(ReplaceQuotes(JSON_CORE_ACTOR_TREE));
-
- BaseHandle handle = builder.Create("my-camera");
- CameraActor camera = CameraActor::DownCast(handle);
-
- DALI_TEST_CHECK(camera);
-
- Property::Value v;
-
- v = camera.GetProperty( camera.GetPropertyIndex("field-of-view") );
- DALI_TEST_CHECK( 0.125f == v.Get<float>() );
-
- v = camera.GetProperty( camera.GetPropertyIndex("aspect-ratio") );
- DALI_TEST_CHECK( 5.0f == v.Get<float>() );
-
- handle = builder.Create("basic-text");
- TextActor textActor = TextActor::DownCast(handle);
-
- v = textActor.GetProperty( textActor.GetPropertyIndex("smooth-edge") );
-
- DALI_TEST_CHECK( 0.2f == v.Get<float>() );
-
- // test ApplyStyle another
- builder.ApplyStyle("theme2-text", textActor);
-
- v = textActor.GetProperty( textActor.GetPropertyIndex("smooth-edge") );
- DALI_TEST_CHECK( 0.8f == v.Get<float>() );
-
- END_TEST;
-}
-
-int UtcDaliBuilderSetProperty(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliBuilderSetProperty");
-
- Builder builder = Builder::New();
-
- builder.LoadFromString(ReplaceQuotes(JSON_TEXT_ACTOR));
-
- builder.AddActors( Stage::GetCurrent().GetRootLayer() );
-
- application.SendNotification();
- application.Render();
-
- TextActor actor = TextActor::DownCast( Stage::GetCurrent().GetRootLayer().FindChildByName("text2") );
-
- DALI_TEST_CHECK( actor );
- DALI_TEST_CHECK( actor.GetText() == "Jaylo" );
-
- END_TEST;
-}
-
-int UtcDaliBuilderCreateFromJson(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliBuilderCreateFromJson");
-
- Builder builder = Builder::New();
-
- TextActor actor = TextActor::DownCast( builder.CreateFromJson("foobar") );
-
- DALI_TEST_CHECK( !actor );
-
- actor = TextActor::DownCast(
- builder.CreateFromJson(
- ReplaceQuotes("{'type':'TextActor','text':'Hi'}") ) );
-
- DALI_TEST_CHECK( actor );
-
- DALI_TEST_CHECK( actor.GetText() == "Hi" );
-
- END_TEST;
-}
-
-int UtcDaliBuilderApplyFromJson(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliBuilderApplyFromJson");
-
- Builder builder = Builder::New();
-
- TextActor actor = TextActor::DownCast(
- builder.CreateFromJson(
- ReplaceQuotes("{'type':'TextActor','text':'Hi'}") ) );
-
- DALI_TEST_CHECK( actor );
-
- DALI_TEST_CHECK( actor.GetText() == "Hi" );
-
- DALI_TEST_CHECK( !builder.ApplyFromJson(actor, ReplaceQuotes("foobar") ) );
-
- builder.ApplyFromJson(actor, ReplaceQuotes("{'text':'low'}") );
-
- DALI_TEST_CHECK( actor.GetText() == "low" );
-
- END_TEST;
-}
-
int UtcDaliBuilderQuitSignal(void)
{
ToolkitTestApplication application;
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-#include <stdlib.h>
-
-// Need to override adaptor classes for toolkit test harness, so include
-// test harness headers before dali headers.
-#include <dali-toolkit-test-suite-utils.h>
-
-#include <dali.h>
-#include <dali-toolkit/dali-toolkit.h>
-
-using namespace Dali;
-
-void utc_dali_toolkit_markup_processor_startup(void)
-{
- test_return_value = TET_UNDEF;
-}
-
-void utc_dali_toolkit_markup_processor_cleanup(void)
-{
- test_return_value = TET_PASS;
-}
-
-namespace
-{
-
-struct MarkupStringTest
-{
- std::string input;
- std::string expectedResult;
-};
-
-bool TestMarkupString( const std::string& input, const std::string& expectedResult, std::string& result )
-{
- Toolkit::MarkupProcessor::StyledTextArray styledTextArray;
-
- GetStyledTextArray( input, styledTextArray, true );
- GetMarkupString( styledTextArray, result );
-
- return expectedResult == result;
-}
-
-} // namespace
-
-
-// Positive test case for a method
-int UtcDaliMarkupProcessor(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliMarkupProcessor ");
-
- const std::string text1( "Text" );
- const std::string text2( "< font face ='FreeSerif' color= 'green' >t< / font >" );
- const std::string text3( "< font face = 'FreeSerif' size= '16' style = 'Bold' color='red'>< i><u >Styled< / u> Text< /i >< / font >< br / >" );
- const std::string text4( "<font face='FreeSerif' size='14' color='0xaadd8744'><b><u>Styled</u> Te<font size='20'>x</font>t</b></font>< br/>" );
- const std::string text5( "< shadow color = 'blue' paramx = '1' paramy = '0.75' >Shadow< / shadow><br />" );
- const std::string text6( "<smooth param= '0.75' >< glow color = 'red' param = '0.1' >Glow</glow></smooth>< br />" );
- const std::string text7( "<font color='green''>< outline color = 'red' paramx = '0.7' paramy = '0.7' >Outline< / outline >< /font >< br / >" );
- const std::string text8( "<smooth param='0.75'>Smooth</smooth>< br / >" );
- const std::string text9( "\\<" );
- const std::string text10( "\\>" );
-
- char crlf[2];
- crlf[0] = 0x0D;
- crlf[1] = 0x0A;
- const std::string text11( crlf, 2 );
-
- const std::string result1( text1 );
- const std::string result2( "<font face='FreeSerif' color='green'>t</font>" );
- const std::string result3( "<font face='FreeSerif' style='Bold' size='16' color='red'><i><u>Styled</u></i></font><font face='FreeSerif' style='Bold' size='16' color='red'><i> Text</i></font><br />" );
- const std::string result4( "<font face='FreeSerif' size='14' color='0xaadd8744'><b><u>Styled</u></b></font><font face='FreeSerif' size='14' color='0xaadd8744'><b> Te</b></font><font face='FreeSerif' size='20' color='0xaadd8744'><b>x</b></font><font face='FreeSerif' size='14' color='0xaadd8744'><b>t</b></font><br />" );
- const std::string result5( "<shadow color='blue' paramx='1' paramy='0.75'>Shadow</shadow><br />" );
- const std::string result6( "<smooth param='0.75'><glow color='red' param='0.1'>Glow</glow></smooth><br />" );
- const std::string result7( "<font color='green'><outline color='red' paramx='0.7' paramy='0.7'>Outline</outline></font><br />" );
- const std::string result8( "<smooth param='0.75'>Smooth</smooth><br />" );
- const std::string result9( text9 );
- const std::string result10( text10 );
- const std::string result11( "<br />" );
-
- std::string markupString;
- Toolkit::MarkupProcessor::StyledTextArray styledTextArray;
-
- GetStyledTextArray( text1, styledTextArray, true );
- GetMarkupString( styledTextArray, markupString );
- DALI_TEST_EQUALS( result1, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text2, styledTextArray, true );
- GetMarkupString( styledTextArray, markupString );
- DALI_TEST_EQUALS( result2, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text3, styledTextArray, true );
- GetMarkupString( styledTextArray, markupString );
- DALI_TEST_EQUALS( result3, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text4, styledTextArray, true );
- GetMarkupString( styledTextArray, markupString );
- DALI_TEST_EQUALS( result4, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text5, styledTextArray, true );
- GetMarkupString( styledTextArray, markupString );
- DALI_TEST_EQUALS( result5, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text6, styledTextArray, true );
- GetMarkupString( styledTextArray, markupString );
- DALI_TEST_EQUALS( result6, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text7, styledTextArray, true );
- GetMarkupString( styledTextArray, markupString );
- DALI_TEST_EQUALS( result7, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text8, styledTextArray, true );
- GetMarkupString( styledTextArray, markupString );
- DALI_TEST_EQUALS( result8, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text9, styledTextArray, true );
- GetMarkupString( styledTextArray, markupString );
- DALI_TEST_EQUALS( result9, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text10, styledTextArray, true );
- GetMarkupString( styledTextArray, markupString );
-
- DALI_TEST_EQUALS( result10, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text11, styledTextArray, true );
- GetMarkupString( styledTextArray, markupString );
-
- DALI_TEST_EQUALS( result11, markupString, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliMarkupProcessorSetTextStyle01(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliMarkupProcessorSetTextStyle01 ");
-
- const std::string text1( "Text with no defined style" );
- const std::string result1( "<font color='green'><i>Text with no defined style</i></font>" );
- const std::string result2( "Text with <font color='green'><i>no defined</i></font> style" );
-
- std::string markupString;
- Toolkit::MarkupProcessor::StyledTextArray styledTextArray;
-
- GetStyledTextArray( text1, styledTextArray, true );
-
- TextStyle style;
- style.SetItalics( true );
- style.SetTextColor( Color::GREEN );
-
- SetTextStyle( styledTextArray, style );
- GetMarkupString( styledTextArray, markupString );
-
- DALI_TEST_EQUALS( result1, markupString, TEST_LOCATION );
-
- styledTextArray.clear();
- SetTextStyle( text1, styledTextArray, style );
- GetMarkupString( styledTextArray, markupString );
-
- DALI_TEST_EQUALS( result1, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text1, styledTextArray, true );
- SetTextStyleToRange( styledTextArray, style, TextStyle::ALL, 0, text1.size() - 1 );
- GetMarkupString( styledTextArray, markupString );
-
- DALI_TEST_EQUALS( result1, markupString, TEST_LOCATION );
-
- GetStyledTextArray( text1, styledTextArray, true );
- SetTextStyleToRange( styledTextArray, style, TextStyle::ALL, 10, 19 );
- GetMarkupString( styledTextArray, markupString );
-
- DALI_TEST_EQUALS( result2, markupString, TEST_LOCATION );
-
- std::string plainString;
- GetPlainString( styledTextArray, plainString );
-
- DALI_TEST_EQUALS( text1, plainString, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliMarkupProcessorSetTextStyle02(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliMarkupProcessorSetTextStyle02 ");
-
- Toolkit::MarkupProcessor::StyledTextArray styledTextArray;
-
- // Test style applied to and empty string doesn't crash
-
- TextStyle style;
- style.SetItalics( true );
- style.SetTextColor( Color::GREEN );
-
- bool fails = false;
- try
- {
- SetTextStyle( styledTextArray, style );
- }
- catch( ... )
- {
- fails = true;
- }
-
- DALI_TEST_CHECK( !fails );
- END_TEST;
-}
-
-int UtcDaliMarkupProcessorTestColors(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliMarkupProcessorTestColors ");
-
- struct MarkupStringTest colorTests[] =
- {
- {
- std::string( "<font color='0xFF000000'>black</font>" ),
- std::string( "<font color='black'>black</font>" )
- },
- {
- std::string( "<font color='0xFFFFFFFF'>white</font>" ),
- std::string( "white" )
- },
- {
- std::string( "<font color='0xFFFF0000'>red</font>" ),
- std::string( "<font color='red'>red</font>" )
- },
- {
- std::string( "<font color='0xFF00FF00'>green</font>" ),
- std::string( "<font color='green'>green</font>" )
- },
- {
- std::string( "<font color='0xFF0000FF'>blue</font>" ),
- std::string( "<font color='blue'>blue</font>" )
- },
- {
- std::string( "<font color='0xFFFFFF00'>yellow</font>" ),
- std::string( "<font color='yellow'>yellow</font>" )
- },
- {
- std::string( "<font color='0xFFFF00FF'>magenta</font>" ),
- std::string( "<font color='magenta'>magenta</font>" )
- },
- {
- std::string( "<font color='0xFF00FFFF'>cyan</font>" ),
- std::string( "<font color='cyan'>cyan</font>" )
- },
- {
- std::string( "<font color='0x00000000'>transparent</font>" ),
- std::string( "<font color='transparent'>transparent</font>" )
- },
- {
- std::string( "<font color='#000000'>black</font>" ),
- std::string( "<font color='black'>black</font>" )
- },
- {
- std::string( "<font color='#FFFFFF'>white</font>" ),
- std::string( "white" )
- },
- {
- std::string( "<font color='#FF0000'>red</font>" ),
- std::string( "<font color='red'>red</font>" )
- },
- {
- std::string( "<font color='#00FF00'>green</font>" ),
- std::string( "<font color='green'>green</font>" )
- },
- {
- std::string( "<font color='#0000FF'>blue</font>" ),
- std::string( "<font color='blue'>blue</font>" )
- },
- {
- std::string( "<font color='#FFFF00'>yellow</font>" ),
- std::string( "<font color='yellow'>yellow</font>" )
- },
- {
- std::string( "<font color='#FF00FF'>magenta</font>" ),
- std::string( "<font color='magenta'>magenta</font>" )
- },
- {
- std::string( "<font color='#00FFFF'>cyan</font>" ),
- std::string( "<font color='cyan'>cyan</font>" )
- },
- {
- std::string( "<font color='#000'>black</font>" ),
- std::string( "<font color='black'>black</font>" )
- },
- {
- std::string( "<font color='#FFF'>white</font>" ),
- std::string( "white" )
- },
- {
- std::string( "<font color='#F00'>red</font>" ),
- std::string( "<font color='red'>red</font>" )
- },
- {
- std::string( "<font color='#0F0'>green</font>" ),
- std::string( "<font color='green'>green</font>" )
- },
- {
- std::string( "<font color='#00F'>blue</font>" ),
- std::string( "<font color='blue'>blue</font>" )
- },
- {
- std::string( "<font color='#FF0'>yellow</font>" ),
- std::string( "<font color='yellow'>yellow</font>" )
- },
- {
- std::string( "<font color='#F0F'>magenta</font>" ),
- std::string( "<font color='magenta'>magenta</font>" )
- },
- {
- std::string( "<font color='#0FF'>cyan</font>" ),
- std::string( "<font color='cyan'>cyan</font>" )
- },
- {
- std::string( "<font color='0x000000'>black</font>" ),
- std::string( "<font color='black'>black</font>" )
- },
- {
- std::string( "<font color='black'>black</font>" ),
- std::string( "<font color='black'>black</font>" )
- },
- {
- std::string( "<font color='white'>white</font>" ),
- std::string( "white" )
- },
- {
- std::string( "<font color='red'>red</font>" ),
- std::string( "<font color='red'>red</font>" )
- },
- {
- std::string( "<font color='0xFF00FF00'>green</font>" ),
- std::string( "<font color='green'>green</font>" )
- },
- {
- std::string( "<font color='blue'>blue</font>" ),
- std::string( "<font color='blue'>blue</font>" )
- },
- {
- std::string( "<font color='yellow'>yellow</font>" ),
- std::string( "<font color='yellow'>yellow</font>" )
- },
- {
- std::string( "<font color='magenta'>magenta</font>" ),
- std::string( "<font color='magenta'>magenta</font>" )
- },
- {
- std::string( "<font color='cyan'>cyan</font>" ),
- std::string( "<font color='cyan'>cyan</font>" )
- },
- {
- std::string( "<font color='transparent'>transparent</font>" ),
- std::string( "<font color='transparent'>transparent</font>" )
- },
- {
- std::string( "<outline color='white'>outline</outline>" ),
- std::string( "<outline color='white'>outline</outline>" )
- },
- };
-
- const std::size_t numberOfTests( 36 );
-
- bool fails = false;
- for( std::size_t index = 0; index < numberOfTests; ++index )
- {
- const MarkupStringTest& test = colorTests[index];
-
- std::string result;
- if( !TestMarkupString( test.input, test.expectedResult, result ) )
- {
- TestMarkupString( test.input, test.expectedResult, result );
- tet_printf( "%s\n input : %s\nexpected result : %s\n result : %s\n", TEST_LOCATION, test.input.c_str(), test.expectedResult.c_str(), result.c_str() );
-
- fails = true;
- }
- }
-
- DALI_TEST_CHECK( !fails );
- END_TEST;
-}
tet_infoline( "UtcDaliNavigationControlCreateNavigationTitleBar" );
ImageActor background = CreateSolidColorActor( Color::RED );
- TextStyle textStyle;
Stage stage = Stage::GetCurrent();
NavigationControl naviControl = NavigationControl::New();
stage.Add( naviControl );
- Toolkit::NaviTitleBarStyle titleBarStyle( background, textStyle, textStyle, 720, 111, 68, 48, 34, 16, 11, 45, 63, 26, 14, 22 );
- naviControl.CreateNavigationTitleBar( titleBarStyle, titleBarStyle );
-
Page naviItem = Page::New();
PushButton firstControl = PushButton::New();
//Test properties
std::string testString = "Hello World";
popup.SetProperty(popup.GetPropertyIndex("title"), testString);
- DALI_TEST_EQUALS( testString, popup.GetTitle().GetText(), TEST_LOCATION );
+ DALI_TEST_EQUALS( testString, popup.GetTitle(), TEST_LOCATION );
END_TEST;
}
int UtcDaliPopupSetTitle(void)
{
- ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
- tet_infoline(" UtcDaliPopupSetTitle");
-
- // Create the Popup actor
- Popup popup = Popup::New();
- Stage::GetCurrent().Add( popup );
- // Put in show state so it's layer is connected to popup (for ancestor check).
- popup.SetState(Popup::POPUP_SHOW, 0.0f);
-
- TextView titleActor = TextView::New();
- titleActor.SetText("title");
-
- DALI_TEST_CHECK( !popup.GetTitle() );
- popup.SetTitle(titleActor);
- DALI_TEST_CHECK( popup.GetTitle() == titleActor );
- DALI_TEST_CHECK( (popup.GetTitle()) && (popup.GetTitle().GetText() == "title") );
- // verify titleActor is actually inside popup, and not elsewhere on stage, or off even.
- DALI_TEST_CHECK( HasAncestor(titleActor, popup) );
-
- TextView titleActor2 = TextView::New();
- titleActor2.SetText("anothertitle");
- popup.SetTitle(titleActor2);
- DALI_TEST_CHECK( popup.GetTitle() != titleActor );
- DALI_TEST_CHECK( popup.GetTitle() == titleActor2 );
- DALI_TEST_CHECK( (popup.GetTitle()) && (popup.GetTitle().GetText() == "anothertitle") );
- // verify titleActor is actually inside popup, and not elsewhere on stage, or off even.
- DALI_TEST_CHECK( HasAncestor(titleActor2, popup) );
- END_TEST;
-}
-
-int UtcDaliPopupSetTitleText(void)
-{
- ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
- tet_infoline(" UtcDaliPopupSetTitleText");
-
- // Create the Popup actor
- Popup popup = Popup::New();
- Stage::GetCurrent().Add( popup );
- // Put in show state so it's layer is connected to popup (for ancestor check).
- popup.SetState(Popup::POPUP_SHOW, 0.0f);
-
- TextView titleActor = TextView::New();
- titleActor.SetText("title");
-
- DALI_TEST_CHECK( !popup.GetTitle() );
- popup.SetTitle(titleActor);
- DALI_TEST_CHECK( popup.GetTitle() == titleActor );
- DALI_TEST_CHECK( (popup.GetTitle()) && (popup.GetTitle().GetText() == "title") );
- // verify titleActor is actually inside popup, and not elsewhere on stage, or off even.
- DALI_TEST_CHECK( HasAncestor(titleActor, popup) );
-
- // this text should replace titleImage actor.
- popup.SetTitle("newtext");
- DALI_TEST_CHECK( popup.GetTitle() != titleActor );
- DALI_TEST_CHECK( (popup.GetTitle()) && (popup.GetTitle().GetText() == "newtext") );
- // verify titleActor is no longer inside popup. (been displaced by newtext actor)
- DALI_TEST_CHECK( !HasAncestor(titleActor, popup) );
+ // TODO
END_TEST;
}
application.SendNotification();
application.Render();
- TextView textView;
-
pushButton.SetLabel( STR );
- textView = TextView::DownCast( pushButton.GetLabel() );
- DALI_TEST_CHECK( STR == textView.GetText() );
-
- TextView text = TextView::New( STR );
- pushButton.SetLabel( text );
-
- textView = TextView::DownCast( pushButton.GetLabel() );
- DALI_TEST_CHECK( STR == textView.GetText() );
END_TEST;
}
int UtcDaliRadioButtonLabelActor(void)
{
- ToolkitTestApplication application;
-
- TextView actor1 = TextView::New( "test actor 1" );
-
- RadioButton radioButton = RadioButton::New( actor1 );
- DALI_TEST_CHECK( actor1 == radioButton.GetLabel() );
-
- TextView actor2 = TextView::New( "test actor 2" );
- radioButton.SetLabel( actor2 );
- DALI_TEST_CHECK( actor2 == radioButton.GetLabel() );
-
+ // TODO
END_TEST;
}
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-
-#include <stdlib.h>
-#include <dali-toolkit-test-suite-utils.h>
-#include <dali.h>
-#include <dali-toolkit/dali-toolkit.h>
-#include <dali/integration-api/events/key-event-integ.h>
-
-using namespace Dali;
-using namespace Toolkit;
-
-void utc_dali_toolkit_text_input_startup(void)
-{
- test_return_value = TET_UNDEF;
-}
-
-void utc_dali_toolkit_text_input_cleanup(void)
-{
- test_return_value = TET_PASS;
-}
-
-namespace
-{
-static bool gObjectCreatedCallBackCalled;
-
-static void TestCallback(BaseHandle handle)
-{
- Actor actor = Actor::DownCast(handle);
-
- if(actor)
- {
- TextInput handle = TextInput::DownCast(actor);
- if (handle)
- {
- gObjectCreatedCallBackCalled = true;
- }
- }
-}
-
-static bool gHasEndSignalBeenReceived;
-static bool gHasStartSignalBeenReceived;
-
-// Callback test function
-void OnStartInput(TextInput textInput)
-{
- gHasStartSignalBeenReceived = true;
-}
-
-// Callback test function
-void OnEndInput(TextInput textInput)
-{
- gHasEndSignalBeenReceived = true;
-}
-
-}
-
-// Positive test case for a method
-int UtcDaliTextInputConstruction(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing New constructor");
-
- TextInput textInput = TextInput::New();
- DALI_TEST_CHECK(textInput);
-
- //Additional check to ensure object is created by checking if it's registered
- ObjectRegistry registry = Stage::GetCurrent().GetObjectRegistry();
- DALI_TEST_CHECK( registry );
-
- gObjectCreatedCallBackCalled = false;
- registry.ObjectCreatedSignal().Connect(&TestCallback);
- {
- TextInput textInput = TextInput::New();
- }
- DALI_TEST_CHECK( gObjectCreatedCallBackCalled );
- END_TEST;
-}
-
-
-static bool downCastToTextInput(Dali::Actor actor)
-{
- TextInput handle = TextInput::DownCast(actor);
- if (handle)
- {
- tet_infoline("Downcasted to TextInput");
- return true;
- }
- else
- {
- tet_infoline("Did not downcast to TextInput");
- return false;
- }
-}
-
-// Positive test case for a method
-int UtcDaliTextInputDownCast(void)
-{
- ToolkitTestApplication application;
-
- TextInput textInput = TextInput::New();
-
- tet_infoline("Testing Downcasting with a TextInput");
- DALI_TEST_EQUALS(true,downCastToTextInput(textInput), TEST_LOCATION); // downcast a TextInput
-
- Dali::TextActor badHandle = Dali::TextActor::New("test");
-
- tet_infoline("Testing Downcasting with the wrong actor");
- DALI_TEST_EQUALS(false, downCastToTextInput(badHandle), TEST_LOCATION); // downcast a TextActor to TextInput
- END_TEST;
-}
-
-// Positive test case for a method
-int UtcDaliTextInputGetText(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing GetText");
-
- const std::string teststring = "test";
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- DALI_TEST_EQUALS("",textInput.GetText(), TEST_LOCATION); // Get text which should be empty
-
- textInput.SetInitialText(teststring);
-
- DALI_TEST_EQUALS(teststring,textInput.GetText(), TEST_LOCATION); // Get text which should be test string
-
- END_TEST;
-}
-
-int UtcDaliTextInputGetMarkupText(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing retrieval of Markup text after style set");
-
- const std::string markup = "<i>Text with italic style</i>" ;
- const std::string teststring = "Text with italic style";
-
- TextInput textInput = TextInput::New();
-
- tet_infoline("Set initial text");
-
- textInput.SetInitialText( teststring );
-
- tet_infoline("Check initial text");
- DALI_TEST_EQUALS( teststring,textInput.GetText(), TEST_LOCATION); // Get text which should be empty
-
- TextStyle style;
- style.SetItalics( true );
-
- tet_infoline("Apply style to TextInput");
- textInput.ApplyStyleToAll( style );
-
- tet_infoline("Retreive Markup Text");
- const std::string retreivedMarkupString = textInput.GetMarkupText();
-
- tet_infoline("Test Retreived text and Markup text match");
- DALI_TEST_EQUALS( retreivedMarkupString , retreivedMarkupString, TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputSetMaxCharacterLength(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing Setting of max characters");
-
- const int maxChars = 4;
- const char* testChar = "v";
-
- TextInput textInput = TextInput::New(); // create empty TextInput
- Stage::GetCurrent().Add(textInput);
- application.SendNotification();
- application.Render();
-
- textInput.SetMaxCharacterLength(maxChars);
-
- Integration::KeyEvent event(testChar, testChar, 0, 0, 0, Integration::KeyEvent::Down );
-
- std::string testString = "";
-
- tet_infoline("Starting editmode");
- textInput.SetEditable( true );
-
- tet_infoline("Sending Key Events");
- // Send max number of characters
- for (int i=0; i < maxChars; i++)
- {
- application.ProcessEvent(event);
- testString.append(testChar);
- }
-
- tet_printf( "Get text result : %s\n", textInput.GetText().c_str());
-
- DALI_TEST_EQUALS(testString, textInput.GetText(), TEST_LOCATION);
-
- tet_infoline("Sending Key Event which exceeds max characters");
-
- application.ProcessEvent(event); // try to append additional character
-
- DALI_TEST_EQUALS(testString,textInput.GetText(), TEST_LOCATION);
-
- tet_infoline("Increase max characters limit");
-
- textInput.SetMaxCharacterLength(maxChars+1); // increment max characters by 1
-
- tet_infoline("Send character again which should now fit");
- application.ProcessEvent(event); // append additional character
- testString.append(testChar);
-
- DALI_TEST_EQUALS(testString,textInput.GetText(), TEST_LOCATION);
- END_TEST;
-}
-
-
-int UtcDaliTextInputSetAndGetNumberOfLines(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Ensuring API for setting and getting max number of lines is correct");
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- unsigned int numberOfLines = 1;
-
- textInput.SetNumberOfLinesLimit( numberOfLines );
-
- DALI_TEST_EQUALS(numberOfLines ,textInput.GetNumberOfLinesLimit(), TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputGetNumberOfCharacters(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing Getting number of characters");
-
- const std::string initialString = "initial text";
- const std::string newInitialString = "initial text new";
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- textInput.SetInitialText( initialString );
-
- tet_infoline("Testing TextInput contains correct number of characters ");
-
- DALI_TEST_EQUALS( initialString.size() , textInput.GetNumberOfCharacters(), TEST_LOCATION);
-
- tet_infoline("Testing TextInput contains correct number of characters second phase ");
-
- textInput.SetInitialText( newInitialString );
-
- DALI_TEST_EQUALS( newInitialString.size() , textInput.GetNumberOfCharacters(), TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputSetAndGetPlaceholderText(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing Setting of PlaceholderText");
-
- const std::string initialString = "initial text";
- const std::string placeholderString = "placeholder";
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- tet_infoline("Testing TextInput is empty at creation ");
-
- DALI_TEST_EQUALS("",textInput.GetText(), TEST_LOCATION);
-
- tet_infoline("Set placeholder text");
-
- textInput.SetPlaceholderText( placeholderString );
-
- tet_infoline("Testing TextInput contains placeholder text");
-
- DALI_TEST_EQUALS( placeholderString , textInput.GetPlaceholderText(), TEST_LOCATION);
-
- tet_infoline("Set initial text which should replace placeholder text");
-
- textInput.SetInitialText( initialString );
-
- tet_infoline("Testing TextInput contains initial text when placeholder text set");
-
- DALI_TEST_EQUALS( initialString,textInput.GetText(), TEST_LOCATION);
- END_TEST;
-}
-
-// Positive test case for a method
-int UtcDaliTextInputSetInitialText(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing Setting of Initial Text");
-
- const std::string teststring = "test";
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- tet_infoline("Testing TextInput is empty at creation ");
-
- DALI_TEST_EQUALS("",textInput.GetText(), TEST_LOCATION);
-
- tet_infoline("Set text to TextInput");
-
- textInput.SetInitialText(teststring);
-
- tet_infoline("Test TextInput contains set text");
-
- DALI_TEST_EQUALS(teststring,textInput.GetText(), TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputSetEditableAndIsEditable(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing SetEditable And IsEditable");
-
- const std::string initialString = "initial text";
-
- TextInput textInput = TextInput::New(); // create empty TextInput
- textInput.SetInitialText( initialString );
-
- Stage::GetCurrent().Add(textInput);
- application.SendNotification();
- application.Render();
-
- bool editableStateFalse ( false );
- bool editableStateTrue ( true );
-
- textInput.SetEditable ( editableStateFalse );
- application.SendNotification();
- application.Render();
- DALI_TEST_EQUALS( editableStateFalse, textInput.IsEditable() , TEST_LOCATION);
-
- textInput.SetEditable ( editableStateTrue );
- application.SendNotification();
- application.Render();
- DALI_TEST_EQUALS( editableStateTrue, textInput.IsEditable() , TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputSetEditOnTouch(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing SetEditOnTouch And IsEditOnTouch");
-
- TextInput textInput = TextInput::New();
-
- bool editableOnTouchOn ( true );
- bool editableOnTouchOff( false );
-
- tet_infoline("Testing SetEditOnTouch disabled");
- textInput.SetEditOnTouch ( editableOnTouchOff );
- DALI_TEST_EQUALS( editableOnTouchOff, textInput.IsEditOnTouch() , TEST_LOCATION);
-
- tet_infoline("Testing SetEditOnTouch enabled");
- textInput.SetEditOnTouch ( editableOnTouchOn );
- DALI_TEST_EQUALS( editableOnTouchOn, textInput.IsEditOnTouch() , TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputSetTextSelectable(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing SetTextSelectable and IsTextSelectable");
-
- const std::string initialString = "initial text";
-
- TextInput textInput = TextInput::New();
- textInput.SetInitialText( initialString );
-
- tet_infoline("Testing SetTextSelectable");
- textInput.SetTextSelectable();
- DALI_TEST_EQUALS( true, textInput.IsTextSelectable() , TEST_LOCATION);
- textInput.SetTextSelectable( false );
- DALI_TEST_EQUALS( false, textInput.IsTextSelectable() , TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputTextSelection(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing Text Selection");
-
- const std::string initialString = "initial text";
-
- TextInput textInput = TextInput::New();
- textInput.SetInitialText( initialString );
-
- Stage::GetCurrent().Add(textInput);
- application.SendNotification();
- application.Render();
-
- textInput.SetEditable( true );
-
- tet_infoline("Testing IsTextSelected negative");
- DALI_TEST_EQUALS( false, textInput.IsTextSelected(), TEST_LOCATION);
-
- textInput.SelectText(1,7);
- DALI_TEST_EQUALS( true, textInput.IsTextSelected(), TEST_LOCATION);
-
- textInput.DeSelectText();
- DALI_TEST_EQUALS( false, textInput.IsTextSelected(), TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputEnableGrabHandleAndIsGrabHandleEnabled(void)
-{
- ToolkitTestApplication application;
-
- TextInput textInput = TextInput::New();
-
- bool grabHandleState = false;
-
- textInput.EnableGrabHandle( grabHandleState );
-
- DALI_TEST_EQUALS( grabHandleState, textInput.IsGrabHandleEnabled(), TEST_LOCATION);
-
- grabHandleState = true;
- textInput.EnableGrabHandle( grabHandleState );
-
- DALI_TEST_EQUALS( grabHandleState, textInput.IsGrabHandleEnabled(), TEST_LOCATION);
-
- END_TEST;
-}
-
-int UtcDaliTextInputSetAndGetBoundingRectangle(void)
-{
- ToolkitTestApplication application;
-
- TextInput textInput = TextInput::New();
-
- Stage::GetCurrent().Add(textInput);
- Vector2 stageSize = Stage::GetCurrent().GetSize();
-
- const Rect<float> boundingRectangle( 100.0f, 100.0f, stageSize.width, stageSize.height );
-
- textInput.SetBoundingRectangle( boundingRectangle );
-
- const Rect<float> retreievedBoundingRectangle = textInput.GetBoundingRectangle();
-
- DALI_TEST_EQUALS( boundingRectangle.x, retreievedBoundingRectangle.x, TEST_LOCATION);
- DALI_TEST_EQUALS( boundingRectangle.y, retreievedBoundingRectangle.y, TEST_LOCATION);
- DALI_TEST_EQUALS( boundingRectangle.width, retreievedBoundingRectangle.width, TEST_LOCATION);
- DALI_TEST_EQUALS( boundingRectangle.height, retreievedBoundingRectangle.height, TEST_LOCATION);
- END_TEST;
-}
-
-
-int UtcDaliTextInputSetAndGetTextAlignment01(void)
-{
- ToolkitTestApplication application;
-
- TextInput textInput = TextInput::New();
- Stage::GetCurrent().Add(textInput);
- application.SendNotification();
- application.Render();
-
- textInput.SetTextAlignment(static_cast<Alignment::Type>( Alignment::HorizontalCenter) );
- application.SendNotification();
- application.Render();
-
- DALI_TEST_CHECK( static_cast<Alignment::Type>( Alignment::HorizontalCenter) & textInput.GetTextAlignment()) ;
- END_TEST;
-}
-
-int UtcDaliTextInputSetAndGetTextAlignment02(void)
-{
- ToolkitTestApplication application;
-
- TextInput textInput = TextInput::New();
- textInput.SetTextAlignment(static_cast<Alignment::Type>( Alignment::HorizontalCenter) );
-
- bool result = ( textInput.GetTextAlignment() & Alignment::HorizontalCenter ) ;
-
- DALI_TEST_CHECK( result );
-
- result = ( textInput.GetTextAlignment() & Alignment::HorizontalRight );
-
- DALI_TEST_CHECK( !result );
- END_TEST;
-}
-
-int UtcDaliTextInputSetSortModifier(void)
-{
- tet_infoline("Testing SetSortModifier does not cause TextInput failure");
-
- ToolkitTestApplication application;
-
- TextInput textInput = TextInput::New();
-
- const float offsetToUse = 1.5f;
-
- textInput.SetSortModifier( offsetToUse );
-
- DALI_TEST_CHECK( textInput );
- END_TEST;
-}
-
-int UtcDaliTextInputSetAndGetSnapshotModeEnabled(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing SetSnapshotModeEnabled and IsSnapshotModeEnabled");
-
- TextInput textInput = TextInput::New(); // create empty TextInput
- bool snapshotMode( true );
- textInput.SetSnapshotModeEnabled( snapshotMode );
-
- DALI_TEST_EQUALS( snapshotMode, textInput.IsSnapshotModeEnabled(), TEST_LOCATION);
-
- snapshotMode = false;
- textInput.SetSnapshotModeEnabled( snapshotMode );
-
- DALI_TEST_EQUALS( snapshotMode, textInput.IsSnapshotModeEnabled(), TEST_LOCATION);
- END_TEST;
-}
-
-
-int UtcDaliTextInputEndSignalEmit(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing Set editable false emits end signal");
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- Stage::GetCurrent().Add(textInput);
-
- textInput.InputFinishedSignal().Connect( &OnEndInput );
-
- textInput.SetEditable(true) ;
-
- gHasEndSignalBeenReceived = false;
-
- textInput.SetEditable(false) ;
-
- DALI_TEST_EQUALS(true, gHasEndSignalBeenReceived, TEST_LOCATION);
- END_TEST;
-}
-
-
-
-int UtcDaliTextInputStartSignalEmit(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing SetEditable emits start signal");
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- Stage::GetCurrent().Add(textInput);
-
- textInput.InputStartedSignal().Connect( &OnStartInput );
-
- gHasStartSignalBeenReceived = false;
-
- textInput.SetEditable(true); // Set editable first time
-
- DALI_TEST_EQUALS(true, gHasStartSignalBeenReceived, TEST_LOCATION);
-
- gHasStartSignalBeenReceived = false;
-
- textInput.SetEditable(true); // Set editable second time, signal should not be sent again.
-
- DALI_TEST_EQUALS(false, gHasStartSignalBeenReceived, TEST_LOCATION);
-
- textInput.SetEditable(false);
-
- gHasStartSignalBeenReceived = false;
-
- textInput.SetEditable(true); // Set editable again
-
- DALI_TEST_EQUALS(true, gHasStartSignalBeenReceived, TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputExceedMaxCharacters(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing Max characters is obeyed when inputting key events ");
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- Stage::GetCurrent().Add(textInput);
- textInput.SetMaxCharacterLength(4);
- textInput.SetInitialText("");
- textInput.SetEditable(true);
-
- application.SendNotification();
- application.Render();
-
- Integration::KeyEvent eventA("a", "a", 0, 0, 0, Integration::KeyEvent::Down );
- Integration::KeyEvent eventB("b", "b", 0, 0, 0, Integration::KeyEvent::Down );
-
- application.ProcessEvent(eventA);
- application.ProcessEvent(eventB);
- application.ProcessEvent(eventA);
- application.ProcessEvent(eventB);
-
- application.ProcessEvent(eventA);
- application.ProcessEvent(eventB);
-
- tet_printf( "Get text result : %s\n", textInput.GetText().c_str());
-
- DALI_TEST_EQUALS("abab",textInput.GetText(), TEST_LOCATION); // Get text which should be only 4 characters
- END_TEST;
-}
-
-
-
-int UtcDaliTextInputSetAndGetFadeBoundary(void)
-{
- tet_infoline("UtcDaliTextViewSetAndGetFadeBoundary: ");
-
- ToolkitTestApplication application;
-
- TextView::FadeBoundary fadeBoundary( PixelSize( 0 ), PixelSize( 20 ), PixelSize( 0 ), PixelSize( 10 ) );
-
- TextInput textInput = TextInput::New();
- textInput.SetInitialText( "Hello world!" );
-
- Stage::GetCurrent().Add(textInput);
- application.SendNotification();
- application.Render();
-
- textInput.SetFadeBoundary( fadeBoundary );
-
- TextView::FadeBoundary fadeBoundary2 = textInput.GetFadeBoundary();
-
- DALI_TEST_EQUALS( fadeBoundary.mLeft, fadeBoundary2.mLeft, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeBoundary.mRight, fadeBoundary2.mRight, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeBoundary.mTop, fadeBoundary2.mTop, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeBoundary.mBottom, fadeBoundary2.mBottom, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliTextInputSetAndGetWidthExceedPolicy(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextInputSetAndGetWidthExceedPolicy: ");
-
- const TextView::ExceedPolicy EXCEED_POLICIES[] = { TextView::Original, TextView::Fade, TextView::Split, TextView::ShrinkToFit };
- const unsigned int NUM_EXCEED_POLICIES = sizeof( EXCEED_POLICIES ) / sizeof( unsigned int );
-
- TextInput textInput = TextInput::New();
- textInput.SetInitialText( "Hello world!" );
-
- for( unsigned int epIndex = 0; epIndex < NUM_EXCEED_POLICIES; ++epIndex )
- {
- textInput.SetWidthExceedPolicy( EXCEED_POLICIES[epIndex] );
-
- DALI_TEST_EQUALS( textInput.GetWidthExceedPolicy(), EXCEED_POLICIES[epIndex], TEST_LOCATION );
- }
- END_TEST;
-}
-
-int UtcDaliTextInputSetAndGetHeightExceedPolicy(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("UtcDaliTextInputSetAndGetHeightExceedPolicy: ");
-
- const TextView::ExceedPolicy EXCEED_POLICIES[] = { TextView::Original, TextView::Fade, TextView::ShrinkToFit };
- const unsigned int NUM_EXCEED_POLICIES = sizeof( EXCEED_POLICIES ) / sizeof( unsigned int );
-
- TextInput textInput = TextInput::New();
- textInput.SetInitialText( "Hello world!" );
-
- for( unsigned int epIndex = 0; epIndex < NUM_EXCEED_POLICIES; ++epIndex )
- {
- textInput.SetHeightExceedPolicy( EXCEED_POLICIES[epIndex] );
-
- DALI_TEST_EQUALS( textInput.GetHeightExceedPolicy(), EXCEED_POLICIES[epIndex], TEST_LOCATION );
- }
- END_TEST;
-}
-
-int UtcDaliTextInputScroll(void)
-{
- tet_infoline("UtcDaliTextInputScroll: ");
- ToolkitTestApplication application;
-
- // Avoids the frame buffer texture to throw an exception.
- application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
-
- TextInput view = TextInput::New();
- view.SetMultilinePolicy( TextView::SplitByNewLineChar );
- view.SetWidthExceedPolicy( TextView::Original );
- view.SetHeightExceedPolicy( TextView::Original );
- view.SetTextAlignment( static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ) );
- view.SetInitialText( "Hello world! This is a scroll test." );
- view.SetSize( 100.f, 100.f );
- view.SetSnapshotModeEnabled( false );
-
- Stage::GetCurrent().Add( view );
-
- application.SendNotification();
- application.Render();
-
- DALI_TEST_CHECK( !view.IsScrollEnabled() ); // Scroll should be disabled by default.
-
- view.SetScrollEnabled( true );
-
- DALI_TEST_CHECK( view.IsScrollEnabled() );
- DALI_TEST_CHECK( view.IsSnapshotModeEnabled() ); // Scroll should enable snapshot mode.
-
- view.SetScrollPosition( Vector2( 400.f, 400.f ) );
-
- application.SendNotification();
- application.Render();
-
- const Vector2& scrollPosition = view.GetScrollPosition();
- DALI_TEST_EQUALS( scrollPosition, Vector2( 149.153656f, 0.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliTextInputSetActiveStyle(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing Setting of Style to newly added text");
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- Stage::GetCurrent().Add(textInput);
-
- const std::string styledString = "Test String<i>ab</i>" ;
- const std::string plainString = "Test String";
- textInput.SetInitialText( plainString );
-
- application.SendNotification();
- application.Render();
-
- textInput.SetEditable(true);
-
- std::string retreivedMarkupString = textInput.GetMarkupText();
-
- tet_infoline("Confirm markup text is a plain string ");
- DALI_TEST_EQUALS( plainString,textInput.GetText(), TEST_LOCATION);
-
- TextStyle style;
- style.SetItalics( true );
-
- tet_infoline("Apply style to TextInput");
- textInput.SetActiveStyle( style );
-
- Integration::KeyEvent eventA("a", "a", 0, 0, 0, Integration::KeyEvent::Down );
- Integration::KeyEvent eventB("b", "b", 0, 0, 0, Integration::KeyEvent::Down );
-
- application.SendNotification();
- application.Render();
-
- application.ProcessEvent(eventA);
- application.SendNotification();
- application.Render();
-
- application.ProcessEvent(eventB);
- application.SendNotification();
- application.Render();
-
- retreivedMarkupString = textInput.GetMarkupText();
-
- DALI_TEST_EQUALS( styledString, retreivedMarkupString, TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputApplyStyleToSelectedText(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing application of style to selected text ");
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- Stage::GetCurrent().Add(textInput);
-
- const std::string styledString = "Test <i>String</i> to style";
- const std::string plainString = "Test String to style";
- textInput.SetInitialText( plainString );
-
- application.SendNotification();
- application.Render();
-
- textInput.SetEditable(true);
-
- std::string retreivedMarkupString = textInput.GetMarkupText();
-
- tet_infoline("Confirm markup text is a plain string ");
- DALI_TEST_EQUALS( plainString,textInput.GetText(), TEST_LOCATION);
-
- TextStyle style;
- style.SetItalics( true );
-
- textInput.SelectText( 5, 11 );
-
- tet_infoline("Apply style to selected text");
- textInput.ApplyStyle( style );
-
- application.Render();
-
- retreivedMarkupString = textInput.GetMarkupText();
-
- DALI_TEST_EQUALS( styledString, retreivedMarkupString, TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputApplyStyleToAll(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Testing application of style to all text ");
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- Stage::GetCurrent().Add(textInput);
-
- const std::string styledString = "<i>Test String to style</i>";
- const std::string plainString = "Test String to style";
- textInput.SetInitialText( plainString );
-
- application.SendNotification();
- application.Render();
-
- textInput.SetEditable(true);
-
- std::string retreivedMarkupString = textInput.GetMarkupText();
-
- tet_infoline("Confirm markup text is a plain string ");
- DALI_TEST_EQUALS( plainString,textInput.GetText(), TEST_LOCATION);
-
- TextStyle style;
- style.SetItalics( true );
-
- tet_infoline("Apply style to all text");
- textInput.ApplyStyleToAll( style );
-
- application.Render();
-
- retreivedMarkupString = textInput.GetMarkupText();
-
- DALI_TEST_EQUALS( styledString, retreivedMarkupString, TEST_LOCATION);
- END_TEST;
-}
-
-int UtcDaliTextInputGetStyleAtCursor(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline("Test getting style at cursor");
-
- TextInput textInput = TextInput::New(); // create empty TextInput
-
- Stage::GetCurrent().Add(textInput);
-
- const std::string styledString = "Test Stringa<i>b</i>" ;
- const std::string plainString = "Test String";
- textInput.SetInitialText( plainString );
-
- application.SendNotification();
- application.Render();
-
- textInput.SetEditable(true);
-
- tet_infoline("Confirm style at cursor is default(plain)");
- TextStyle style;
- Integration::KeyEvent eventA("a", "a", 0, 0, 0, Integration::KeyEvent::Down );
- application.ProcessEvent(eventA);
- application.SendNotification();
- application.Render();
-
- TextStyle retreivedStyleAtCursor = textInput.GetStyleAtCursor();
-
- DALI_TEST_CHECK( style == retreivedStyleAtCursor );
- DALI_TEST_CHECK( !retreivedStyleAtCursor.IsItalicsEnabled() );
-
- tet_infoline("Set style before adding new character");
- style.SetItalics( true );
- textInput.SetActiveStyle( style );
-
- Integration::KeyEvent eventB("b", "b", 0, 0, 0, Integration::KeyEvent::Down );
- application.ProcessEvent(eventB);
- application.SendNotification();
- application.Render();
-
- tet_infoline("Confirm style at cursor is correct style");
- retreivedStyleAtCursor = textInput.GetStyleAtCursor();
-
- DALI_TEST_CHECK( retreivedStyleAtCursor.IsItalicsEnabled() );
-
- tet_infoline("Confirm style at cursor is not a style that was not set");
- DALI_TEST_CHECK( !retreivedStyleAtCursor.IsUnderlineEnabled() );
-
- tet_infoline("Confirm markup text is correct");
- DALI_TEST_EQUALS( styledString, textInput.GetMarkupText(), TEST_LOCATION);
-
-
-
- END_TEST;
-}
-
-int UtcDaliTextInputSetAndGetMultilinePolicy(void)
-{
- ToolkitTestApplication application;
-
- const TextView::MultilinePolicy MULTILINE_POLICIES[] = { TextView::SplitByNewLineChar, TextView::SplitByWord, TextView::SplitByChar };
- const unsigned int NUM_MULTILINE_POLICIES = sizeof( MULTILINE_POLICIES ) / sizeof( unsigned int );
-
- TextInput textInput = TextInput::New();
- Stage::GetCurrent().Add(textInput);
- textInput.SetInitialText( "Hello world!" );
-
- for( unsigned int epIndex = 0; epIndex < NUM_MULTILINE_POLICIES; ++epIndex )
- {
- textInput.SetMultilinePolicy( MULTILINE_POLICIES[epIndex] );
-
- DALI_TEST_EQUALS( textInput.GetMultilinePolicy(), MULTILINE_POLICIES[epIndex], TEST_LOCATION );
- }
- END_TEST;
-}
-
-int UtcDaliTextInputSetAndGetExceedEnabled(void)
-{
- ToolkitTestApplication application;
-
- const TextView::ExceedPolicy EXCEED_POLICIES[] = { TextView::Original, TextView::Fade, TextView::Split, TextView::ShrinkToFit };
- const unsigned int NUM_EXCEED_POLICIES = sizeof( EXCEED_POLICIES ) / sizeof( unsigned int );
-
- TextInput textInput = TextInput::New();
- Stage::GetCurrent().Add(textInput);
- textInput.SetInitialText( "Hello world!" );
-
- for( unsigned int epIndex = 0; epIndex < NUM_EXCEED_POLICIES; ++epIndex )
- {
- textInput.SetWidthExceedPolicy( EXCEED_POLICIES[epIndex] );
-
- DALI_TEST_EQUALS( textInput.GetWidthExceedPolicy(), EXCEED_POLICIES[epIndex], TEST_LOCATION );
- }
- END_TEST;
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-#include <stdlib.h>
-
-// Need to override adaptor classes for toolkit test harness, so include
-// test harness headers before dali headers.
-#include <dali-toolkit-test-suite-utils.h>
-
-#include <dali.h>
-#include <dali-toolkit/dali-toolkit.h>
-
-using namespace Dali;
-using namespace Toolkit;
-
-void utc_dali_toolkit_text_view_startup(void)
-{
- test_return_value = TET_UNDEF;
-}
-
-void utc_dali_toolkit_text_view_cleanup(void)
-{
- test_return_value = TET_PASS;
-}
-
-
-namespace
-{
-
-const char* const PROPERTY_TEXT = "text";
-const char* const PROPERTY_MULTILINE_POLICY = "multiline-policy";
-const char* const PROPERTY_WIDTH_EXCEED_POLICY = "width-exceed-policy";
-const char* const PROPERTY_HEIGHT_EXCEED_POLICY = "height-exceed-policy";
-const char* const PROPERTY_LINE_JUSTIFICATION = "line-justification";
-const char* const PROPERTY_FADE_BOUNDARY = "fade-boundary";
-const char* const PROPERTY_LINE_HEIGHT_OFFSET = "line-height-offset";
-const char* const PROPERTY_HORIZONTAL_ALIGNMENT = "horizontal-alignment";
-const char* const PROPERTY_VERTICAL_ALIGNMENT = "vertical-alignment";
-
-bool TestEqual( float x, float y )
-{
- return !( fabsf( x - y ) > Math::MACHINE_EPSILON_1000 );
-}
-
-static bool gObjectCreatedCallBackCalled;
-static unsigned int gNumberObjectCreated;
-
-static void TestCallback(BaseHandle handle)
-{
- gObjectCreatedCallBackCalled = true;
- ++gNumberObjectCreated;
-}
-
-static bool gTextScrolled;
-static Vector2 gScrollDelta;
-static void TestTextScrolled( TextView textView, Vector2 scrollDelta )
-{
- gTextScrolled = true;
- gScrollDelta = scrollDelta;
-}
-
-} // namespace
-
-
-int UtcDaliTextViewNew(void)
-{
- tet_infoline("UtcDaliTextViewNew: ");
- ToolkitTestApplication application;
-
- // Test default constructor.
- TextView view;
-
- DALI_TEST_CHECK( !view );
-
- // Test default initialization.
- view = TextView::New();
-
- DALI_TEST_CHECK( view );
-
- // Test copy constructor and asignment operator.
- TextView viewCopy1;
-
- viewCopy1 = view;
-
- DALI_TEST_CHECK( viewCopy1 );
-
- TextView viewCopy2( view );
-
- DALI_TEST_CHECK( viewCopy2 );
-
- // Test down cast.
- Actor actorView;
-
- actorView = view;
-
- TextView downCastView = TextView::DownCast( actorView );
-
- DALI_TEST_CHECK( downCastView );
-
- // Test constructor with a given text.
-
- const std::string text( "Hello world!" );
-
- const float DESCENDER = 8.0f;
-
- TextView view1 = TextView::New( text );
-
- DALI_TEST_EQUALS( view1.GetText(), text, TEST_LOCATION );
-
- MarkupProcessor::StyledTextArray styledText;
- MarkupProcessor::GetStyledTextArray( text, styledText, true );
-
- TextView view2 = TextView::New( styledText );
-
- DALI_TEST_EQUALS( view2.GetText(), text, TEST_LOCATION );
-
- // Check the default Toolkit::TextView::CharacterLayoutInfo::CharacterLayoutInfo() to increase coverage.
- TextView::CharacterLayoutInfo characterLayoutInfo;
-
- DALI_TEST_EQUALS( characterLayoutInfo.mSize, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mPosition, Vector3::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mIsNewLineChar, false, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mIsRightToLeftCharacter, false, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mIsVisible, true, TEST_LOCATION );
-
- TextView::CharacterLayoutInfo characterLayoutInfo2( Size( 2.f, 2.f ),
- Vector3( 3.f, 4.f, 5.f ),
- true,
- true,
- false,
- DESCENDER );
-
- characterLayoutInfo = characterLayoutInfo2;
-
- DALI_TEST_EQUALS( characterLayoutInfo.mSize, Size( 2.f, 2.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mPosition, Vector3( 3.f, 4.f, 5.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mIsNewLineChar, true, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mIsRightToLeftCharacter, true, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mIsVisible, false, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo.mDescender, DESCENDER , TEST_LOCATION );
-
-
- TextView::CharacterLayoutInfo characterLayoutInfo3( characterLayoutInfo );
-
- DALI_TEST_EQUALS( characterLayoutInfo3.mSize, Size( 2.f, 2.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo3.mPosition, Vector3( 3.f, 4.f, 5.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo3.mIsNewLineChar, true, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo3.mIsRightToLeftCharacter, true, TEST_LOCATION );
- DALI_TEST_EQUALS( characterLayoutInfo3.mIsVisible, false, TEST_LOCATION );
-
- // Check the default Toolkit::TextView::TextLayoutInfo::TextLayoutInfo() to increase coverage.
-
- TextView::TextLayoutInfo textLayoutInfo;
- DALI_TEST_EQUALS( textLayoutInfo.mCharacterLayoutInfoTable.size(), 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mCharacterLogicalToVisualMap.size(), 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mCharacterVisualToLogicalMap.size(), 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mTextSize, Size::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo.mScrollOffset, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
- textLayoutInfo.mCharacterLayoutInfoTable.push_back( characterLayoutInfo );
- textLayoutInfo.mCharacterLogicalToVisualMap.push_back( 1 );
- textLayoutInfo.mCharacterVisualToLogicalMap.push_back( 1 );
- textLayoutInfo.mTextSize = Size( 10.f, 10.f );
- textLayoutInfo.mScrollOffset = Vector2( 5.f, 5.f );
-
- TextView::TextLayoutInfo textLayoutInfo2( textLayoutInfo );
-
- DALI_TEST_EQUALS( textLayoutInfo2.mCharacterLayoutInfoTable.size(), 1u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo2.mCharacterLogicalToVisualMap.size(), 1u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo2.mCharacterVisualToLogicalMap.size(), 1u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo2.mTextSize, Size( 10.f, 10.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo2.mScrollOffset, Vector2( 5.f, 5.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
- TextView::TextLayoutInfo textLayoutInfo3;
-
- textLayoutInfo3 = textLayoutInfo2;
-
- DALI_TEST_EQUALS( textLayoutInfo3.mCharacterLayoutInfoTable.size(), 1u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo3.mCharacterLogicalToVisualMap.size(), 1u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo3.mCharacterVisualToLogicalMap.size(), 1u, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo3.mTextSize, Size( 10.f, 10.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( textLayoutInfo3.mScrollOffset, Vector2( 5.f, 5.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
- //Additional check to ensure object is created by checking if it's registered
- ObjectRegistry registry = Stage::GetCurrent().GetObjectRegistry();
- DALI_TEST_CHECK( registry );
-
- gObjectCreatedCallBackCalled = false;
- registry.ObjectCreatedSignal().Connect(&TestCallback);
- {
- TextView view = TextView::New();
- }
- DALI_TEST_CHECK( gObjectCreatedCallBackCalled );
- END_TEST;
-}
-
-int UtcDaliTextViewSetAndGetText(void)
-{
- tet_infoline("UtcDaliTextViewSetAndGetText: ");
- ToolkitTestApplication application;
-
- TextView view = TextView::New();
- view.SetSnapshotModeEnabled( false ); // Disables offscreen rendering.
-
- std::string str( "Text with differing aCeNdEr and dEcEnDeR" );
-
- view.SetText( str );
- DALI_TEST_EQUALS( view.GetText(), str, TEST_LOCATION );
-
- MarkupProcessor::StyledTextArray styledText;
- MarkupProcessor::GetStyledTextArray( str, styledText, true );
-
- view.SetText( styledText );
- DALI_TEST_EQUALS( view.GetText(), str, TEST_LOCATION );
-
- // Test the number of text actor created.
-
- ObjectRegistry registry = Stage::GetCurrent().GetObjectRegistry();
- DALI_TEST_CHECK( registry );
-
- gNumberObjectCreated = 0u;
- registry.ObjectCreatedSignal().Connect(&TestCallback);
-
- // Following string should create three text-actors ([Hel], [lo wo] and [rld]).
- std::string text( "Hel<font size='10'>lo wo</font>rld!\n"
- "\n" );
-
- view.SetMarkupProcessingEnabled( true ); // Enables markup processing.
-
- Stage::GetCurrent().Add( view );
- view.SetText( text );
-
- application.SendNotification();
- application.Render();
-
- DALI_TEST_EQUALS( 3u, gNumberObjectCreated, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliTextViewSetStyleToCurrentText(void)
-{
- tet_infoline("UtcDaliTextViewSetStyleToCurrentText: ");
- ToolkitTestApplication application;
-
- TextStyle style;
- style.SetItalics( true );
-
- const std::string text( "앞서 농식품부 주이석 검역검사본부\n"
- "동물방역부장을 단장으로 하는\n"
- "민관합동조사단은 지난달 30일부터\n"
- "12일간의 현지 조사활동을 마치고\n"
- "11일 새벽 귀국했습니다." );
- TextView view = TextView::New( text );
-
- bool fail = false;
- try
- {
- view.SetStyleToCurrentText( style );
- }
- catch( ... )
- {
- tet_printf( "Tet case fails\n" );
- fail = true;
- tet_result(TET_FAIL);
- }
-
- DALI_TEST_CHECK( !fail );
- END_TEST;
-}
-
-int UtcDaliTextViewSetAndGetLineHeight(void)
-{
- tet_infoline("UtcDaliTextViewSetAndGetLineHeight: ");
-
- ToolkitTestApplication application;
-
- const float lineHeightOffset( 9.f );
-
- TextView textView = TextView::New();
-
- textView.SetLineHeightOffset( PointSize( lineHeightOffset ) );
-
- DALI_TEST_EQUALS( float(textView.GetLineHeightOffset()), lineHeightOffset, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliTextViewSetAndGetFadeBoundary(void)
-{
- tet_infoline("UtcDaliTextViewSetAndGetFadeBoundary: ");
-
- ToolkitTestApplication application;
-
- TextView::FadeBoundary fadeBoundary( PixelSize( 0 ), PixelSize( 20 ), PixelSize( 0 ), PixelSize( 10 ) );
-
- TextView textView = TextView::New( "Hello world!" );
-
- textView.SetFadeBoundary( fadeBoundary );
-
- TextView::FadeBoundary fadeBoundary2 = textView.GetFadeBoundary();
-
- DALI_TEST_EQUALS( fadeBoundary.mLeft, fadeBoundary2.mLeft, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeBoundary.mRight, fadeBoundary2.mRight, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeBoundary.mTop, fadeBoundary2.mTop, TEST_LOCATION );
- DALI_TEST_EQUALS( fadeBoundary.mBottom, fadeBoundary2.mBottom, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliTextViewSetAndGetEllipsizeText(void)
-{
- tet_infoline("UtcDaliTextViewSetAndGetEllipsizeText: ");
-
- ToolkitTestApplication application;
-
- TextView textView = TextView::New( "Hello world!" );
-
- textView.SetEllipsizeText( std::string( "..." ) );
-
- DALI_TEST_EQUALS( std::string( "..." ), textView.GetEllipsizeText(), TEST_LOCATION );
-
- Toolkit::MarkupProcessor::StyledTextArray styledTextArray;
-
- GetStyledTextArray( std::string( "..." ), styledTextArray, true );
-
- textView.SetEllipsizeText( styledTextArray );
-
- DALI_TEST_EQUALS( std::string( "..." ), textView.GetEllipsizeText(), TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliTextViewSetAndGetWidthExceedPolicy(void)
-{
- tet_infoline("UtcDaliTextViewSetAndGetWidthExceedPolicy: ");
-
- ToolkitTestApplication application;
-
- const TextView::ExceedPolicy EXCEED_POLICIES[] = { TextView::Original, TextView::Fade, TextView::Split, TextView::ShrinkToFit };
- const unsigned int NUM_EXCEED_POLICIES = sizeof( EXCEED_POLICIES ) / sizeof( unsigned int );
-
- TextView textView = TextView::New( "Hello world!" );
-
- for( unsigned int epIndex = 0; epIndex < NUM_EXCEED_POLICIES; ++epIndex )
- {
- textView.SetWidthExceedPolicy( EXCEED_POLICIES[epIndex] );
-
- DALI_TEST_EQUALS( textView.GetWidthExceedPolicy(), EXCEED_POLICIES[epIndex], TEST_LOCATION );
- }
- END_TEST;
-}
-
-int UtcDaliTextViewSetAndGetHeightExceedPolicy(void)
-{
- tet_infoline("UtcDaliTextViewSetAndGetHeightExceedPolicy: ");
-
- ToolkitTestApplication application;
-
- const TextView::ExceedPolicy EXCEED_POLICIES[] = { TextView::Original, TextView::Fade, TextView::ShrinkToFit };
- const unsigned int NUM_EXCEED_POLICIES = sizeof( EXCEED_POLICIES ) / sizeof( unsigned int );
-
- TextView textView = TextView::New( "Hello world!" );
-
- for( unsigned int epIndex = 0; epIndex < NUM_EXCEED_POLICIES; ++epIndex )
- {
- textView.SetHeightExceedPolicy( EXCEED_POLICIES[epIndex] );
-
- DALI_TEST_EQUALS( textView.GetHeightExceedPolicy(), EXCEED_POLICIES[epIndex], TEST_LOCATION );
- }
- END_TEST;
-}
-
-/*
-// Re-enable this test case when ALL layout options work in TextView, currently this breaks TCT
-// output because too many warnings/errors are printed out
-//int UtcDaliTextViewTestLayoutOptions01(void)
-{
- tet_infoline("UtcDaliTextViewTestLayoutOptions01: ");
-
- ToolkitTestApplication application;
-
- const std::string text( "앞서 농식품부 주이석 검역검사본부\n"
- "동물방역부장을 단장으로 하는\n"
- "민관합동조사단은 지난달 30일부터\n"
- "12일간의 현지 조사활동을 마치고\n"
- "11일 새벽 귀국했습니다." );
-
- const TextView::MultilinePolicy MULTILINE_POLICIES[] = { TextView::SplitByNewLineChar, TextView::SplitByWord, TextView::SplitByChar };
- const TextView::ExceedPolicy EXCEED_WIDTH_POLICIES[] = { TextView::Original, TextView::Fade, TextView::Split, TextView::ShrinkToFit, TextView::EllipsizeEnd };
- const TextView::ExceedPolicy EXCEED_HEIGHT_POLICIES[] = { TextView::Original, TextView::Fade, TextView::ShrinkToFit };
- const Alignment::Type TEXT_ALIGNMENT[] = { static_cast<Alignment::Type>( Alignment::HorizontalLeft | Alignment::VerticalTop ),
- static_cast<Alignment::Type>( Alignment::HorizontalLeft | Alignment::VerticalCenter ),
- static_cast<Alignment::Type>( Alignment::HorizontalLeft | Alignment::VerticalBottom ),
- static_cast<Alignment::Type>( Alignment::HorizontalCenter | Alignment::VerticalTop ),
- static_cast<Alignment::Type>( Alignment::HorizontalCenter | Alignment::VerticalCenter ),
- static_cast<Alignment::Type>( Alignment::HorizontalCenter | Alignment::VerticalBottom ),
- static_cast<Alignment::Type>( Alignment::HorizontalRight | Alignment::VerticalTop ),
- static_cast<Alignment::Type>( Alignment::HorizontalRight | Alignment::VerticalCenter ),
- static_cast<Alignment::Type>( Alignment::HorizontalRight | Alignment::VerticalBottom ) };
- const TextView::LineJustification LINE_JUSTIFICATION[] = { TextView::Left, TextView::Center, TextView::Right, TextView::Justified };
-
- const unsigned int NUM_MULTILINE_POLICIES = sizeof( MULTILINE_POLICIES ) / sizeof( unsigned int );
- const unsigned int NUM_WIDTH_EXCEED_POLICIES = sizeof( EXCEED_WIDTH_POLICIES ) / sizeof( unsigned int );
- const unsigned int NUM_HEIGHT_EXCEED_POLICIES = sizeof( EXCEED_HEIGHT_POLICIES ) / sizeof( unsigned int );
- const unsigned int NUM_TEXT_ALIGNMENT = sizeof( TEXT_ALIGNMENT ) / sizeof( unsigned int );
- const unsigned int NUM_LINE_JUSTIFICATION = sizeof( LINE_JUSTIFICATION ) / sizeof( unsigned int );
-
- TextView textView = TextView::New( text );
- textView.SetSnapshotModeEnabled( false ); // Disables offscreen rendering.
-
- Stage::GetCurrent().Add( textView );
-
- TextView::TextLayoutInfo textLayoutInfo;
-
- for( unsigned int mlpIndex = 0; mlpIndex < NUM_MULTILINE_POLICIES; ++mlpIndex )
- {
- textView.SetMultilinePolicy( MULTILINE_POLICIES[mlpIndex] );
- for( unsigned int ewpIndex = 0; ewpIndex < NUM_WIDTH_EXCEED_POLICIES; ++ewpIndex )
- {
- textView.SetWidthExceedPolicy( EXCEED_WIDTH_POLICIES[ewpIndex] );
- for( unsigned int ehpIndex = 0; ehpIndex < NUM_HEIGHT_EXCEED_POLICIES; ++ehpIndex )
- {
- textView.SetHeightExceedPolicy( EXCEED_HEIGHT_POLICIES[ehpIndex] );
- for( unsigned int taIndex = 0; taIndex < NUM_TEXT_ALIGNMENT; ++taIndex )
- {
- textView.SetTextAlignment( TEXT_ALIGNMENT[taIndex] );
- for( unsigned int ljIndex = 0; ljIndex < NUM_LINE_JUSTIFICATION; ++ljIndex )
- {
- textView.SetLineJustification( LINE_JUSTIFICATION[ljIndex] );
-
- try
- {
- textView.GetTextLayoutInfo( textLayoutInfo );
-
- application.SendNotification();
- application.Render();
- }
- catch( Dali::DaliException& e )
- {
- DALI_TEST_EQUALS( e.condition, "!\"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination\"", TEST_LOCATION );
- }
- catch( ... )
- {
- tet_printf( "Tet case fails\n" );
- tet_printf( " MultilinePolicy : %d\n", MULTILINE_POLICIES[mlpIndex] );
- tet_printf( " Width ExceedPolicy : %d\n", EXCEED_WIDTH_POLICIES[ewpIndex] );
- tet_printf( " Height ExceedPolicy : %d\n", EXCEED_HEIGHT_POLICIES[ehpIndex] );
- tet_printf( " TextAlignment : %d\n", TEXT_ALIGNMENT[taIndex] );
- tet_printf( " LineJustification : %d\n", LINE_JUSTIFICATION[ljIndex] );
- tet_result(TET_FAIL);
- }
-
- DALI_TEST_CHECK( LINE_JUSTIFICATION[ljIndex] == textView.GetLineJustification() );
- }
- DALI_TEST_CHECK( TEXT_ALIGNMENT[taIndex] == textView.GetTextAlignment() );
- }
- DALI_TEST_CHECK( EXCEED_HEIGHT_POLICIES[ehpIndex] == textView.GetHeightExceedPolicy() );
- }
- DALI_TEST_CHECK( EXCEED_WIDTH_POLICIES[ewpIndex] == textView.GetWidthExceedPolicy() );
- }
- DALI_TEST_CHECK( MULTILINE_POLICIES[mlpIndex] == textView.GetMultilinePolicy() );
- }
- END_TEST;
-}
-*/
-
-int UtcDaliTextViewTestLayoutOptions02(void)
-{
- tet_infoline("UtcDaliTextViewTestLayoutOptions02: ");
- ToolkitTestApplication application;
-
- // Check some configurations.
-
- TextView textView = TextView::New();
- textView.SetSnapshotModeEnabled( false ); // Disables offscreen rendering.
- textView.SetMarkupProcessingEnabled( true ); // Enables markup processing.
-
- Stage::GetCurrent().Add( textView );
-
- // SplitByWord and ShrinkToFit.
- // Centered alignment.
- // Centered justification.
- // Don't create a text actor per character.
-
- textView.SetMultilinePolicy( TextView::SplitByWord );
- textView.SetWidthExceedPolicy( TextView::ShrinkToFit );
- textView.SetHeightExceedPolicy( TextView::ShrinkToFit );
- textView.SetTextAlignment( static_cast<Alignment::Type>( Alignment::HorizontalCenter | Alignment::VerticalTop ) );
- textView.SetLineJustification( TextView::Center );
- textView.SetSize( 136.56252f, 100.f );
-
- textView.SetText( "Hel<font color='green'>lo wo</font>rld!" );
-
- application.SendNotification();
- application.Render();
-
- std::vector<Size> sizes;
- sizes.push_back( Size( 34.14063f, 11.380210f ) ); //
- sizes.push_back( Size( 56.90105f, 11.380210f ) ); //
- sizes.push_back( Size( 45.52084f, 11.380210f ) ); // By default characters have width and height values of 11.380210.
- // The result should be a line with the text 'Hello world' as shown below.
- std::vector<Vector3> positions; // ____________
- positions.push_back( Vector3( 0.000008f, 11.380209f, 0.f ) ); // |Hello world!|
- positions.push_back( Vector3( 34.14063f, 11.380209f, 0.f ) ); // ------------
- positions.push_back( Vector3( 91.04168f, 11.380209f, 0.f ) ); //
-
- DALI_TEST_CHECK( positions.size() == textView.GetChildCount() ); // Check text has two text-actors.
-
- for( std::size_t index = 0, num = textView.GetChildCount(); index < num; ++index )
- {
- const Vector3& size = textView.GetChildAt(index).GetCurrentSize();
- const Vector3& position = textView.GetChildAt(index).GetCurrentPosition();
-
- DALI_TEST_EQUALS( size.width, sizes[index].width, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( size.height, sizes[index].height, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( position.width, positions[index].width, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( position.height, positions[index].height, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- }
-
- textView.SetSize( 50.f, 50.f );
- textView.SetTextAlignment( static_cast<Alignment::Type>( Alignment::HorizontalCenter | Alignment::VerticalCenter ) );
- textView.SetSizePolicy( Toolkit::Control::Fixed, Toolkit::Control::Fixed );
- textView.SetLineJustification( Toolkit::TextView::Left );
-
- application.SendNotification();
- application.Render();
-
- sizes.clear();
- sizes.push_back( Size( 24.999999f, 8.333333f ) ); //
- sizes.push_back( Size( 24.999999f, 8.333333f ) ); //
- sizes.push_back( Size( 16.666666f, 8.333333f ) ); // Longest word is 'world!' (6 characters x 11.380210) which doesn't fit in the 50x50 box.
- sizes.push_back( Size( 33.333332f, 8.333333f ) ); // The scale factor is 0.732265339, so the character size is 8.333333.
- // Text should be split in two lines, centered in the vertical dimension and fitted in the horizontal one.
- positions.clear(); // As shown below, the text is two lines and centered in the vertical dimension and
- positions.push_back( Vector3( 0.000008f, 25.223114f, 0.f ) ); // it should start in middle height (~25).
- positions.push_back( Vector3( 24.999999f, 25.223114f, 0.f ) ); // ______
- positions.push_back( Vector3( 0.000006f, 33.556446f, 0.f ) ); // | |
- positions.push_back( Vector3( 16.666666f, 33.556446f, 0.f ) ); // |Hello |
- // |world!|
- // |______|
- //
-
- DALI_TEST_CHECK( positions.size() == textView.GetChildCount() ); // Check text has two text-actors.
-
- for( std::size_t index = 0, num = textView.GetChildCount(); index < num; ++index )
- {
- const Vector3& size = textView.GetChildAt(index).GetCurrentSize();
- const Vector3& position = textView.GetChildAt(index).GetCurrentPosition();
-
- DALI_TEST_EQUALS( size.width, sizes[index].width, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( size.height, sizes[index].height, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( position.width, positions[index].width, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( position.height, positions[index].height, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- }
-
- // TODO: Add more tests when TextView implementation is finished.
- END_TEST;
-}
-
-int UtcDaliTextViewInsertRemoveText(void)
-{
- tet_infoline("UtcDaliTextViewInsertRemoveText: ");
- ToolkitTestApplication application;
-
- std::string text("Hello ");
-
- MarkupProcessor::StyledTextArray styledText;
- MarkupProcessor::GetStyledTextArray( text, styledText, true );
-
- TextView view = TextView::New( "world!" );
-
- view.InsertTextAt( 0, styledText );
-
- DALI_TEST_EQUALS( view.GetText(), std::string("Hello world!"), TEST_LOCATION );
-
- view.RemoveTextFrom( 4, 5 );
-
- DALI_TEST_EQUALS( view.GetText(), std::string("Hellld!"), TEST_LOCATION );
-
- view.InsertTextAt( 0, "Hello " );
-
- DALI_TEST_EQUALS( view.GetText(), std::string("Hello Hellld!"), TEST_LOCATION );
-
-
- view.InsertTextAt( 0, "Hello " );
- view.InsertTextAt( 0, "Hello " );
- view.InsertTextAt( 0, "Hello " );
- view.InsertTextAt( 0, "Hello " );
- view.RemoveTextFrom( 4, 2 );
- view.RemoveTextFrom( 4, 2 );
- view.RemoveTextFrom( 4, 2 );
- view.RemoveTextFrom( 4, 2 );
- view.RemoveTextFrom( 4, 2 );
- view.SetText( "Hello world!" );
-
- DALI_TEST_EQUALS( view.GetText(), std::string("Hello world!"), TEST_LOCATION );
-
- view.ReplaceTextFromTo( 5, 1, "" );
-
- DALI_TEST_EQUALS( view.GetText(), std::string("Helloworld!"), TEST_LOCATION );
-
- view.ReplaceTextFromTo( 0, 11, styledText );
-
- DALI_TEST_EQUALS( view.GetText(), std::string("Hello "), TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliTextViewSnapshotEnable(void)
-{
- tet_infoline("UtcDaliTextViewSnapshotEnable: ");
- ToolkitTestApplication application;
-
- // Avoids the frame buffer texture to throw an exception.
- application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
-
- TextView view = TextView::New();
- view.SetMarkupProcessingEnabled( true ); // Enables markup processing.
- view.SetText( "Hel<font color='green'>lo world!</font> This <font color='green'>is</font> a sna<font color='green'>psho</font>t test." );
-
- Stage::GetCurrent().Add( view );
-
- view.SetSnapshotModeEnabled( true ); // VCC. By default the snapshot mode should be enabled but it has been temporary disabled.
- // This line should be removed when text-view is set to use the snapshot mode by default.
-
- // Snapshot is enabled by default.
- DALI_TEST_CHECK( view.IsSnapshotModeEnabled() );
-
- application.SendNotification();
- application.Render();
-
- // TextView should have only two actors:
- // the root (Actor) and the image (ImageActor).
-
- DALI_TEST_EQUALS( view.GetChildCount(), 2u, TEST_LOCATION );
-
- view.SetSnapshotModeEnabled( false );
- DALI_TEST_CHECK( !view.IsSnapshotModeEnabled() );
-
- application.SendNotification();
- application.Render();
-
- // TextView should have one text-actor per word.
-
- DALI_TEST_EQUALS( view.GetChildCount(), 7u, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliTextViewScroll(void)
-{
- tet_infoline("UtcDaliTextViewScroll: ");
- ToolkitTestApplication application;
-
- // Avoids the frame buffer texture to throw an exception.
- application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
-
- TextView view = TextView::New( "Hello world! This is a scroll test." );
- view.SetSize( 100.f, 100.f );
- view.SetSnapshotModeEnabled( false );
-
- Stage::GetCurrent().Add( view );
-
- application.SendNotification();
- application.Render();
-
- DALI_TEST_CHECK( !view.IsScrollEnabled() ); // Scroll should be disabled by default.
-
- view.SetScrollEnabled( true );
- view.ScrolledSignal().Connect( &TestTextScrolled );
-
- DALI_TEST_CHECK( view.IsScrollEnabled() );
- DALI_TEST_CHECK( view.IsSnapshotModeEnabled() ); // Scroll should enable snapshot mode.
-
- gTextScrolled = false;
- gScrollDelta = Vector2::ZERO;
- view.SetScrollPosition( Vector2( 400.f, 400.f ) );
-
- application.SendNotification();
- application.Render();
-
- const Vector2& scrollPosition = view.GetScrollPosition();
- DALI_TEST_EQUALS( scrollPosition, Vector2( 149.153656f, 0.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
- DALI_TEST_CHECK( gTextScrolled );
- DALI_TEST_EQUALS( gScrollDelta, Vector2( 149.153656f, 0.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
- DALI_TEST_CHECK( view.IsScrollPositionTrimmed() );
- END_TEST;
-}
-
-int UtcDaliTextViewSetProperty(void)
-{
- tet_infoline("UtcDaliTextViewSetAndGetText: ");
- ToolkitTestApplication application;
-
- TextView view = TextView::New( "Hello world!" );
- Stage::GetCurrent().Add( view );
-
- //Test multiline policy property
- view.SetProperty(view.GetPropertyIndex(PROPERTY_MULTILINE_POLICY), "SplitByNewLineChar");
- DALI_TEST_CHECK( Toolkit::TextView::SplitByNewLineChar == view.GetMultilinePolicy() );
-
- view.SetProperty(view.GetPropertyIndex(PROPERTY_MULTILINE_POLICY), "SplitByWord");
- DALI_TEST_CHECK( Toolkit::TextView::SplitByWord == view.GetMultilinePolicy() );
-
- view.SetProperty(view.GetPropertyIndex(PROPERTY_MULTILINE_POLICY), "SplitByChar");
- DALI_TEST_CHECK( Toolkit::TextView::SplitByChar == view.GetMultilinePolicy() );
-
- //Test width exceed policy property
- view.SetProperty(view.GetPropertyIndex(PROPERTY_WIDTH_EXCEED_POLICY), "Original");
- view.SetProperty(view.GetPropertyIndex(PROPERTY_HEIGHT_EXCEED_POLICY), "Original");
- DALI_TEST_CHECK( Toolkit::TextView::Original == view.GetWidthExceedPolicy() );
- DALI_TEST_CHECK( Toolkit::TextView::Original == view.GetHeightExceedPolicy() );
-
- view.SetProperty(view.GetPropertyIndex(PROPERTY_WIDTH_EXCEED_POLICY), "Fade");
- view.SetProperty(view.GetPropertyIndex(PROPERTY_HEIGHT_EXCEED_POLICY), "Fade");
- DALI_TEST_CHECK( Toolkit::TextView::Fade == view.GetWidthExceedPolicy() );
- DALI_TEST_CHECK( Toolkit::TextView::Fade == view.GetHeightExceedPolicy() );
-
- view.SetProperty(view.GetPropertyIndex(PROPERTY_WIDTH_EXCEED_POLICY), "ShrinkToFit");
- view.SetProperty(view.GetPropertyIndex(PROPERTY_HEIGHT_EXCEED_POLICY), "ShrinkToFit");
- DALI_TEST_CHECK( Toolkit::TextView::ShrinkToFit == view.GetWidthExceedPolicy() );
- DALI_TEST_CHECK( Toolkit::TextView::ShrinkToFit == view.GetHeightExceedPolicy() );
-
- //Test line justification property
- view.SetProperty(view.GetPropertyIndex(PROPERTY_LINE_JUSTIFICATION), "Left");
- DALI_TEST_CHECK( Toolkit::TextView::Left == view.GetLineJustification() );
-
- view.SetProperty(view.GetPropertyIndex(PROPERTY_LINE_JUSTIFICATION), "Center");
- DALI_TEST_CHECK( Toolkit::TextView::Center == view.GetLineJustification() );
-
- view.SetProperty(view.GetPropertyIndex(PROPERTY_LINE_JUSTIFICATION), "Right");
- DALI_TEST_CHECK( Toolkit::TextView::Right == view.GetLineJustification() );
-
- view.SetProperty(view.GetPropertyIndex(PROPERTY_LINE_JUSTIFICATION), "Justified");
- DALI_TEST_CHECK( Toolkit::TextView::Justified == view.GetLineJustification() );
-
- //Test fade boundary property
- const Vector4 testValue( 23.f, 26.f, 2.f, 11.f );
-
- view.SetProperty(view.GetPropertyIndex(PROPERTY_FADE_BOUNDARY), testValue);
- DALI_TEST_CHECK( testValue.x == view.GetFadeBoundary().mLeft );
- DALI_TEST_CHECK( testValue.y == view.GetFadeBoundary().mRight );
- DALI_TEST_CHECK( testValue.z == view.GetFadeBoundary().mTop );
- DALI_TEST_CHECK( testValue.w == view.GetFadeBoundary().mBottom );
-
- //Test Line height offset property
- float testOffsetValue = 14.04f;
- view.SetProperty(view.GetPropertyIndex(PROPERTY_LINE_HEIGHT_OFFSET), testOffsetValue);
- DALI_TEST_CHECK( PointSize(testOffsetValue) == view.GetLineHeightOffset() );
-
- //Test alignment property
- view.SetProperty(view.GetPropertyIndex(PROPERTY_HORIZONTAL_ALIGNMENT), "HorizontalLeft");
- view.SetProperty(view.GetPropertyIndex(PROPERTY_VERTICAL_ALIGNMENT), "VerticalTop");
- DALI_TEST_CHECK( (Toolkit::Alignment::HorizontalLeft | Toolkit::Alignment::VerticalTop) == view.GetTextAlignment() );
- END_TEST;
-}
-
-int UtcDaliTextViewSetSortModifier(void)
-{
- tet_infoline("UtcDaliTextViewSetAndGetText: ");
- ToolkitTestApplication application;
-
- TextView view = TextView::New( "Hello world!" );
- Stage::GetCurrent().Add( view );
-
- view.SetSortModifier( 10.f );
- view.SetSnapshotModeEnabled( false );
-
- application.SendNotification();
- application.Render();
-
- DALI_TEST_EQUALS( RenderableActor::DownCast(view.GetChildAt(0)).GetSortModifier(), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliTextViewUnderlineText(void)
-{
- tet_infoline("UtcDaliTextViewUnderlineText: ");
- ToolkitTestApplication application;
-
- TextView textView = TextView::New();
- textView.SetSnapshotModeEnabled( false );
- textView.SetMarkupProcessingEnabled( true );
- textView.SetText( "<u><font size='10'>gg<font size='14'>gg<font size='18'>gg<font size='22'>gg</font>gg</font>gg</font>gg</font></u>" );
-
- textView.SetSize( 150.f, 100.f );
-
- Stage::GetCurrent().Add( textView );
-
- application.SendNotification();
- application.Render();
-
- std::vector<float> positions;
- positions.push_back( 6.448784f );
- positions.push_back( 9.862847f );
- positions.push_back( 13.276909f );
- positions.push_back( 16.690973f );
- positions.push_back( 13.276909f );
- positions.push_back( 9.862847f );
- positions.push_back( 6.448784f );
-
- for( std::size_t index = 0, num = textView.GetChildCount(); index < num; ++index )
- {
- TextStyle style = TextActor::DownCast( textView.GetChildAt(index) ).GetTextStyle();
-
- DALI_TEST_EQUALS( 4.17274f, style.GetUnderlineThickness(), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- DALI_TEST_EQUALS( positions[index], style.GetUnderlinePosition(), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
- }
- END_TEST;
-}
PKG_CHECK_MODULES(DALICORE, dali-core)
PKG_CHECK_MODULES(DALI, dali)
-PKG_CHECK_MODULES(FRIBIDI, fribidi)
DALI_TOOLKIT_CFLAGS=-DPLATFORM_TIZEN
publicapisliderdir = $(publicapicontrolsdir)/slider
publicapisuperblurviewdir = $(publicapicontrolsdir)/super-blur-view
publicapitableviewdir = $(publicapicontrolsdir)/table-view
-publicapitextviewdir = $(publicapicontrolsdir)/text-view
-publicapitextinputdir = $(publicapicontrolsdir)/text-input
+publicapitextcontrolsdir = $(publicapidir)/controls/text-controls
+publicapitextdir = $(publicapidir)/text
+publicapitextdecoratordir = $(publicapidir)/text/decorator
+publicapitextlayoutsdir = $(publicapidir)/text/layouts
+publicapitextrenderingdir = $(publicapidir)/text/rendering
+publicapitextrenderingbasicdir = $(publicapidir)/text/rendering/basic
+publicapitextrenderingshadersdir = $(publicapidir)/text/rendering/shaders
publicapitoolbardir = $(publicapicontrolsdir)/tool-bar
publicapiviewdir = $(publicapicontrolsdir)/view
-
publicapibuilderdir = $(publicapidir)/builder
publicapifocusmanagerdir = $(publicapidir)/focus-manager
-publicapimarkupprocessordir = $(publicapidir)/markup-processor
publicapishadereffectsdir = $(publicapidir)/shader-effects
publicapibubbleeffectdir = $(publicapidir)/shader-effects/bubble-effect
publicapistylingdir = $(publicapidir)/styling
publicapislider_HEADERS = $(public_api_slider_header_files)
publicapisuperblurview_HEADERS = $(public_api_super_blur_view_header_files)
publicapitableview_HEADERS = $(public_api_table_view_header_files)
-publicapitextview_HEADERS = $(public_api_text_view_header_files)
-publicapitextinput_HEADERS = $(public_api_text_input_header_files)
+publicapitextcontrols_HEADERS = $(public_api_text_controls_header_files)
+publicapitext_HEADERS = $(public_api_text_header_files)
+publicapitextdecorator_HEADERS = $(public_api_text_decorator_header_files)
+publicapitextlayouts_HEADERS = $(public_api_text_layouts_header_files)
+publicapitextrendering_HEADERS = $(public_api_text_rendering_header_files)
+publicapitextrenderingbasic_HEADERS = $(public_api_text_rendering_basic_header_files)
+publicapitextrenderingshaders_HEADERS = $(public_api_text_rendering_shaders_header_files)
publicapitoolbar_HEADERS = $(public_api_tool_bar_header_files)
publicapiview_HEADERS = $(public_api_view_header_files)
-
publicapibuilder_HEADERS = $(public_api_builder_header_files)
publicapifocusmanager_HEADERS = $(public_api_focus_manager_header_files)
-publicapimarkupprocessor_HEADERS = $(public_api_markup_processor_header_files)
publicapishadereffects_HEADERS = $(public_api_shader_effects_header_files)
publicapibubbleeffect_HEADERS = $(public_api_bubble_effect_header_files)
publicapistyling_HEADERS = $(public_api_styling_header_files)
#include <dali-toolkit/public-api/controls/slider/slider.h>
#include <dali-toolkit/public-api/controls/super-blur-view/super-blur-view.h>
#include <dali-toolkit/public-api/controls/table-view/table-view.h>
-#include <dali-toolkit/public-api/controls/text-input/text-input.h>
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-field.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
#include <dali-toolkit/public-api/controls/tool-bar/tool-bar.h>
#include <dali-toolkit/public-api/controls/view/view.h>
#include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
#include <dali-toolkit/public-api/focus-manager/keyinput-focus-manager.h>
-#include <dali-toolkit/public-api/markup-processor/markup-processor.h>
-
#include <dali-toolkit/public-api/scripting/script.h>
#include <dali-toolkit/public-api/scripting/script-plugin.h>
#include <dali-toolkit/public-api/shader-effects/ripple2d-effect.h>
#include <dali-toolkit/public-api/shader-effects/swirl-effect.h>
+#include <dali-toolkit/public-api/text/bidirectional-line-info-run.h>
+#include <dali-toolkit/public-api/text/bidirectional-paragraph-info-run.h>
+#include <dali-toolkit/public-api/text/bidirectional-support.h>
+#include <dali-toolkit/public-api/text/character-run.h>
+#include <dali-toolkit/public-api/text/character-set-conversion.h>
+#include <dali-toolkit/public-api/text/font-run.h>
+#include <dali-toolkit/public-api/text/line-run.h>
+#include <dali-toolkit/public-api/text/logical-model.h>
+#include <dali-toolkit/public-api/text/multi-language-support.h>
+#include <dali-toolkit/public-api/text/script.h>
+#include <dali-toolkit/public-api/text/script-run.h>
+#include <dali-toolkit/public-api/text/segmentation.h>
+#include <dali-toolkit/public-api/text/shaper.h>
+#include <dali-toolkit/public-api/text/text-controller.h>
+#include <dali-toolkit/public-api/text/text-definitions.h>
+#include <dali-toolkit/public-api/text/text-view.h>
+#include <dali-toolkit/public-api/text/text-view-interface.h>
+#include <dali-toolkit/public-api/text/visual-model.h>
+#include <dali-toolkit/public-api/text/decorator/text-decorator.h>
+#include <dali-toolkit/public-api/text/layouts/layout-engine.h>
+#include <dali-toolkit/public-api/text/rendering/text-renderer.h>
+#include <dali-toolkit/public-api/text/rendering/basic/text-basic-renderer.h>
+#include <dali-toolkit/public-api/text/rendering/shaders/text-basic-shader.h>
+
#include <dali-toolkit/public-api/transition-effects/cube-transition-effect.h>
#include <dali-toolkit/public-api/transition-effects/cube-transition-wave-effect.h>
#include <dali-toolkit/public-api/transition-effects/cube-transition-cross-effect.h>
#include <dali/public-api/scripting/scripting.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
namespace Dali
{
void Button::SetLabel( const std::string& label )
{
- Toolkit::TextView textView = Toolkit::TextView::New( label );
- textView.SetWidthExceedPolicy( Toolkit::TextView::ShrinkToFit ); // Make sure our text always fits inside the button
- SetLabel( textView );
}
void Button::SetLabel( Actor label )
#include <dali/public-api/object/type-registry.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
#include <dali-toolkit/internal/controls/relayout-helper.h>
namespace Dali
size.height = std::max( size.height, imageSize.height );
}
}
-
- // If label, test against it's size
- Toolkit::TextView textView = Toolkit::TextView::DownCast( GetLabel() );
- if( textView )
- {
- Vector3 textViewSize = textView.GetNaturalSize();
-
- if( widthIsZero )
- {
- size.width = std::max( size.width, textViewSize.width + TEXT_PADDING * 2.0f );
- }
-
- if( heightIsZero )
- {
- size.height = std::max( size.height, textViewSize.height + TEXT_PADDING * 2.0f );
- }
- }
}
return size;
#include <dali/public-api/common/dali-vector.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
#include <dali-toolkit/public-api/controls/buttons/radio-button.h>
#include "button-impl.h"
// title icon layout: the top row, the bottom row and the left column are all for margins
mTitleIconLayout= Toolkit::TableView::New( 3,2 );
SetFixedSizes();
-
- mTitle = Toolkit::TextView::New();
- mTitle.SetTextAlignment( Toolkit::Alignment::HorizontalLeft );
- mTitle.SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
- mSubTitle = Toolkit::TextView::New();
- mSubTitle.SetTextAlignment( Toolkit::Alignment::HorizontalLeft );
- mSubTitle.SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
}
void NavigationTitleBar::Update( Toolkit::Page page )
mLayout.AddChild(mButtonLayout, Toolkit::TableView::CellPosition(0,2));
}
- // add title and subtitle(if exist)
- mTitle.SetText( page.GetTitle() );
- mTitle.SetStyleToCurrentText(mCurrentStyle->titleTextStyle);
- if( page.GetSubTitle().empty() ) //display title
- {
- mTitleLayout.SetFixedHeight( 1,mCurrentStyle->titleHeightWithoutSubtitle - mCurrentStyle->subtitleHeight );
- mTitleLayout.AddChild( mTitle, Toolkit::TableView::CellPosition(1,0,2,1) );
- }
- else //display title and subtitle
- {
- mTitleLayout.SetFixedHeight( 1, mCurrentStyle->titleHeightWithSubtitle );
- mTitleLayout.AddChild( mTitle, Toolkit::TableView::CellPosition(1,0) );
- mSubTitle.SetText( page.GetSubTitle() );
- mSubTitle.SetStyleToCurrentText(mCurrentStyle->subtitleTextStyle);
- mTitleLayout.AddChild( mSubTitle, Toolkit::TableView::CellPosition(2,0) );
- }
-
// insert title icon to the left of the title(if exist)
if( page.GetTitleIcon() )
{
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/navigation-frame/page.h>
#include <dali-toolkit/public-api/controls/table-view/table-view.h>
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
#include <dali-toolkit/internal/controls/navigation-frame/navigation-control-impl.h>
#include <dali-toolkit/internal/controls/navigation-frame/navigation-bar.h>
Toolkit::TableView mTitleLayout;
Toolkit::TableView mTitleIconLayout;
- Toolkit::TextView mTitle;
- Toolkit::TextView mSubTitle;
-
};
} // namespace Internal
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/table-view/table-view.h>
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
#include <dali-toolkit/internal/controls/navigation-frame/navigation-control-impl.h>
#include <dali-toolkit/internal/controls/navigation-frame/navigation-bar.h>
#include <dali-toolkit/public-api/controls/navigation-frame/page.h>
void Popup::SetTitle( const std::string& text )
{
- Toolkit::TextView titleActor = Toolkit::TextView::New();
- titleActor.SetText( text );
- titleActor.SetColor( Color::BLACK );
- titleActor.SetMultilinePolicy( Toolkit::TextView::SplitByWord );
- titleActor.SetWidthExceedPolicy( Toolkit::TextView::Split );
- titleActor.SetLineJustification( Toolkit::TextView::Center );
-
- SetTitle( titleActor );
}
-void Popup::SetTitle( Toolkit::TextView titleActor )
+const std::string& Popup::GetTitle() const
{
- // Replaces the current title actor.
- if( mTitle && mPopupBg )
- {
- mPopupBg.Remove( mTitle );
- }
- mTitle = titleActor;
-
- mPopupBg.Add( mTitle );
-
- RelayoutRequest();
-}
-
-Toolkit::TextView Popup::GetTitle() const
-{
- return mTitle;
+ static std::string temp("");
+ return temp;
}
void Popup::AddButton( Toolkit::Button button )
// Relayout title
Vector3 positionOffset( 0.0f, mPopupStyle->margin + POPUP_OUT_MARGIN_WIDTH, CONTENT_DEPTH );
- if( mTitle )
- {
- Vector2 titleSize;
- titleSize.width = popupSize.width;
- titleSize.height = mTitle.GetHeightForWidth( titleSize.width );
-
- // As the default size policy for text-view is Fixed & Fixed, a size needs to be set.
- // Otherwise size-negotiation algorithm uses the GetNaturalSize() with doesn't take
- // into account the multiline and exceed policies, giving as result a wrong size.
- mTitle.SetSize( titleSize );
- Relayout( mTitle, titleSize, container );
-
- mTitle.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- mTitle.SetParentOrigin( ParentOrigin::TOP_CENTER );
- mTitle.SetPosition( positionOffset );
-
- positionOffset.y += titleSize.height + mPopupStyle->margin;
- }
+ // TODO
// Relayout content
if( mContent )
Vector3 naturalSize( 0.0f, 0.0f, 0.0f );
- if ( mTitle )
- {
- Vector3 titleNaturalSize = mTitle.GetImplementation().GetNaturalSize();
- // Buffer to avoid errors. The width of the popup could potentially be the width of the title text.
- // It was observed in this case that text wrapping was then inconsistent when seen on device
- const float titleBuffer = 0.5f;
- titleNaturalSize.width += titleBuffer;
-
- // As TextView GetNaturalSize does not take wrapping into account, limit the width
- // to that of the stage
- if( titleNaturalSize.width >= maxWidth)
- {
- naturalSize.width = maxWidth;
- naturalSize.height = mTitle.GetImplementation().GetHeightForWidth( naturalSize.width );
- }
- else
- {
- naturalSize += titleNaturalSize;
- }
-
- naturalSize.height += mPopupStyle->margin;
- }
-
if( mContent )
{
Vector3 contentSize = RelayoutHelper::GetNaturalSize( mContent );
float height( 0.0f );
float popupWidth( width - 2.f * ( POPUP_OUT_MARGIN_WIDTH + mPopupStyle->margin ) );
- if ( mTitle )
- {
- height += mTitle.GetImplementation().GetHeightForWidth( popupWidth );
- height += mPopupStyle->margin;
- }
-
if( mContent )
{
height += RelayoutHelper::GetHeightForWidth( mContent, popupWidth ) + mPopupStyle->margin;
void SetTitle( const std::string& text );
/**
- * @copydoc Toolkit::Popup::SetTitle( TextView titleActor )
- */
- void SetTitle( Toolkit::TextView titleActor );
-
- /**
* @copydoc Toolkit::Popup::GetTitle
*/
- Toolkit::TextView GetTitle() const;
+ const std::string& GetTitle() const;
/**
* @copydoc Toolkit::Popup::AddButton
Actor mBackgroundImage; ///< Stores the background image.
Actor mButtonAreaImage; ///< Stores the button background image.
- Toolkit::TextView mTitle; ///< Stores the text title.
Actor mContent; ///< Stores popup's content.
Actor mBottomBg; ///< bottom button bar background. ImageActor is replaced with Actor due to hidden image.
Actor mTailImage; ///< Stores the tail image
#include <sstream>
#endif // defined(DEBUG_ENABLED)
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
-
namespace Dali
{
#include "relayout-controller-impl.h"
#include "dali-toolkit/public-api/controls/control.h"
#include "dali-toolkit/public-api/controls/control-impl.h"
-#include "dali-toolkit/public-api/controls/text-view/text-view.h"
namespace Dali
{
// EXTERNAL INCLUDES
#include <dali/public-api/actors/image-actor.h>
-#include <dali/public-api/actors/text-actor.h>
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control.h>
Image image = imageActor.GetImage();
size = Vector3( static_cast<float>( image.GetWidth() ), static_cast<float>( image.GetHeight() ), depth );
}
- else
- {
- // Get natural size for TextActor.
- TextActor textActor = TextActor::DownCast( actor );
- if( textActor )
- {
- Font font = textActor.GetFont();
- if( !font )
- {
- font = Font::New();
- }
- size = font.MeasureText( textActor.GetText() );
- size.depth = depth;
- }
- }
}
return size;
}
else
{
- TextActor textActor = TextActor::DownCast( actor );
- if( textActor )
- {
- Font font = textActor.GetFont();
- if( !font )
- {
- font = Font::New();
- }
- size = font.MeasureText( textActor.GetText() );
-
- constrainSize = true;
- }
- else
- {
- size = actor.GetCurrentSize();
- }
+ size = actor.GetCurrentSize();
}
// Scale the actor
mMarkSignal.Emit( self, markIndex );
}
}
-
- if( mHandleValueTextView )
- {
- std::stringstream ss;
- ss.precision( GetValuePrecision() );
- ss << std::fixed << clampledValue;
- mHandleValueTextView.SetText( ss.str() );
- }
}
void Slider::SetMarks( const MarkList& marks )
return arrow;
}
-Toolkit::TextView Slider::CreatePopupText()
-{
- Toolkit::TextView textView = Toolkit::TextView::New();
- textView.SetParentOrigin( ParentOrigin::CENTER );
- textView.SetAnchorPoint( AnchorPoint::CENTER );
- textView.SetSizePolicy( Toolkit::Control::Flexible, Toolkit::Control::Flexible );
- textView.SetZ( VALUE_DISPLAY_TEXT_Z );
- return textView;
-}
+//Toolkit::TextView Slider::CreatePopupText()
+//{
+//}
ImageActor Slider::CreatePopup()
{
popup.SetParentOrigin( ParentOrigin::TOP_CENTER );
popup.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
- mValueTextView = CreatePopupText();
- popup.Add( mValueTextView );
-
return popup;
}
void Slider::CreateHandleValueDisplay()
{
- if( mHandle && !mHandleValueTextView )
- {
- mHandleValueTextView = Toolkit::TextView::New();
- mHandleValueTextView.SetParentOrigin( ParentOrigin::CENTER );
- mHandleValueTextView.SetAnchorPoint( AnchorPoint::CENTER );
- mHandleValueTextView.SetSize( GetHandleRegion() );
- mHandleValueTextView.SetZ( HANDLE_VALUE_DISPLAY_TEXT_Z );
- mHandle.Add( mHandleValueTextView );
- }
}
void Slider::DestroyHandleValueDisplay()
{
- if(mHandleValueTextView)
- {
- mHandleValueTextView.Unparent();
- mHandleValueTextView.Reset();
- }
}
void Slider::SetPopupTextColor( const Vector4& color )
void Slider::DisplayPopup( float value )
{
- // Value displayDoConnectSignal
- if( mValueTextView )
- {
- std::stringstream ss;
- ss.precision( GetValuePrecision() );
- ss << std::fixed << value;
- mValueTextView.SetText( ss.str() );
- TextStyle style;
- style.SetTextColor( GetPopupTextColor() );
- mValueTextView.SetStyleToCurrentText( style, TextStyle::COLOR);
-
- if( mValueDisplay )
- {
- Font font = Font::New();
- float popupWidth = font.MeasureText( ss.str() ).x + VALUE_POPUP_MARGIN * 2.0f;
- if( popupWidth < VALUE_POPUP_MIN_WIDTH )
- {
- popupWidth = VALUE_POPUP_MIN_WIDTH;
- }
-
- mPopup.SetSize( popupWidth, VALUE_POPUP_HEIGHT );
- mValueDisplay.SetVisible( true );
-
- mValueTimer.SetInterval( VALUE_VIEW_SHOW_DURATION );
- }
- }
}
void Slider::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/slider/slider.h>
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
namespace Dali
{
*
* @return The textview created for the popup
*/
- Toolkit::TextView CreatePopupText();
+ //Toolkit::TextView CreatePopupText();
/**
* Create the value display for the slider
ImageActor mPopup; ///< Popup backing
ImageActor mPopupArrow; ///< Popup arrow backing
- Toolkit::TextView mValueTextView; //< The text value in popup
- Toolkit::TextView mHandleValueTextView; ///< The text value on handle
Vector2 mHandleLastTouchPoint; ///< The last touch point for the handle
Timer mValueTimer; ///< Timer used to hide value view
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/images/resource-image.h>
+#include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/layouts/layout-engine.h>
+#include <dali-toolkit/public-api/text/rendering/text-backend.h>
+
+using namespace Dali::Toolkit::Text;
+
+namespace
+{
+
+const unsigned int DEFAULT_RENDERING_BACKEND = 0;
+
+} // namespace
+
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+const Property::Index TextField::PROPERTY_RENDERING_BACKEND( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX );
+const Property::Index TextField::PROPERTY_PLACEHOLDER_TEXT( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 1 );
+const Property::Index TextField::PROPERTY_TEXT( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 2 );
+const Property::Index TextField::PROPERTY_CURSOR_IMAGE( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 3 );
+const Property::Index TextField::PROPERTY_PRIMARY_CURSOR_COLOR( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 4 );
+const Property::Index TextField::PROPERTY_SECONDARY_CURSOR_COLOR( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 5 );
+const Property::Index TextField::PROPERTY_ENABLE_CURSOR_BLINK( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 6 );
+const Property::Index TextField::PROPERTY_CURSOR_BLINK_INTERVAL( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 7 );
+const Property::Index TextField::PROPERTY_CURSOR_BLINK_DURATION( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 8 );
+const Property::Index TextField::PROPERTY_GRAB_HANDLE_IMAGE( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 9 );
+const Property::Index TextField::PROPERTY_DECORATION_BOUNDING_BOX( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 10 );
+
+namespace Internal
+{
+
+namespace
+{
+
+// Type registration
+BaseHandle Create()
+{
+ return Toolkit::TextField::New();
+}
+
+TypeRegistration mType( typeid(Toolkit::TextField), typeid(Toolkit::Control), Create );
+
+PropertyRegistration property01( mType, "rendering-backend", Toolkit::TextField::PROPERTY_RENDERING_BACKEND, Property::INTEGER, &TextField::SetProperty, &TextField::GetProperty );
+PropertyRegistration property02( mType, "placeholder-text", Toolkit::TextField::PROPERTY_PLACEHOLDER_TEXT, Property::STRING, &TextField::SetProperty, &TextField::GetProperty );
+PropertyRegistration property03( mType, "text", Toolkit::TextField::PROPERTY_TEXT, Property::STRING, &TextField::SetProperty, &TextField::GetProperty );
+PropertyRegistration property04( mType, "cursor-image", Toolkit::TextField::PROPERTY_CURSOR_IMAGE, Property::STRING, &TextField::SetProperty, &TextField::GetProperty );
+PropertyRegistration property05( mType, "primary-cursor-color", Toolkit::TextField::PROPERTY_PRIMARY_CURSOR_COLOR, Property::VECTOR4, &TextField::SetProperty, &TextField::GetProperty );
+PropertyRegistration property06( mType, "secondary-cursor-color", Toolkit::TextField::PROPERTY_SECONDARY_CURSOR_COLOR, Property::VECTOR4, &TextField::SetProperty, &TextField::GetProperty );
+PropertyRegistration property07( mType, "enable-cursor-blink", Toolkit::TextField::PROPERTY_ENABLE_CURSOR_BLINK, Property::BOOLEAN, &TextField::SetProperty, &TextField::GetProperty );
+PropertyRegistration property08( mType, "cursor-blink-interval", Toolkit::TextField::PROPERTY_CURSOR_BLINK_INTERVAL, Property::FLOAT, &TextField::SetProperty, &TextField::GetProperty );
+PropertyRegistration property09( mType, "cursor-blink-duration", Toolkit::TextField::PROPERTY_CURSOR_BLINK_DURATION, Property::FLOAT, &TextField::SetProperty, &TextField::GetProperty );
+PropertyRegistration property10( mType, "grab-handle-image", Toolkit::TextField::PROPERTY_GRAB_HANDLE_IMAGE, Property::STRING, &TextField::SetProperty, &TextField::GetProperty );
+PropertyRegistration property11( mType, "decoration bounding-box", Toolkit::TextField::PROPERTY_DECORATION_BOUNDING_BOX, Property::RECTANGLE, &TextField::SetProperty, &TextField::GetProperty );
+} // namespace
+
+Toolkit::TextField TextField::New()
+{
+ // Create the implementation, temporarily owned by this handle on stack
+ IntrusivePtr< TextField > impl = new TextField();
+
+ // Pass ownership to CustomActor handle
+ Toolkit::TextField handle( *impl );
+
+ // Second-phase init of the implementation
+ // This can only be done after the CustomActor connection has been made...
+ impl->Initialize();
+
+ return handle;
+}
+
+void TextField::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+ Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
+
+ if( textField )
+ {
+ TextField& impl( GetImpl( textField ) );
+
+ switch( index )
+ {
+ case Toolkit::TextField::PROPERTY_RENDERING_BACKEND:
+ {
+ unsigned int backend = value.Get< unsigned int >();
+
+ if( impl.mRenderingBackend != backend )
+ {
+ impl.mRenderingBackend = backend;
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_PLACEHOLDER_TEXT:
+ {
+ if( impl.mController )
+ {
+ //impl.mController->SetPlaceholderText( value.Get< std::string >() ); TODO
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_TEXT:
+ {
+ if( impl.mController )
+ {
+ impl.mController->SetText( value.Get< std::string >() );
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_CURSOR_IMAGE:
+ {
+ ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetCursorImage( image );
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_PRIMARY_CURSOR_COLOR:
+ {
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetColor( PRIMARY_CURSOR, value.Get< Vector4 >() );
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_SECONDARY_CURSOR_COLOR:
+ {
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetColor( SECONDARY_CURSOR, value.Get< Vector4 >() );
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_ENABLE_CURSOR_BLINK:
+ {
+ if( impl.mController )
+ {
+ //impl.mController->SetEnableCursorBlink( value.Get< bool >() ); TODO
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_CURSOR_BLINK_INTERVAL:
+ {
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetCursorBlinkInterval( value.Get< float >() );
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_CURSOR_BLINK_DURATION:
+ {
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetCursorBlinkDuration( value.Get< float >() );
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_GRAB_HANDLE_IMAGE:
+ {
+ ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetGrabHandleImage( image );
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_DECORATION_BOUNDING_BOX:
+ {
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetBoundingBox( value.Get< Rect<int> >() );
+ }
+ break;
+ }
+ }
+ }
+}
+
+Property::Value TextField::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
+
+ if( textField )
+ {
+ TextField& impl( GetImpl( textField ) );
+
+ switch( index )
+ {
+ case Toolkit::TextField::PROPERTY_RENDERING_BACKEND:
+ {
+ value = impl.mRenderingBackend;
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_PLACEHOLDER_TEXT:
+ {
+ DALI_LOG_WARNING( "UTF-8 text representation was discarded\n" );
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_TEXT:
+ {
+ DALI_LOG_WARNING( "UTF-8 text representation was discarded\n" );
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_CURSOR_IMAGE:
+ {
+ if( impl.mDecorator )
+ {
+ ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetCursorImage() );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_PRIMARY_CURSOR_COLOR:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_SECONDARY_CURSOR_COLOR:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_ENABLE_CURSOR_BLINK:
+ {
+ //value = impl.mController->GetEnableCursorBlink(); TODO
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_CURSOR_BLINK_INTERVAL:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetCursorBlinkInterval();
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_CURSOR_BLINK_DURATION:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetCursorBlinkDuration();
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_GRAB_HANDLE_IMAGE:
+ {
+ if( impl.mDecorator )
+ {
+ ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetCursorImage() );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextField::PROPERTY_DECORATION_BOUNDING_BOX:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetBoundingBox();
+ }
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
+void TextField::OnInitialize()
+{
+ mController = Text::Controller::New( *this );
+
+ mDecorator = Text::Decorator::New( *this, *mController );
+
+ mController->GetLayoutEngine().SetLayout( LayoutEngine::SINGLE_LINE_BOX );
+
+ mController->EnableTextInput( mDecorator );
+
+ // Forward input events to controller
+ EnableGestureDetection( Gesture::Tap );
+
+ // TODO - Fix TapGestureDetector to support single and double tap
+ mDoubleTapDetector = TapGestureDetector::New();
+ mDoubleTapDetector.SetTapsRequired( 2 );
+ mDoubleTapDetector.DetectedSignal().Connect( this, &TextField::OnDoubleTap );
+ mDoubleTapDetector.Attach(Self());
+
+ // Set BoundingBox to stage size if not already set.
+ if ( mDecorator->GetBoundingBox().IsEmpty() )
+ {
+ Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
+ mDecorator->SetBoundingBox( Rect<int>( 0.0f, 0.0f, stageSize.width, stageSize.height ) );
+ }
+}
+
+Vector3 TextField::GetNaturalSize()
+{
+ return mController->GetNaturalSize();
+}
+
+float TextField::GetHeightForWidth( float width )
+{
+ return mController->GetHeightForWidth( width );
+}
+
+void TextField::OnRelayout( const Vector2& size, ActorSizeContainer& container )
+{
+ if( mController->Relayout( size ) )
+ {
+ if( mDecorator )
+ {
+ mDecorator->Relayout( size );
+ }
+
+ if( !mRenderer )
+ {
+ mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
+ }
+
+ if( mRenderer )
+ {
+ Actor renderableActor = mRenderer->Render( mController->GetView() );
+
+ if( renderableActor )
+ {
+ Self().Add( renderableActor );
+ }
+ }
+ }
+}
+
+void TextField::OnTap( const TapGesture& tap )
+{
+ mController->TapEvent( tap.numberOfTaps, tap.localPoint.x, tap.localPoint.y );
+}
+
+void TextField::OnDoubleTap( Actor actor, const TapGesture& tap )
+{
+ mController->TapEvent( tap.numberOfTaps, tap.localPoint.x, tap.localPoint.y );
+}
+
+void TextField::RequestTextRelayout()
+{
+ RelayoutRequest();
+}
+
+TextField::TextField()
+: Control( ControlBehaviour( CONTROL_BEHAVIOUR_NONE ) ),
+ mRenderingBackend( DEFAULT_RENDERING_BACKEND )
+{
+}
+
+TextField::~TextField()
+{
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-field.h>
+#include <dali-toolkit/public-api/text/decorator/text-decorator.h>
+#include <dali-toolkit/public-api/text/text-control-interface.h>
+#include <dali-toolkit/public-api/text/text-controller.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * @brief A control which renders a short text string.
+ */
+class TextField : public Control, public Text::ControlInterface
+{
+public:
+
+ // Properties
+ enum
+ {
+ TEXTFIELD_PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
+ TEXTFIELD_PROPERTY_END_INDEX = TEXTFIELD_PROPERTY_START_INDEX + 1000 ///< Reserving 1000 property indices
+ };
+
+ /**
+ * @copydoc Dali::Toollkit::TextField::New()
+ */
+ static Toolkit::TextField New();
+
+ // Properties
+
+ /**
+ * Called when a property of an object of this type is set.
+ * @param[in] object The object whose property is set.
+ * @param[in] index The property index.
+ * @param[in] value The new property value.
+ */
+ static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
+
+ /**
+ * Called to retrieve a property of an object of this type.
+ * @param[in] object The object whose property is to be retrieved.
+ * @param[in] index The property index.
+ * @return The current value of the property.
+ */
+ static Property::Value GetProperty( BaseObject* object, Property::Index index );
+
+private: // From Control
+
+ /**
+ * @copydoc Control::OnInitialize()
+ */
+ virtual void OnInitialize();
+
+ /**
+ * @copydoc Control::GetNaturalSize()
+ */
+ virtual Vector3 GetNaturalSize();
+
+ /**
+ * @copydoc Control::GetHeightForWidth()
+ */
+ virtual float GetHeightForWidth( float width );
+
+ /**
+ * @copydoc Control::OnInitialize()
+ */
+ virtual void OnRelayout( const Vector2& size, ActorSizeContainer& container );
+
+ /**
+ * @copydoc Control::OnTap()
+ */
+ virtual void OnTap( const TapGesture& tap );
+
+ /**
+ * TODO - Fix TapGestureDetector to support single and double tap
+ */
+ void OnDoubleTap( Actor actor, const TapGesture& tap );
+
+ /**
+ * @copydoc Text::ControlInterface::RequestTextRelayout()
+ */
+ virtual void RequestTextRelayout();
+
+private: // Implementation
+
+ /**
+ * Construct a new TextField.
+ */
+ TextField();
+
+ /**
+ * A reference counted object may only be deleted by calling Unreference()
+ */
+ virtual ~TextField();
+
+private:
+
+ // Undefined copy constructor and assignment operators
+ TextField(const TextField&);
+ TextField& operator=(const TextField& rhs);
+
+private: // Data
+
+ Text::ControllerPtr mController;
+ Text::RendererPtr mRenderer;
+ Text::DecoratorPtr mDecorator;
+
+ TapGestureDetector mDoubleTapDetector;
+
+ unsigned int mRenderingBackend;
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Toolkit::Internal::TextField& GetImpl( Toolkit::TextField& textField )
+{
+ DALI_ASSERT_ALWAYS(textField);
+
+ Dali::RefObject& handle = textField.GetImplementation();
+
+ return static_cast<Toolkit::Internal::TextField&>(handle);
+}
+
+inline const Toolkit::Internal::TextField& GetImpl( const Toolkit::TextField& textField )
+{
+ DALI_ASSERT_ALWAYS(textField);
+
+ const Dali::RefObject& handle = textField.GetImplementation();
+
+ return static_cast<const Toolkit::Internal::TextField&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/controls/text-controls/text-label-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/type-registry.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/layouts/layout-engine.h>
+#include <dali-toolkit/public-api/text/rendering/text-backend.h>
+
+using Dali::Toolkit::Text::LayoutEngine;
+using Dali::Toolkit::Text::Backend;
+
+namespace
+{
+
+const unsigned int DEFAULT_RENDERING_BACKEND = 0;
+
+} // namespace
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+const Property::Index TextLabel::PROPERTY_RENDERING_BACKEND( Internal::TextLabel::TEXTLABEL_PROPERTY_START_INDEX );
+const Property::Index TextLabel::PROPERTY_TEXT( Internal::TextLabel::TEXTLABEL_PROPERTY_START_INDEX + 1 );
+const Property::Index TextLabel::PROPERTY_MULTI_LINE( Internal::TextLabel::TEXTLABEL_PROPERTY_START_INDEX + 2 );
+
+namespace Internal
+{
+
+namespace
+{
+
+// Type registration
+BaseHandle Create()
+{
+ return Toolkit::TextLabel::New();
+}
+
+TypeRegistration mType( typeid(Toolkit::TextLabel), typeid(Toolkit::Control), Create );
+
+PropertyRegistration property1( mType, "rendering-backend", Toolkit::TextLabel::PROPERTY_RENDERING_BACKEND, Property::INTEGER, &TextLabel::SetProperty, &TextLabel::GetProperty );
+PropertyRegistration property2( mType, "text", Toolkit::TextLabel::PROPERTY_TEXT, Property::STRING, &TextLabel::SetProperty, &TextLabel::GetProperty );
+PropertyRegistration property3( mType, "multi-line", Toolkit::TextLabel::PROPERTY_MULTI_LINE, Property::STRING, &TextLabel::SetProperty, &TextLabel::GetProperty );
+
+} // namespace
+
+Toolkit::TextLabel TextLabel::New()
+{
+ // Create the implementation, temporarily owned by this handle on stack
+ IntrusivePtr< TextLabel > impl = new TextLabel();
+
+ // Pass ownership to CustomActor handle
+ Toolkit::TextLabel handle( *impl );
+
+ // Second-phase init of the implementation
+ // This can only be done after the CustomActor connection has been made...
+ impl->Initialize();
+
+ return handle;
+}
+
+void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+ Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) );
+
+ if( label )
+ {
+ TextLabel& impl( GetImpl( label ) );
+ switch( index )
+ {
+ case Toolkit::TextLabel::PROPERTY_RENDERING_BACKEND:
+ {
+ unsigned int backend = value.Get< int >();
+
+ if( impl.mRenderingBackend != backend )
+ {
+ impl.mRenderingBackend = static_cast< unsigned int >( backend );
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextLabel::PROPERTY_TEXT:
+ {
+ if( impl.mController )
+ {
+ impl.mController->SetText( value.Get< std::string >() );
+ }
+ break;
+ }
+ case Toolkit::TextLabel::PROPERTY_MULTI_LINE:
+ {
+ if( impl.mController )
+ {
+ LayoutEngine::Layout layout = value.Get< bool >() ? LayoutEngine::MULTI_LINE_BOX : LayoutEngine::SINGLE_LINE_BOX;
+ impl.mController->GetLayoutEngine().SetLayout( layout );
+ }
+ break;
+ }
+ }
+ }
+}
+
+Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) );
+
+ if( label )
+ {
+ TextLabel& impl( GetImpl( label ) );
+ switch( index )
+ {
+ case Toolkit::TextLabel::PROPERTY_RENDERING_BACKEND:
+ {
+ value = impl.mRenderingBackend;
+ break;
+ }
+
+ case Toolkit::TextLabel::PROPERTY_TEXT:
+ {
+ DALI_LOG_WARNING( "UTF-8 text representation was discarded\n" );
+ break;
+ }
+
+ case Toolkit::TextLabel::PROPERTY_MULTI_LINE:
+ {
+ if( impl.mController )
+ {
+ value = impl.mController->GetLayoutEngine().GetLayout();
+ }
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
+void TextLabel::OnInitialize()
+{
+ mController = Text::Controller::New( *this );
+}
+
+Vector3 TextLabel::GetNaturalSize()
+{
+ return mController->GetNaturalSize();
+}
+
+float TextLabel::GetHeightForWidth( float width )
+{
+ return mController->GetHeightForWidth( width );
+}
+
+void TextLabel::OnRelayout( const Vector2& size, ActorSizeContainer& container )
+{
+ if( mController->Relayout( size ) )
+ {
+ if( !mRenderer )
+ {
+ mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
+ }
+
+ if( mRenderer )
+ {
+ Actor renderableActor = mRenderer->Render( mController->GetView() );
+
+ if( renderableActor )
+ {
+ Self().Add( renderableActor );
+ }
+ }
+ }
+}
+
+void TextLabel::RequestTextRelayout()
+{
+ RelayoutRequest();
+}
+
+TextLabel::TextLabel()
+: Control( ControlBehaviour( CONTROL_BEHAVIOUR_NONE ) ),
+ mRenderingBackend( DEFAULT_RENDERING_BACKEND )
+{
+}
+
+TextLabel::~TextLabel()
+{
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
+#include <dali-toolkit/public-api/text/text-controller.h>
+#include <dali-toolkit/public-api/text/rendering/text-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * @brief A control which renders a short text string.
+ */
+class TextLabel : public Control, public Text::ControlInterface
+{
+public:
+
+ // Properties
+ enum
+ {
+ TEXTLABEL_PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
+ TEXTLABEL_PROPERTY_END_INDEX = TEXTLABEL_PROPERTY_START_INDEX + 1000 ///< Reserving 1000 property indices
+ };
+
+ /**
+ * @copydoc Dali::Toollkit::TextLabel::New()
+ */
+ static Toolkit::TextLabel New();
+
+ // Properties
+
+ /**
+ * Called when a property of an object of this type is set.
+ * @param[in] object The object whose property is set.
+ * @param[in] index The property index.
+ * @param[in] value The new property value.
+ */
+ static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
+
+ /**
+ * Called to retrieve a property of an object of this type.
+ * @param[in] object The object whose property is to be retrieved.
+ * @param[in] index The property index.
+ * @return The current value of the property.
+ */
+ static Property::Value GetProperty( BaseObject* object, Property::Index index );
+
+private: // From Control
+
+ /**
+ * @copydoc Control::OnInitialize()
+ */
+ virtual void OnInitialize();
+
+ /**
+ * @copydoc Control::OnInitialize()
+ */
+ virtual void OnRelayout( const Vector2& size, ActorSizeContainer& container );
+
+ /**
+ * @copydoc Control::GetNaturalSize()
+ */
+ virtual Vector3 GetNaturalSize();
+
+ /**
+ * @copydoc Control::GetHeightForWidth()
+ */
+ virtual float GetHeightForWidth( float width );
+
+ /**
+ * @copydoc Text::ControlInterface::RequestTextRelayout()
+ */
+ virtual void RequestTextRelayout();
+
+private: // Implementation
+
+ /**
+ * Construct a new TextLabel.
+ */
+ TextLabel();
+
+ /**
+ * A reference counted object may only be deleted by calling Unreference()
+ */
+ virtual ~TextLabel();
+
+private:
+
+ // Undefined copy constructor and assignment operators
+ TextLabel(const TextLabel&);
+ TextLabel& operator=(const TextLabel& rhs);
+
+private: // Data
+
+ Text::ControllerPtr mController;
+ Text::RendererPtr mRenderer;
+
+ unsigned int mRenderingBackend;
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Toolkit::Internal::TextLabel& GetImpl( Toolkit::TextLabel& textLabel )
+{
+ DALI_ASSERT_ALWAYS(textLabel);
+
+ Dali::RefObject& handle = textLabel.GetImplementation();
+
+ return static_cast<Toolkit::Internal::TextLabel&>(handle);
+}
+
+inline const Toolkit::Internal::TextLabel& GetImpl( const Toolkit::TextLabel& textLabel )
+{
+ DALI_ASSERT_ALWAYS(textLabel);
+
+ const Dali::RefObject& handle = textLabel.GetImplementation();
+
+ return static_cast<const Toolkit::Internal::TextLabel&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali-toolkit/internal/controls/text-input/text-input-decorator-impl.h>
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/adaptor-framework/clipboard.h>
-#include <dali/public-api/common/stage.h>
-#include <dali/public-api/events/pan-gesture.h>
-#include <dali/public-api/object/property-notification.h>
-#include <dali/integration-api/debug.h>
-#include <dali/public-api/images/resource-image.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-input/text-input-handles-impl.h>
-
-using namespace Dali;
-
-namespace
-{
-#if defined(DEBUG_ENABLED)
- Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TEXT_INPUT_DECORATOR");
-#endif
-
-const Vector3 DEFAULT_SELECTION_HANDLE_SIZE( 51.0f, 79.0f, 0.0f );
-const float TOP_HANDLE_TOP_OFFSET(-1.5f); // Offset between top handle and cutCopyPaste pop-up
-const float BOTTOM_HANDLE_BOTTOM_OFFSET(1.5f); // Offset between bottom handle and cutCopyPaste pop-up
-const float UI_Z_OFFSET( 0.2f ); // Text Selection Handles/Cursor z-offset.
-const Vector3 UI_OFFSET(0.0f, 0.0f, UI_Z_OFFSET); // Text Selection Handles/Cursor offset.
-const char* DEFAULT_CURSOR( DALI_IMAGE_DIR "cursor.png" );
-const Vector4 DEFAULT_CURSOR_IMAGE_9_BORDER( 2.0f, 2.0f, 2.0f, 2.0f );
-const std::size_t CURSOR_BLINK_INTERVAL = 500; // Cursor blink interval
-const float CURSOR_THICKNESS(6.0f);
-const Degree CURSOR_ANGLE_OFFSET(2.0f); // Offset from the angle
-
-const unsigned int SCROLL_TICK_INTERVAL = 50u;
-const float SCROLL_THRESHOLD = 10.f;
-const float SCROLL_SPEED = 15.f;
-
-/**
- * Whether the given position plus the cursor size offset is inside the given boundary.
- *
- * @param[in] position The given position.
- * @param[in] cursorSize The cursor size.
- * @param[in] controlSize The given boundary.
- * @param[in] threshold imaginary indent around boundary that will trigger the position to be outside of control.
- *
- * @return whether the given position is inside the given boundary.
- */
-bool IsPositionWithinControl( const Vector3& position, const Size& cursorSize, const Vector3& controlSize, const Vector2 threshold = Vector2::ZERO )
-{
- return ( position.x >= -Math::MACHINE_EPSILON_1000 + threshold.x ) &&
- ( position.x <= controlSize.width - threshold.x + Math::MACHINE_EPSILON_1000 ) &&
- ( position.y - cursorSize.height >= -Math::MACHINE_EPSILON_1000 + threshold.y ) &&
- ( position.y <= controlSize.height + Math::MACHINE_EPSILON_1000 - threshold.y);
-}
-
-}
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-Decorator::Decorator( TextViewCharacterPositioning& textViewManager, TextInputTextStyle& textStyle ):
- mTextViewCharacterPositioning( textViewManager ),
- mTextStyle( textStyle ),
- mSelectionHandleOnePosition(0),
- mSelectionHandleTwoPosition(0),
- mGrabHandlePosition(0),
- mCursorPosition( 0 ),
- mTextHighlight( textViewManager ),
- mCursorBlinkStatus( true ),
- mCursorVisibility( true ),
- mCursorRTLEnabled( false ),
- mIsGrabHandleInScrollArea( false ),
- mIsCursorInScrollArea( false ),
- mGrabHandleVisibility( false ),
- mGrabHandleEnabled( true )
-{
-}
-
-Decorator::~Decorator()
-{
-}
-
-/**
- * Bounding Box
- */
-void Decorator::SetBoundingBox( const Rect<float>& boundingRectangle )
-{
- // Convert to world coordinates and store as a Vector4 to be compatible with Property Notifications.
- Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
-
- const float originX = boundingRectangle.x - 0.5f * stageSize.width;
- const float originY = boundingRectangle.y - 0.5f * stageSize.height;
-
- const Vector4 boundary( originX,
- originY,
- originX + boundingRectangle.width,
- originY + boundingRectangle.height );
-
- mBoundingRectangleWorldCoordinates = boundary;
-}
-
-Vector4 Decorator::GetBoundingBox() const
-{
- return mBoundingRectangleWorldCoordinates;
-}
-
-/**
- * Selection Handles
- */
-void Decorator::OnHandlePan(Actor actor, const PanGesture& gesture)
-{
- Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
- Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
-
- switch (gesture.state)
- {
- case Gesture::Started:
- // fall through so code not duplicated
- case Gesture::Continuing:
- {
- if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleOne() )
- {
- MoveSelectionHandle( selectionHandleOne, mSelectionHandleOneActualPosition, mSelectionHandleOnePosition, gesture.displacement );
- HidePopUp();
- }
- else if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleTwo() )
- {
- MoveSelectionHandle( selectionHandleTwo, mSelectionHandleTwoActualPosition, mSelectionHandleTwoPosition, gesture.displacement );
- HidePopUp();
- }
- else if ( actor.GetParent() == mTextInputHandles.GetGrabHandle() )
- {
- SetCursorVisibility( true );
- ShowGrabHandle( mGrabHandleVisibility && mIsGrabHandleInScrollArea );
- MoveGrabHandle( gesture.displacement );
- HidePopUp(); // Do not show popup while handle is moving
- }
- }
- break;
-
- case Gesture::Finished:
- {
- // Revert back to non-pressed selection handle images
- if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleOne() )
- {
- mSelectionHandleOneActualPosition = MoveSelectionHandle( selectionHandleOne, mSelectionHandleOneActualPosition, mSelectionHandleOnePosition, gesture.displacement );
- ShowPopupCutCopyPaste();
- }
- else if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleTwo() )
- {
- mSelectionHandleTwoActualPosition = MoveSelectionHandle( selectionHandleTwo, mSelectionHandleTwoActualPosition, mSelectionHandleTwoPosition, gesture.displacement );
- ShowPopupCutCopyPaste();
- }
- else if ( actor.GetParent() == mTextInputHandles.GetGrabHandle() )
- {
- MoveGrabHandle( gesture.displacement );
- SetCursorVisibility( true );
- ShowPopupCutCopyPaste();
- }
- }
- break;
- default:
- break;
- }
-}
-
-void Decorator::CreateSelectionHandles( Actor targetParent )
-{
- if ( !mPanGestureDetector )
- {
- mPanGestureDetector = PanGestureDetector::New();
- mPanGestureDetector.DetectedSignal().Connect(this, &Decorator::OnHandlePan);
- }
-
- if ( !mTextInputHandles.GetSelectionHandleOne() )
- {
- mTextInputHandles.CreateSelectionHandles();
-
- mTextInputHandles.AttachSelectionHandlesToGivenPanGesture( mPanGestureDetector );
-
- targetParent.Add( mTextInputHandles.GetSelectionHandleOne() );
- targetParent.Add( mTextInputHandles.GetSelectionHandleTwo() );
-
- SetUpHandlePropertyNotifications();
- }
-}
-
-void Decorator::RemoveSelectionHandles()
-{
- mTextInputHandles.DestorySelectionHandles();
-}
-
-Vector3 Decorator::GetSelectionHandleSize()
-{
- return DEFAULT_SELECTION_HANDLE_SIZE;
-}
-
-std::size_t Decorator::GetHandleOnePosition() const
-{
- return mSelectionHandleOnePosition;
-}
-
-std::size_t Decorator::GetHandleTwoPosition() const
-{
- return mSelectionHandleTwoPosition;
-}
-
-Vector3 Decorator::PositionSelectionHandle( Actor selectionHandle, std::size_t position )
-{
- bool direction(false);
- Vector3 alternatePosition;
- bool alternatePositionValid(false);
-
- Vector3 actualPositionOfSelectionHandle = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( position, direction, alternatePosition,alternatePositionValid );
-
- return PositionSelectionHandle( selectionHandle, actualPositionOfSelectionHandle, position );
-
-}
-
-Vector3 Decorator::PositionSelectionHandle( Actor selectionHandle, Vector3& actualPosition, std::size_t position )
-{
- const Vector3 DEFAULT_HANDLE_OFFSET(0.0f, -5.0f, 0.0f);
-
- selectionHandle.SetPosition( actualPosition += DEFAULT_HANDLE_OFFSET );
-
- return actualPosition;
-}
-
-void Decorator::SetSelectionHandlesVisibility(bool visible )
-{
- mTextInputHandles.SetSelectionHandleOneVisibility( visible );
- mTextInputHandles.SetSelectionHandleTwoVisibility( visible );
-}
-
-void Decorator::PositionSelectionHandles( std::size_t start, std::size_t end )
-{
- mSelectionHandleOnePosition = start;
- mSelectionHandleTwoPosition = end;
-
- mTextViewCharacterPositioning.UpdateTextLayoutInfo();
-
- mSelectionHandleOneActualPosition = PositionSelectionHandle( mTextInputHandles.GetSelectionHandleOne(), mSelectionHandleOnePosition );
- mSelectionHandleTwoActualPosition = PositionSelectionHandle( mTextInputHandles.GetSelectionHandleTwo(), mSelectionHandleTwoPosition );
-}
-
-Vector3 Decorator::MoveSelectionHandle( Actor selectionHandle,
- Vector3& actualSelectionHandlePosition,
- std::size_t& currentSelectionHandlePosition,
- const Vector2& displacement )
-{
- Vector3 actualHandlePosition;
- actualSelectionHandlePosition.x += displacement.x * selectionHandle.GetCurrentScale().x;
- actualSelectionHandlePosition.y += displacement.y * selectionHandle.GetCurrentScale().y;
-
- // Selection handles should jump to the nearest character
- std::size_t newHandlePosition = 0;
- newHandlePosition = mTextViewCharacterPositioning.ReturnClosestIndex( actualSelectionHandlePosition.GetVectorXY() );
-
- bool direction(false);
- Vector3 alternatePosition;
- bool alternatePositionValid(false);
- actualHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandlePosition,direction, alternatePosition, alternatePositionValid );
-
- bool handleVisible = true;
-
- if ( handleVisible && // Ensure the handle is visible.
- ( newHandlePosition != currentSelectionHandlePosition ) && // Ensure the handle has moved.
- ( newHandlePosition != mSelectionHandleTwoPosition ) && // Ensure new handle position not the same position as an existing handle.
- ( newHandlePosition != mSelectionHandleOnePosition ) )
- {
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::MoveSelectionHandle Handle visible and moved]\n");
-
- currentSelectionHandlePosition = newHandlePosition;
-
- PositionSelectionHandle( selectionHandle, actualHandlePosition, newHandlePosition );
-
- ShowUpdatedHighlight();
-
- // Set Active Style to that of first character in selection
- std::size_t firstHandleInSelection = std::min( mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
-
- const TextStyle inputStyle = mTextViewCharacterPositioning.GetStyleAt( firstHandleInSelection );
- mTextStyle.SetInputStyle( inputStyle );
- }
- return actualHandlePosition; // Returns Handle position passed in if new value not assigned.
-}
-
-/**
- * GrabHandle
- */
-void Decorator::PositionGrabHandle( std::size_t positionInText )
-{
- bool direction(false);
- Vector3 alternatePosition;
- bool alternatePositionValid(false);
-
- mGrabHandlePosition = positionInText;
-
- mTextViewCharacterPositioning.UpdateTextLayoutInfo();
- mActualGrabHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( positionInText, direction, alternatePosition,alternatePositionValid );
-
- mTextInputHandles.GetGrabHandle().SetPosition( mActualGrabHandlePosition );
-}
-
-void Decorator::MoveGrabHandle( const Vector2& displacement /*, std::size_t currentHandlePosition */)
-{
- mActualGrabHandlePosition.x += displacement.x;
- mActualGrabHandlePosition.y += displacement.y;
-
- // Grab handle should jump to the nearest character and take cursor with it
- std::size_t newHandlePosition = mTextViewCharacterPositioning.ReturnClosestIndex( mActualGrabHandlePosition.GetVectorXY() );
-
- Vector3 actualHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandlePosition );
-
- bool handleVisible = true;
-
- if( ( newHandlePosition != mGrabHandlePosition ) && // Only redraw cursor and do updates if position changed
- ( handleVisible ) )// and the new position is visible (if scroll is not enabled, it's always true).
- {
- mActualGrabHandlePosition = actualHandlePosition;
- mTextInputHandles.GetGrabHandle().SetPosition( mActualGrabHandlePosition );
-
- //PositionGrabHandle( newHandlePosition );
- mGrabHandlePosition = newHandlePosition;
- SetCurrentCursorPosition( mGrabHandlePosition );
- DrawCursor( mGrabHandlePosition );
-
- const std::size_t cursorPosition = GetCurrentCursorPosition();
-
- // Let keyboard know the new cursor position so can 're-capture' for prediction.
- mCursorRePositionedSignal.Emit();
-
- // Set Input Style to that of cursor position
- if ( !mTextViewCharacterPositioning.IsStyledTextEmpty() && ( cursorPosition > 0 ) )
- {
- DALI_ASSERT_DEBUG( ( 0 <= cursorPosition-1 ) && ( cursorPosition-1 < mTextViewCharacterPositioning.StyledTextSize() ) );
- }
- }
-}
-
-void Decorator::ShowGrabHandle( bool visible )
-{
- mGrabHandleVisibility = visible;
- mTextInputHandles.SetGrabHandleVisibility( visible );
-}
-
-void Decorator::CreateGrabHandle( Actor targetParent )
-{
- if ( !mPanGestureDetector )
- {
- mPanGestureDetector = PanGestureDetector::New();
- mPanGestureDetector.DetectedSignal().Connect(this, &Decorator::OnHandlePan);
- }
-
- if ( !mTextInputHandles.GetGrabHandle() )
- {
- mTextInputHandles.CreateGrabHandle();
- mTextInputHandles.AttachGrabHandleToGivenPanGesture( mPanGestureDetector );
- targetParent.Add( mTextInputHandles.GetGrabHandle() );
- }
-}
-
-void Decorator::SetGrabHandleImage( Image image )
-{
- mTextInputHandles.SetGrabHandleImage( image );
-}
-
-void Decorator::EnableGrabHandle( bool toggle)
-{
- // enables grab handle with will in turn de-activate magnifier
- mGrabHandleEnabled = toggle;
-}
-
-bool Decorator::IsGrabHandleEnabled()
-{
- // if false then magnifier will be shown instead.
- return mGrabHandleEnabled;
-}
-
-/**
- * Cursor
- */
-std::size_t Decorator::GetCurrentCursorPosition() const
-{
- return mCursorPosition;
-}
-
-void Decorator::SetCurrentCursorPosition( std::size_t newCursorPosition )
-{
- mCursorPosition = newCursorPosition;
-}
-
-void Decorator::SetCursorVisibility( bool visible )
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::SetCursorVisibility[%s]\n", ( visible )?"true":"false");
-
- mCursorVisibility = visible;
- mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea );
- mCursorRTL.SetVisible( mCursorVisibility && mCursorRTLEnabled );
-}
-
-void Decorator::DrawCursor(const std::size_t nthChar)
-{
- std::size_t cursorPosition = GetCurrentCursorPosition();
-
- // Get height of cursor and set its size
- Size size( CURSOR_THICKNESS, 0.0f );
-
- Vector2 min, max; // out parameters for GetRowRectFromCharacterPosition
- size.height = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mTextViewCharacterPositioning.GetVisualPosition( cursorPosition ), min, max ).height;
-
- mCursor.SetSize(size);
-
- // If the character is italic then the cursor also tilts.
- if ( !mTextViewCharacterPositioning.IsStyledTextEmpty() && ( cursorPosition > 0 ) )
- {
- DALI_ASSERT_DEBUG( ( 0 <= cursorPosition-1 ) && ( cursorPosition-1 < mTextViewCharacterPositioning.StyledTextSize() ) );
- const TextStyle styleAtCursor = mTextViewCharacterPositioning.GetStyleAt( cursorPosition-1 );
- mCursor.SetRotation( styleAtCursor.IsItalicsEnabled() ? Degree( styleAtCursor.GetItalicsAngle() - CURSOR_ANGLE_OFFSET ) : Degree( 0.f ), Vector3::ZAXIS );
- }
-
- DALI_ASSERT_DEBUG( cursorPosition <= mTextViewCharacterPositioning.GetNumberOfCharactersInText() );
- if ( ( cursorPosition <= mTextViewCharacterPositioning.GetNumberOfCharactersInText() ) )
- {
- Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
- bool altPositionValid( false ); // Alternate cursor validity flag.
- bool directionRTL( false ); // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
- Vector3 position = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorPosition, directionRTL, altPosition, altPositionValid );
-
- SetAltCursorEnabled( altPositionValid );
-
- mCursor.SetPosition( position + UI_OFFSET );
- }
-}
-
-void Decorator::SetAltCursorEnabled( bool enabled )
-{
- mCursorRTLEnabled = enabled;
- mCursorRTL.SetVisible( mCursorVisibility && mCursorRTLEnabled );
-}
-
-void Decorator::SetCursorImage(Dali::Image image, const Vector4& border )
-{
- DALI_ASSERT_DEBUG ( image && "Create cursor image invalid")
-
- if ( image )
- {
- mCursor.SetImage( image );
- mCursor.SetNinePatchBorder( border );
- }
-}
-
-void Decorator::SetRTLCursorImage( Image image, const Vector4& border )
-{
- DALI_ASSERT_DEBUG ( image && "Create cursor image invalid")
-
- if ( image )
- {
- mCursorRTL.SetImage( image );
- mCursorRTL.SetNinePatchBorder( border );
- }
-}
-
-ImageActor Decorator::CreateCursor( Image cursorImage, const Vector4& border, const std::string& cursorName )
-{
- ImageActor cursor;
-
- if ( cursorImage )
- {
- cursor = ImageActor::New( cursorImage );
- }
- else
- {
- cursor = ImageActor::New( ResourceImage::New( DEFAULT_CURSOR ) );
- }
-
- cursor.SetStyle(ImageActor::STYLE_NINE_PATCH);
- cursor.SetNinePatchBorder( border );
- cursor.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER);
- cursor.SetVisible(false);
- cursor.SetName( cursorName );
- return cursor;
-}
-
-void Decorator::CreateCursors( Actor targetParent )
-{
- Image mCursorImage = ResourceImage::New( DEFAULT_CURSOR );
- mCursor = CreateCursor (mCursorImage, DEFAULT_CURSOR_IMAGE_9_BORDER , "mainCursor");
- mCursorRTL = CreateCursor ( mCursorImage, DEFAULT_CURSOR_IMAGE_9_BORDER, "rtlCursor");
- targetParent.Add( mCursor );
- targetParent.Add( mCursorRTL );
-}
-
-Size Decorator::GetCursorSizeAt( std::size_t positionWithinTextToGetCursorSize )
-{
- std::size_t visualPosition = mTextViewCharacterPositioning.GetVisualPosition( positionWithinTextToGetCursorSize );
-
- Vector2 min, max;
-
- const Size cursorSize( CURSOR_THICKNESS,
- mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( visualPosition, min, max ).height );
-
- return cursorSize;
-}
-
-void Decorator::StartCursorBlinkTimer()
-{
- if ( !mCursorBlinkTimer )
- {
- mCursorBlinkTimer = Timer::New( CURSOR_BLINK_INTERVAL );
- mCursorBlinkTimer.TickSignal().Connect( this, &Decorator::OnCursorBlinkTimerTick );
- }
-
- if ( !mCursorBlinkTimer.IsRunning() )
- {
- mCursorBlinkTimer.Start();
- }
-}
-
-void Decorator::StopCursorBlinkTimer()
-{
- if ( mCursorBlinkTimer )
- {
- mCursorBlinkTimer.Stop();
- }
-}
-
-bool Decorator::OnCursorBlinkTimerTick()
-{
- // Cursor blinking
- mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea && mCursorBlinkStatus );
- if ( mCursorRTLEnabled )
- {
- mCursorRTL.SetVisible( mCursorVisibility && mIsCursorInScrollArea && mCursorBlinkStatus );
- }
- mCursorBlinkStatus = !mCursorBlinkStatus;
-
- return true;
-}
-
-/**
- * Highlight
- */
-void Decorator::ShowUpdatedHighlight()
-{
- Toolkit::TextView::TextLayoutInfo textLayoutInfo = mTextViewCharacterPositioning.GetLayoutInfo();
- TextHighlight::HighlightInfo highlightInfo = mTextHighlight.CalculateHighlightInfo( mSelectionHandleOnePosition, mSelectionHandleTwoPosition, textLayoutInfo );
-
- // Clamp highlightInfo so they don't exceed the boundary of the control.
- const Vector3& controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize();
- highlightInfo.Clamp2D( Vector2::ZERO, Vector2(controlSize.x, controlSize.y) );
-
- mTextHighlight.UpdateHighlight( highlightInfo );
-}
-
-void Decorator::CreateHighlight( Actor parent )
-{
- DALI_ASSERT_DEBUG( parent && "Highlight target parent does not exist" );
-
- if ( !mHighlightMeshActor )
- {
- mHighlightMeshActor = MeshActor::New( mTextHighlight.CreateHighLightMesh() );
- mHighlightMeshActor.SetName( "HighlightMeshActor" );
- parent.Add( mHighlightMeshActor );
- }
-}
-
-void Decorator::RemoveHighlight()
-{
- if ( mHighlightMeshActor )
- {
- mHighlightMeshActor.Unparent();
- mHighlightMeshActor.Reset();
- // NOTE: We cannot dereference mHighlightMesh, due to a how the scene-graph MeshRenderer uses the Mesh data.
- }
-}
-
-void Decorator::HighlightVisibility( bool visiblility )
-{
- if ( mHighlightMeshActor )
- {
- mHighlightMeshActor.SetVisible( visiblility );
- }
-}
-
-/**
- * Callbacks connected to be Property notifications for Boundary checking.
- */
-// Note If PropertyNotification signal definition included Actor we would not need to duplicate functions.
-void Decorator::OnHandleOneLeavesBoundary( PropertyNotification& source)
-{
- mTextInputHandles.GetSelectionHandleOne().SetOpacity(0.0f);
-}
-
-void Decorator::OnHandleOneWithinBoundary(PropertyNotification& source)
-{
- mTextInputHandles.GetSelectionHandleOne().SetOpacity(1.0f);
-}
-
-void Decorator::OnHandleTwoLeavesBoundary( PropertyNotification& source)
-{
- mTextInputHandles.GetSelectionHandleTwo().SetOpacity(0.0f);
-}
-
-void Decorator::OnHandleTwoWithinBoundary(PropertyNotification& source)
-{
- mTextInputHandles.GetSelectionHandleTwo().SetOpacity(1.0f);
-}
-
-void Decorator::OnLeftBoundaryExceeded(PropertyNotification& source)
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextInputDecorationLayouter::OnLeftBoundaryExceeded\n");
- Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
- selectionHandleOne.SetScale( -1.0f, 1.0f, 1.0f );
- selectionHandleOne.SetAnchorPoint( AnchorPoint::TOP_LEFT);
-}
-
-void Decorator::OnReturnToLeftBoundary(PropertyNotification& source)
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextInputDecorationLayouter::OnReturnToLeftBoundary\n");
- Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
- selectionHandleOne.SetScale( 1.0f, 1.0f, 1.0f );
- selectionHandleOne.SetAnchorPoint( AnchorPoint::TOP_RIGHT);
-}
-
-void Decorator::OnRightBoundaryExceeded(PropertyNotification& source)
-{
- Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
- selectionHandleTwo.SetScale( -1.0f, 1.0f, 1.0f );
- selectionHandleTwo.SetAnchorPoint( AnchorPoint::TOP_RIGHT);
-}
-
-void Decorator::OnReturnToRightBoundary(PropertyNotification& source)
-{
- Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
- selectionHandleTwo.SetScale( 1.0f, 1.0f, 1.0f );
- selectionHandleTwo.SetAnchorPoint( AnchorPoint::TOP_LEFT);
-}
-
-void Decorator::SetUpHandlePropertyNotifications()
-{
- /* Property notifications for handles exceeding the boundary and returning back within boundary */
-
- Vector3 handlesize = GetSelectionHandleSize();
-
- Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
- Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
-
- // Exceeding horizontal boundary
- PropertyNotification leftNotification = selectionHandleOne.AddPropertyNotification( Actor::Property::WorldPositionX, LessThanCondition( mBoundingRectangleWorldCoordinates.x + handlesize.x) );
- leftNotification.NotifySignal().Connect( this, &Decorator::OnLeftBoundaryExceeded );
-
- PropertyNotification rightNotification = selectionHandleTwo.AddPropertyNotification( Actor::Property::WorldPositionX, GreaterThanCondition( mBoundingRectangleWorldCoordinates.z - handlesize.x ) );
- rightNotification.NotifySignal().Connect( this, &Decorator::OnRightBoundaryExceeded );
-
- // Within horizontal boundary
- PropertyNotification leftLeaveNotification = selectionHandleOne.AddPropertyNotification( Actor::Property::WorldPositionX, GreaterThanCondition( mBoundingRectangleWorldCoordinates.x + 2*handlesize.x ) );
- leftLeaveNotification.NotifySignal().Connect( this, &Decorator::OnReturnToLeftBoundary );
-
- PropertyNotification rightLeaveNotification = selectionHandleTwo.AddPropertyNotification( Actor::Property::WorldPositionX, LessThanCondition( mBoundingRectangleWorldCoordinates.z - 2*handlesize.x ) );
- rightLeaveNotification.NotifySignal().Connect( this, &Decorator::OnReturnToRightBoundary );
-
- // Exceeding vertical boundary
- PropertyNotification verticalExceedNotificationOne = selectionHandleOne.AddPropertyNotification( Actor::Property::WorldPositionY,
- OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalExceedNotificationOne.NotifySignal().Connect( this, &Decorator::OnHandleOneLeavesBoundary );
-
- PropertyNotification verticalExceedNotificationTwo = selectionHandleTwo.AddPropertyNotification( Actor::Property::WorldPositionY,
- OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalExceedNotificationTwo.NotifySignal().Connect( this, &Decorator::OnHandleTwoLeavesBoundary );
-
- // Within vertical boundary
- PropertyNotification verticalWithinNotificationOne = selectionHandleOne.AddPropertyNotification( Actor::Property::WorldPositionY,
- InsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalWithinNotificationOne.NotifySignal().Connect( this, &Decorator::OnHandleOneWithinBoundary );
-
- PropertyNotification verticalWithinNotificationTwo = selectionHandleTwo.AddPropertyNotification( Actor::Property::WorldPositionY,
- InsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalWithinNotificationTwo.NotifySignal().Connect( this, &Decorator::OnHandleTwoWithinBoundary );
-}
-
-/**
- * PopUp
- */
-Vector3 Decorator::PositionOfPopUpRelativeToSelectionHandles()
-{
- Vector3 position;
- Vector2 min, max;
- Vector3 topHandle;
- Size rowSize;
-
- // When text is selected, show popup above top handle (and text), or below bottom handle.
-
- // topHandle: referring to the top most point of the handle or the top line of selection.
- if ( mSelectionHandleTwoActualPosition.y > mSelectionHandleOneActualPosition.y ) // Handle may switch positions so calculate which is top.
- {
- topHandle = mSelectionHandleOneActualPosition;
- rowSize= mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mSelectionHandleOnePosition, min, max );
- }
- else
- {
- topHandle = mSelectionHandleTwoActualPosition;
- rowSize = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mSelectionHandleTwoPosition, min, max );
- }
- topHandle.y += TOP_HANDLE_TOP_OFFSET - rowSize.height;
- position = Vector3(topHandle.x, topHandle.y, 0.0f);
-
- return position;
-}
-
-Vector3 Decorator::AlternatePopUpPositionRelativeToSelectionHandles()
-{
- // alternativePosition: referring to the bottom most point of the handle or the bottom line of selection.
- Vector3 alternativePosition;
- alternativePosition.y = std::max ( mSelectionHandleTwoActualPosition.y , mSelectionHandleOneActualPosition.y );
- alternativePosition.y += GetSelectionHandleSize().y + mPopUpPanel.GetSize().y + BOTTOM_HANDLE_BOTTOM_OFFSET;
-
- return alternativePosition;
-}
-
-Vector3 Decorator::PositionOfPopUpRelativeToCursor()
-{
- // When no text is selected, show PopUp at position of cursor
- Vector3 position;
- Vector2 min, max;
- std::size_t cursorPosition = GetCurrentCursorPosition();
- position = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorPosition );
- const Size rowSize = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( cursorPosition, min, max );
- position.y -= rowSize.height;
-
- return position;
-}
-
-Vector3 Decorator::AlternatePopUpPositionRelativeToCursor()
-{
- std::size_t cursorPosition = GetCurrentCursorPosition();
- Vector3 alternativePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorPosition );
-
- if ( mTextInputHandles.GetGrabHandle() )
- {
- // If grab handle enabled then position pop-up below the grab handle.
- alternativePosition.y += mTextInputHandles.GetGrabHandle().GetCurrentSize().height + mPopUpPanel.GetSize().y + BOTTOM_HANDLE_BOTTOM_OFFSET ;
- }
- else
- {
- alternativePosition.y += mPopUpPanel.GetSize().y;
- }
-
- return alternativePosition;
-
-}
-
-Vector3 Decorator::PositionOfPopUpRelativeToGrabHandle()
-{
- return Vector3::ZERO;
-}
-
-void Decorator::ShowPopUp()
-{
- Vector3 position;
- Vector3 alternativePosition;
- Size rowSize;
-
- DALI_ASSERT_DEBUG( mPopUpTarget && "PopUp Target Actor does not exist" );
-
- if( mHighlightMeshActor ) // Text Selection mode
- {
- position = PositionOfPopUpRelativeToSelectionHandles();
- }
- else // Not in Text Selection mode so position relative to cursor.
- {
- position = PositionOfPopUpRelativeToCursor();
- }
-
- // reposition popup above the desired cursor position.
- mPopUpPanel.Show( mPopUpTarget, true );
- mPopUpPanel.Self().SetPosition( position );
- mPopUpPanel.PressedSignal().Connect( this, &Decorator::OnPopupButtonPressed );
-
- SetUpPopUpPositionNotifications();
- mPopUpPanel.ApplyConfinementConstraint( mBoundingRectangleWorldCoordinates );
-}
-
-void Decorator::ShowPopUp( Actor target )
-{
- mPopUpTarget = target;
- ShowPopupCutCopyPaste();
-}
-
-void Decorator::ShowPopupCutCopyPaste()
-{
- bool isAllTextSelectedAlready = ( mTextViewCharacterPositioning.StyledTextSize() == GetSelectedText().size() );
- bool isTextEmpty = mTextViewCharacterPositioning.IsStyledTextEmpty() ;
- bool isSubsetOfTextAlreadySelected = ( !isAllTextSelectedAlready ) && mHighlightMeshActor;
-
- Clipboard clipboard = Clipboard::Get();
- bool hasClipboardGotContent = clipboard.NumberOfItems();
-
- mPopUpPanel.CreateCutCopyPastePopUp( isAllTextSelectedAlready, isTextEmpty, hasClipboardGotContent, isSubsetOfTextAlreadySelected );
- ShowPopUp();
-}
-
-void Decorator::HidePopUp( bool animate, bool signalFinished )
-{
-}
-
-void Decorator::AddPopupOption(const std::string& name, const std::string& caption, const Image icon, bool finalOption)
-{
- mPopUpPanel.AddButton(name, caption, icon, finalOption);
-}
-
-void Decorator::ClearPopup()
-{
- mPopUpPanel.Clear();
-}
-
-void Decorator::PopUpLeavesVerticalBoundary( PropertyNotification& source)
-{
- Vector3 position, alternativePosition;
-
- if( mHighlightMeshActor ) // Text Selection mode
- {
- alternativePosition = AlternatePopUpPositionRelativeToSelectionHandles();
- }
- else // Not in Text Selection mode
- {
- alternativePosition = AlternatePopUpPositionRelativeToCursor();
- // if can't be positioned above, then position below row.
- }
- // reposition popup above the desired cursor position.
- mPopUpPanel.Self().SetPosition( alternativePosition );
-}
-
-void Decorator::SetUpPopUpPositionNotifications( )
-{
- // Note Property notifications ignore any set anchor point so conditions must allow for this. Default is Top Left.
-
- // Exceeding vertical boundary
- PropertyNotification verticalExceedNotificationOne = mPopUpPanel.Self().AddPropertyNotification( Actor::Property::WorldPositionY,
- OutsideCondition( mBoundingRectangleWorldCoordinates.y + mPopUpPanel.GetSize().y/2,
- mBoundingRectangleWorldCoordinates.w - mPopUpPanel.GetSize().y/2 ) );
- verticalExceedNotificationOne.NotifySignal().Connect( this, &Decorator::PopUpLeavesVerticalBoundary );
-}
-
-bool Decorator::OnPopupButtonPressed( Toolkit::Button button )
-{
- mPopUpButtonPressedSignal.Emit( button );
- return false;
-}
-
-Decorator::PressedSignal& Decorator::PopUpButtonPressedSignal()
-{
- return mPopUpButtonPressedSignal;
-}
-
-Decorator::CursorPositionedSignal& Decorator::CursorRePositionedSignal()
-{
- return mCursorRePositionedSignal;
-}
-
-/**
- * Decoration Positioning during Scrolling
- */
-void Decorator::TextViewScrolled( Toolkit::TextView textView, Vector2 scrollPosition )
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::TextViewScrolled\n");
-
- const Vector3& controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize(); // todo Could store size and only update in Control Size change.
- Size cursorSize( CURSOR_THICKNESS, 0.f );
-
- // Updates the cursor and grab handle position and visibility.
- if( mTextInputHandles.GetGrabHandle() || mCursor )
- {
- Vector2 min, max;
- size_t cursorTextPosition = GetCurrentCursorPosition();
- cursorSize.height = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( cursorTextPosition, min, max ).height;
-
- const Vector3 cursorPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorTextPosition );
-
- bool mIsCursorInScrollArea = IsPositionWithinControl( cursorPosition, cursorSize, controlSize );
- bool mIsGrabHandleInScrollArea = mIsCursorInScrollArea;
-
- Vector2 actualGrabHandlePosition = cursorPosition.GetVectorXY();
-
- if( mTextInputHandles.GetGrabHandle() )
- {
- ShowGrabHandle( mGrabHandleVisibility && mIsGrabHandleInScrollArea );
- PositionGrabHandle( cursorTextPosition );
- }
-
- if( mCursor )
- {
- mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea );
- DrawCursor( cursorTextPosition );
- mCursor.SetPosition( Vector3(actualGrabHandlePosition) + UI_OFFSET );
- }
- }
-
- Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
- Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
-
- // Updates the selection handles and highlighted text position and visibility.
- if( mTextInputHandles.GetSelectionHandleOne() && mTextInputHandles.GetSelectionHandleTwo() )
- {
- const Vector3 cursorPositionOne = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleOnePosition );
- const Vector3 cursorPositionTwo = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleTwoPosition );
-
- Size cursorSize( GetCursorSizeAt( mSelectionHandleOnePosition ) );
- const bool isSelectionHandleOneVisible = IsPositionWithinControl( cursorPositionOne, cursorSize, controlSize );
-
- cursorSize = GetCursorSizeAt( mSelectionHandleTwoPosition );
- const bool isSelectionHandleTwoVisible = IsPositionWithinControl( cursorPositionTwo, cursorSize, controlSize );
-
- mSelectionHandleOneActualPosition = cursorPositionOne.GetVectorXY();
- mSelectionHandleTwoActualPosition = cursorPositionTwo.GetVectorXY();
-
- selectionHandleOne.SetVisible( isSelectionHandleOneVisible );
- selectionHandleTwo.SetVisible( isSelectionHandleTwoVisible );
-
- PositionSelectionHandle( selectionHandleOne, mSelectionHandleOneActualPosition, mSelectionHandleOnePosition );
- PositionSelectionHandle( selectionHandleTwo, mSelectionHandleTwoActualPosition, mSelectionHandleTwoPosition );
-
- if( mHighlightMeshActor )
- {
- mHighlightMeshActor.SetVisible( true );
- ShowUpdatedHighlight();
- }
- }
-}
-
-void Decorator::StartScrollTimer()
-{
- if( !mScrollTimer )
- {
- mScrollTimer = Timer::New( SCROLL_TICK_INTERVAL );
- mScrollTimer.TickSignal().Connect( this, &Decorator::OnScrollTimerTick );
- }
-
- if( !mScrollTimer.IsRunning() )
- {
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::StartScrollTimer\n");
- mScrollTimer.Start();
- }
-}
-
-void Decorator::StopScrollTimer()
-{
- if( mScrollTimer )
- {
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::StopScrollTimer\n");
-
- mScrollTimer.Stop();
- mScrollTimer.Reset();
- }
-}
-
-bool Decorator::OnScrollTimerTick()
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::OnScrollTimerTick\n");
-
- if ( mGrabHandleVisibility && mTextInputHandles.GetGrabHandle() )
- {
- std::size_t newGrabHandlePosition = mTextViewCharacterPositioning.ReturnClosestIndex( mActualGrabHandlePosition.GetVectorXY() );
- if ( mGrabHandlePosition != newGrabHandlePosition )
- {
- Vector2 scrollPosition = mTextViewCharacterPositioning.GetScrollPosition();
- Vector2 scrollDelta = ( mActualGrabHandlePosition - mCurrentHandlePosition ).GetVectorXY();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::OnScrollTimerTick scrollPosition(%f) scrollDelta(%f)\n", scrollPosition.x, scrollDelta.x);
- scrollPosition += scrollDelta;
- mTextViewCharacterPositioning.SetScrollPosition( scrollPosition );
-
- mActualGrabHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newGrabHandlePosition ).GetVectorXY();
- }
- }
-
- Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
- Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
-
- if ( selectionHandleOne && selectionHandleTwo )
- {
- std::size_t newHandleOnePosition = mTextViewCharacterPositioning.ReturnClosestIndex( mSelectionHandleOneActualPosition.GetVectorXY() );
-
- // todo duplicated code should be a function
-
- if ( mSelectionHandleOnePosition != newHandleOnePosition )
- {
- const Vector3 actualPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandleOnePosition );
-
- Vector2 scrollDelta = ( actualPosition - mSelectionHandleOneActualPosition ).GetVectorXY();
-
- Vector2 scrollPosition = mTextViewCharacterPositioning.GetScrollPosition();
- scrollPosition += scrollDelta;
- mTextViewCharacterPositioning.SetScrollPosition( scrollPosition );
-
- mSelectionHandleOnePosition = newHandleOnePosition;
- mSelectionHandleOneActualPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleOnePosition ).GetVectorXY();
- }
- else
- {
- mSelectionHandleOneActualPosition.x += mScrollDisplacement.x;
- mSelectionHandleOneActualPosition.y += mScrollDisplacement.y;
- }
-
- std::size_t newHandleTwoPosition = mTextViewCharacterPositioning.ReturnClosestIndex( mSelectionHandleTwoActualPosition.GetVectorXY() );
-
- if ( mSelectionHandleTwoPosition != newHandleTwoPosition )
- {
- const Vector3 actualPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandleTwoPosition );
-
- Vector2 scrollDelta = ( actualPosition - mSelectionHandleTwoActualPosition ).GetVectorXY();
-
- Vector2 scrollPosition = mTextViewCharacterPositioning.GetScrollPosition();
- scrollPosition += scrollDelta;
- mTextViewCharacterPositioning.SetScrollPosition( scrollPosition );
-
- mSelectionHandleTwoPosition = newHandleTwoPosition;
- mCurrentHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleTwoPosition ).GetVectorXY();
-
- }
- else
- {
- mSelectionHandleTwoActualPosition.x += mScrollDisplacement.x;
- mSelectionHandleTwoActualPosition.y += mScrollDisplacement.y;
- }
- }
-
- return true;
-}
-
-/**
- * Text Selection
- */
-MarkupProcessor::StyledTextArray Decorator::GetSelectedText()
-{
- MarkupProcessor::StyledTextArray currentSelectedText;
-
- if ( mHighlightMeshActor ) // Text Selected
- {
- MarkupProcessor::StyledTextArray::iterator it = mTextViewCharacterPositioning.GetStyledTextArray().begin() + std::min(mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
- MarkupProcessor::StyledTextArray::iterator end = mTextViewCharacterPositioning.GetStyledTextArray().begin() + std::max(mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
-
- for(; it != end; ++it)
- {
- MarkupProcessor::StyledText& styledText( *it );
- currentSelectedText.push_back( styledText );
- }
- }
- return currentSelectedText;
-}
-
-} // Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/actors/image-actor.h>
-#include <dali/public-api/actors/mesh-actor.h>
-#include <dali/public-api/adaptor-framework/timer.h>
-#include <dali/public-api/animation/animation.h>
-#include <dali/public-api/common/intrusive-ptr.h>
-#include <dali/public-api/geometry/mesh.h>
-#include <dali/public-api/signals/connection-tracker.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-input/textview-character-positions-impl.h>
-#include <dali-toolkit/internal/controls/text-input/text-input-handles-impl.h>
-#include <dali-toolkit/internal/controls/text-input/text-input-text-highlight-impl.h>
-#include <dali-toolkit/internal/controls/text-input/text-input-popup-new-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-class Decorator;
-
-typedef IntrusivePtr<Decorator> DecoratorPtr;
-
-/**
- * @brief Decorator Class
- *
- * Decorations are Selection Handles, cursor, grab handle, magnifier the "cut copy paste" PopUp and Selection highlight.
- * The Decorator triggers creation of these decorations and positions them.
- * Decoration positions can be dependent on other decorations like the PopUp on the Selection handles.
- * The decorator maintains a Bounding Box which the decorations have to be positioned within, decorations can be flipped or hidden to obey this Bounding Box.
- * Scrolling of Text can effect positioning of decorations, the decorator repositions decorations in this case.
- */
-
-class Decorator : public ConnectionTracker
-{
-
-public:
-
- /**
- * @brief Constructor
- *
- * @param[in] textviewManager TextViewManager to be used
- */
- Decorator( TextViewCharacterPositioning& textviewManager, TextInputTextStyle& textStyle);
-
- /**
- * @brief Default destructor
- */
- ~Decorator();
-
- /**
- * @brief Set the dimensions of the bounding rectangle for decorations to obey.
- *
- * @param[in] boundingRectangle
- */
- void SetBoundingBox( const Rect<float>& boundingRectangle );
-
- /**
- * @brief Get the bounding dimensions of the bounding box
- *
- * @return dimensions of the bounding box from world origin. (x, y, w, z )
- *
- * -----------------
- * | ^ |
- * | | |
- * | y |
- * | | |
- * | v |
- * |<--x--> o <--z-->|
- * | ^ |
- * | | |
- * | w |
- * | | |
- * | v |
- * -----------------
- */
- Vector4 GetBoundingBox() const;
-
- /**
- * @brief Callback when a handle is panned/moved, either selection handles or grab handle
- *
- * @param actor Handle of the selection or grab handle.
- * @param gesture Data structure with the parameters of the gesture.
- */
- void OnHandlePan(Actor actor, const PanGesture& gesture);
-
- // Selection Handles
-
- /**
- * @brief Create a left and right selection handle and parent both to the provided actor
- * @param[in] parent actor in which the handles should be added to.
- */
- void CreateSelectionHandles( Actor parent );
-
- /**
- * @brief Remove selection handles from their parent
- */
- void RemoveSelectionHandles();
-
- /**
- * @brief Get size of Selection handles
- *
- * @return size of a selection handle
- */
- Vector3 GetSelectionHandleSize();
-
- /**
- * @brief Get position of Selection handle within text
- *
- * @return character position of a selection handle one
- */
- std::size_t GetHandleOnePosition() const;
-
- /**
- * @brief Get position of Selection handle within text
- *
- * @return character position of a selection handle two
- */
- std::size_t GetHandleTwoPosition() const;
-
- /**
- * @brief Position Selection a single handle at given positions within the text string.
- *
- * @param[in] selectionHandle handle to be positioned
- * @param[in] position where to place handle
- * @return Vector3 Position of handle as a coordinate.
- */
- Vector3 PositionSelectionHandle( Actor selectionHandle, std::size_t position );
-
- /**
- * @brief Position Selection a single handle at given coordinates
- *
- * @param[in] selectionHandle handle to be positioned
- * @param[in] actualPosition coordinates to position handle
- * @param[in] position where to place handle
- * @return Vector3 Position of handle as a coordinate.
- */
- Vector3 PositionSelectionHandle( Actor selectionHandle, Vector3& actualPosition, std::size_t position );
-
- /**
- * @brief Make both selection handle visible or invisible
- * @param[in] visible true to make visible, false to fine
- */
- void SetSelectionHandlesVisibility( bool visible );
-
- /**
- * @brief Position Selection handles at given positions within the text string.
- *
- * @param[in] start where to place first handle
- * @param[in] end where to place second handle
- */
- void PositionSelectionHandles( std::size_t start, std::size_t end );
-
- /**
- * @brief Move selection handle by the given displacement.
- *
- * @param[in] selectionHandle Actor to move
- * @param[in] actualSelectionHandlePosition actual current position of the handle in x y z
- * @param[in] currentSelectionHandlePosition current position along the string
- * @param[in] displacement the x y displacement
- */
- Vector3 MoveSelectionHandle( Actor selectionHandle,
- Vector3& actualSelectionHandlePosition,
- std::size_t& currentSelectionHandlePosition,
- const Vector2& displacement );
-
- /* Grab Handle */
-
- /**
- * @brief Position GrabHandlewith depending on the the character in the text it should be placed at
- * @param[in] positonInText the character position within the text the handle should be at
- */
- void PositionGrabHandle( std::size_t positionInText );
-
- /**
- * @brief Move grab handle to the required position within the text
- *
- * @param[in] displacement Displacement of the grab handle in actor coordinates.
- */
- void MoveGrabHandle( const Vector2& displacement );
-
- /**
- * @brief Show or hide the GrabHandle is visibility is true
- *
- * @param[in] visible flag to show or not show the grab handle
- */
- void ShowGrabHandle( bool visible );
-
- /**
- * @brief Create the GrabHandle used to position cursor
- * @param[in] targetParent the Actor to parent the GrabHandle
- */
- void CreateGrabHandle( Actor targetParent );
-
- /**
- * @brief Set the image to be used as the cursor grab hander
- * @pre The text input actor has been initialised.
- * @param[in] image The image to be used.
- */
- void SetGrabHandleImage( Image image );
-
- /**
- * @brief Toggle to enable the grab handle, used to position cursor when magnifier not being used.
- * Default behaviour is to use the magnifier to position the cursor, enabling this prevents the magnifier from being shown.
- * @param[in] toggle true to enable, false to disable grab handle
- */
- void EnableGrabHandle(bool toggle);
-
- /**
- * @brief Method to check if grab handle is enabled, if false then the magnifier will be used to position cursor.
- * @return bool returns true is grab handle enabled.
- */
- bool IsGrabHandleEnabled();
-
- /* Cursor */
-
- /**
- * @brief Get the current Cursor position
- * @return current cursor position
- */
- std::size_t GetCurrentCursorPosition() const;
-
- /**
- * @brief Set the Cursor position
- * @param[in] the position the cursor should be set to
- */
- void SetCurrentCursorPosition( std::size_t newCursorPosition );
-
- /**
- * @brief Set if the cursors are visible or not.
- * @param[in] visible flag true for visible
- */
- void SetCursorVisibility( bool visible );
-
- /**
- * @brief Display cursor
- * @param[in] nthChar position in text string to display cursor
- */
- void DrawCursor( const std::size_t nthChar = 0 );
-
- /**
- * Sets alternate cursor enable state
- * @see SetCursorVisibility
- * alternate cursor will only be visible if both SetCursorVisiblity
- * and cursor enabled have been set to true.
- */
- void SetAltCursorEnabled( bool enabled );
-
- /**
- * @brief Set the image to be used for the regular left to right cursor
- * @pre The text input actor has been initialised.
- * @param[in] image The image to be used.
- * @param[in] border The nine patch border for the image.
- */
- void SetCursorImage( Image image, const Vector4& border );
-
- /**
- * @brief Set the image to be used for the Right to Left cursor
- * @pre The text input actor has been initialised.
- * @param[in] image The image to be used.
- * @param[in] border The nine patch border for the image.
- */
- void SetRTLCursorImage( Image image, const Vector4& border );
-
- /**
- * @brief Creates a cursor from the supplied image and nine patch border.
- * @param[in] cursorImage the image to be used for the cursor.
- * @param[in] border the nine patch border corresponding to the supplied image.
- * @paran[in] cursorName actor name for cursor
- * @return the image actor to be used as the cursor.
- */
- ImageActor CreateCursor( Image cursorImage, const Vector4& border, const std::string& cursorName );
-
- /**
- * @brief Creates a regular and Right-To-Left cursor and parents them to give target Actor
- * @param[in] targetParent target Actor
- */
- void CreateCursors( Actor targetParent );
-
- /**
- * @Brief Returns the cursor size at a given position in the text.
- * @return Size the size of the cursor
- */
- Size GetCursorSizeAt( std::size_t positionWithinTextToGetCursorSize );
-
- /**
- * @brief Start a timer to signal cursor to blink.
- */
- void StartCursorBlinkTimer();
-
- /**
- * @brief Stop the timer signalling the cursor to blink.
- */
- void StopCursorBlinkTimer();
-
- /**
- * @brief Callback when handle timer ticks.
- *
- * Cursor should become visible/invisible to simulate blinking.
- *
- * @return True if the timer should be keep running.
- */
- bool OnCursorBlinkTimerTick();
-
- /* Selection Highlight */
-
- /**
- * @brief Updates mesh data for selection highlight depending on handle positions and displays it.
- */
- void ShowUpdatedHighlight();
-
- /**
- * @brief Creates the Highlight used for selection
- *
- * @param[in] parent target actor in which the handles should be added to.
- */
- void CreateHighlight( Actor parent );
-
- /**
- * @brief Remove Highlight actor from it's parent
- */
- void RemoveHighlight();
-
- /**
- * @brief Set the visibility of the Highlight
- *
- * @param[in] visibility True to show and False to hide.
- */
- void HighlightVisibility( bool visiblility );
-
- /* Boundary Property Notifications when handle exceed bounding box*/
-
- /**
- * @brief PropertyNotification Callback when left boundary exceeded so handle can be flipped.
- *
- * @param[in] source PropertyNotification
- */
- void OnLeftBoundaryExceeded( PropertyNotification& source );
- /**
- * @brief PropertyNotification Callback when within left boundary so handle can be flipped back.
- *
- * @param[in] source PropertyNotification
- */
- void OnReturnToLeftBoundary( PropertyNotification& source );
- /**
- * @brief PropertyNotification Callback when right boundary exceeded so handle can be flipped.
- *
- * @param[in] source PropertyNotification
- */
- void OnRightBoundaryExceeded( PropertyNotification& source );
- /**
- * @brief PropertyNotification Callback when within right boundary so handle can be flipped back.
- *
- * @param[in] source PropertyNotification
- */
- void OnReturnToRightBoundary( PropertyNotification& source );
-
- /**
- * @brief PropertyNotification Callbacks for hiding handle one when it exceeds boundary.
- *
- * @param[in] source PropertyNotification
- */
- void OnHandleOneLeavesBoundary( PropertyNotification& source );
- /**
- * @brief PropertyNotification Callbacks for showing hidden handle one when returns within boundary
- *
- * @param[in] source PropertyNotification
- */
- void OnHandleOneWithinBoundary( PropertyNotification& source );
- /**
- * @brief PropertyNotification Callbacks for hiding handle two it when exceeds boundary.
- *
- * @param[in] source PropertyNotification
- */
- void OnHandleTwoLeavesBoundary( PropertyNotification& source );
- /**
- * @brief PropertyNotification Callbacks for showing hidden handle two when returns within boundary
- *
- * @param[in] source PropertyNotification
- */
- void OnHandleTwoWithinBoundary( PropertyNotification& source );
-
- /**
- * @brief Set up property notifications on the position of the handles to facilitate flipping and hiding when at screen boundary.
- */
- void SetUpHandlePropertyNotifications();
-
- // Cut & Paste Pop-up
-
- /**
- * @brief Calculate positioning of PopUp relative to handles
- * @return Actual position of PopUp
- */
- Vector3 PositionOfPopUpRelativeToSelectionHandles( );
-
- /**
- * @brief Calculate alternative position of PopUp relative to handles when can it not be displayed in the default upper position.
- * @return Actual position of PopUp
- */
- Vector3 AlternatePopUpPositionRelativeToSelectionHandles();
-
- /**
- * @brief Calculate positioning of PopUp relative to cursor
- * @return Actual position of PopUp
- */
- Vector3 PositionOfPopUpRelativeToCursor();
-
- /**
- * @brief Calculate alternative position of PopUp relative to cursor when can not be displayed in normal upper position.
- * @return Actual position of PopUp
- */
- Vector3 AlternatePopUpPositionRelativeToCursor();
-
- /**
- * @brief Calculate positioning of PopUp relative to GrabHandle
- * @return Actual position of PopUp
- */
- Vector3 PositionOfPopUpRelativeToGrabHandle();
-
- /**
- * @brief Show the PopUp in the provided target
- * @param[in] target target actor in which the PopUp should be added to.
- */
- void ShowPopUp( Actor target );
-
- /**
- * @brief Show PopUp in previously set Target.
- * @pre Must have previously called ShopPopUp( Actor target ) otherwise PopUp will not be shown.
- */
- void ShowPopUp();
-
- /**
- * @brief Create and Show Cut Copy Paste PopUp
- */
- void ShowPopupCutCopyPaste();
-
- /**
- * @brief Hide PopUp
- * @param[in] animate Animate or just hide instantly, default is true
- * @param[in] signalFinished Signal when finished, default is true
- */
- void HidePopUp( bool animate=true, bool signalFinished=true );
-
- /**
- * @brief Adds a popup option.
- * @brief Creates popup frame if not already created.
- * @param[in] name The unique name for this option.
- * @param[in] caption The caption (label) for this option
- * @param[in] icon the image icon to be displayed for this option
- * @param[in] finalOption Flag to indicate that this is the final option.
- * (set to true on the last option you add)
- */
- void AddPopupOption(const std::string& name, const std::string& caption, const Image icon, bool finalOption = false);
-
- /**
- * @brief Removes popup, and its options.
- */
- void ClearPopup();
-
- /**
- * @brief PropertyNotification Callbacks for flipping PopUp when exceeds boundary.
- * @param[in] source PropertyNotification
- */
- void PopUpLeavesVerticalBoundary( PropertyNotification& source );
-
- /**
- * @brief Setup position notifications when PopUp exceeds boundary
- */
- void SetUpPopUpPositionNotifications( );
-
- /**
- * @brief Callback for when a button is pressed in popup panel
- * @param[in] button handle to the button pressed.
- * @return bool consummation
- */
- bool OnPopupButtonPressed( Toolkit::Button button );
-
- // Decoration positioning during scrolling
-
- /**
- * @brief Updates the position of the decorations when Text is scrolled.
- *
- * @param[in] textView Handle of the text-view.
- * @param[in] scrollPosition The difference with the previous scroll position.
- */
- void TextViewScrolled( Toolkit::TextView textView, Vector2 scrollPosition );
-
- /**
- * @brief Creates and starts a timer to scroll the text when handles are close to the edges of the text-input.
- *
- * It only starts the timer if it's already created.
- */
- void StartScrollTimer();
-
- /**
- * @brief Stops the timer used to scroll the text.
- */
- void StopScrollTimer();
-
- /**
- * @brief Scroll Text according to handle position
- * @param[in out] handlePosition handle position within character string
- * @param[in] actual vector position of handle
- * @return updated actual vector position of handle
- */
- Vector3 ScrollRelativeToHandle( std::size_t& handlePosition, Vector3& actualHandlePosition );
-
- /**
- * @brief Callback called by the timer used to scroll the text.
- *
- * It calculates and sets a new scroll position.
- */
- bool OnScrollTimerTick();
-
- // Text Selection
-
- /**
- * @brief Function to get Text selected between the 2 selection handles.
- * @return StyledTextArray an array of
- */
- MarkupProcessor::StyledTextArray GetSelectedText();
-
-private:
-
- /**
- * @brief Copy Constructor
- * @param[in] decorator
- * Undefined/Hidden.
- */
- Decorator(const Decorator& decorator);
-
- /**
- * @Assignment Constructor
- * @param[in] rhs
- * Undefined/Hidden.
- */
- Decorator& operator=(const Decorator& rhs);
-
-public:
-
- typedef Signal< bool( Toolkit::Button ) > PressedSignal;
- typedef Signal< void () > CursorPositionedSignal;
- /**
- * @brief Signal emitted when the button is touched.
- * This is relayed from the PopUp class. It enables the owner of the Decorator to act on the PopUp button press.
- */
- PressedSignal& PopUpButtonPressedSignal();
-
- /**
- * @brief Signal emitted when the cursor is repositioned
- * @param[in] cursor the new cursor position
- */
- CursorPositionedSignal& CursorRePositionedSignal();
-
-private:
-
- Vector4 mBoundingRectangleWorldCoordinates;
-
- TextViewCharacterPositioning& mTextViewCharacterPositioning;
-
- TextInputHandles mTextInputHandles;
-
- TextInputTextStyle& mTextStyle;
-
- Vector3 mSelectionHandleOneActualPosition; // Actual x y position of handle
- Vector3 mSelectionHandleTwoActualPosition; // Actual x y position of handle
- std::size_t mSelectionHandleOnePosition; // Position of handle along the string of text
- std::size_t mSelectionHandleTwoPosition; // Position of handle along the string of text
-
- TextInputPopupNew mPopUpPanel; // PopUp used for Cut Cpoy and Paste
- Actor mPopUpTarget; // Target Actor to parent PopUp
-
- Vector3 mActualGrabHandlePosition; // Actual position of grab handle, this might not be snapped to a character
- std::size_t mGrabHandlePosition; // Position of grab handle along the string of text
- Vector3 mCurrentHandlePosition;
-
- std::size_t mCursorPosition; // Current cursor position within the text string
- ImageActor mCursor; // Cursor overlayed on Text to show where new text will be inserted
- ImageActor mCursorRTL; // Right To Left Cursor overlayed on Text (where new RTL text would be inserted)
- Animation mCursorAnimation; // Animation for cursor blinking.
- Timer mCursorBlinkTimer; // Timer to signal cursor to blink
-
- Vector2 mScrollDisplacement; // How much to scroll by
- Timer mScrollTimer; // Timer to scroll text over a period of time not all in one update.
-
- TextHighlight mTextHighlight; // Holds data required to construct the highlight
- MeshActor mHighlightMeshActor; // Mesh Actor to display highlight
-
- PanGestureDetector mPanGestureDetector;
-
- PressedSignal mPopUpButtonPressedSignal; // Signal emitted when a button within the popup is pressed.
- CursorPositionedSignal mCursorRePositionedSignal; // Signal emitted when a button when cursor position is changed.
-
- bool mCursorBlinkStatus:1; // \e true shows the cursor, \e false hides it.
- bool mCursorVisibility:1; // Should cursor be visible
- bool mCursorRTLEnabled:1; // Enable state of Alternate RTL Cursor (need to keep track of this as it's not always enabled)
- bool mIsGrabHandleInScrollArea:1; // Whether the grab handle is inside the boundaries of the text-input.
- bool mIsCursorInScrollArea:1; // Whether the cursor is inside the boundaries of the text-input.
- bool mGrabHandleVisibility:1; // Should grab handle be visible
- bool mGrabHandleEnabled:1; // Flag to enable the grab handle instead of the default magnifier.
-};
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali-toolkit/internal/controls/text-input/text-input-handles-impl.h>
-
-// EXTERNAL INCLUDES
-#include <math.h>
-#include <sstream>
-#include <algorithm>
-#include <dali/public-api/animation/constraints.h>
-#include <dali/integration-api/debug.h>
-#include <dali/public-api/images/resource-image.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-input/textview-character-positions-impl.h>
-#include <dali-toolkit/internal/controls/text-input/text-input-impl.h>
-#include <dali-toolkit/internal/controls/text-view/text-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-#include <dali-toolkit/public-api/controls/buttons/push-button.h>
-#include <dali-toolkit/public-api/controls/alignment/alignment.h>
-
-using namespace Dali;
-
-namespace
-{
-const char* const DEFAULT_SELECTION_HANDLE_ONE( DALI_IMAGE_DIR "text-input-selection-handle-left.png" );
-const char* const DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
-const char* const DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" );
-const char* const DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" );
-
-const char* const DEFAULT_GRAB_HANDLE( DALI_IMAGE_DIR "insertpoint-icon.png" );
-
-const Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SCALE( 1.5f, 1.5f, 1.0f );
-const Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SCALE( 1.5f, 2.0f, 1.0f );
-
-const char* const SELECTION_GRAB_AREA_ONE( "SelectionHandleOneGrabArea");
-const char* const SELECTION_GRAB_AREA_TWO( "SelectionHandleTwoGrabArea");
-const char* const GRABHANDLE_GRAB_AREA( "GrabHandleGrabArea");
-
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "TEXT_INPUT_HANDLES" );
-#endif
-
-Actor CreateGrabArea( const std::string& name, const Vector3& relativeScale )
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateGrabArea\n" );
-
- Actor handleGrabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
- handleGrabArea.SetName( name );
- handleGrabArea.SetSizeMode( SIZE_RELATIVE_TO_PARENT );
- handleGrabArea.SetSizeModeFactor( relativeScale );
- handleGrabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
-
- return handleGrabArea;
-}
-
-ImageActor CreateHandle( const Vector3& anchorPoint, const Image& handleImage, const std::string& name )
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateSelectionHandle\n" );
-
- ImageActor selectionHandle = ImageActor::New( handleImage );
- selectionHandle.SetName( name );
- selectionHandle.SetAnchorPoint( anchorPoint );
- selectionHandle.SetDrawMode( DrawMode::OVERLAY ); // ensure handle above text
-
- return selectionHandle;
-}
-}
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-// Default constructor
-TextInputHandles::TextInputHandles():
- mSelectionHandleOne(),
- mSelectionHandleTwo(),
- mSelectionHandleOneOffset( Vector3::ZERO ),
- mSelectionHandleTwoOffset( Vector3::ZERO ),
- mSelectionHandleOneCoordinatePosition( Vector3::ZERO ),
- mSelectionHandleTwoCoordinatePosition( Vector3::ZERO ),
- mSelectionHandleOneStringPosition( 0 ),
- mSelectionHandleTwoStringPosition( 0 ),
- mIsSelectionHandleOneFlipped( false ),
- mIsSelectionHandleTwoFlipped( false )
-{
-}
-
-TextInputHandles::~TextInputHandles()
-{
-}
-
-void TextInputHandles::CreateSelectionHandles()
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateSelectionHandles\n" );
-
- mSelectionHandleOneImage = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE );
- mSelectionHandleOneImagePressed = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE_PRESSED );
- mSelectionHandleOne = CreateHandle( AnchorPoint::TOP_RIGHT, mSelectionHandleOneImage, "SelectionHandleOne" );
- mIsSelectionHandleOneFlipped = false;
-
- mHandleOneGrabArea = CreateGrabArea( SELECTION_GRAB_AREA_ONE, DEFAULT_SELECTION_HANDLE_RELATIVE_SCALE );
- mSelectionHandleOne.Add( mHandleOneGrabArea );
- mHandleOneGrabArea.TouchedSignal().Connect(this, &TextInputHandles::OnSelectionHandleTouched);
-
-// mTapDetector.Attach( mHandleOneGrabArea );
-
- mSelectionHandleTwoImage = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO );
- mSelectionHandleTwoImagePressed = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO_PRESSED );
- mSelectionHandleTwo = CreateHandle( AnchorPoint::TOP_LEFT, mSelectionHandleTwoImage, "SelectionHandleTwo" );
- mIsSelectionHandleTwoFlipped = false;
-
- mHandleTwoGrabArea = CreateGrabArea( SELECTION_GRAB_AREA_TWO, DEFAULT_SELECTION_HANDLE_RELATIVE_SCALE );
- mSelectionHandleTwo.Add( mHandleTwoGrabArea );
- mHandleTwoGrabArea.TouchedSignal().Connect(this, &TextInputHandles::OnSelectionHandleTouched);
-
- // mTapDetector.Attach( mHandleTwoGrabArea );
-}
-
-void TextInputHandles::DestorySelectionHandles()
-{
- if ( mSelectionHandleOne && mSelectionHandleTwo)
- {
- mSelectionHandleOne.Unparent();
- mSelectionHandleTwo.Unparent();
- mSelectionHandleOneImagePressed.Reset();
- mSelectionHandleOneImage.Reset();
- mSelectionHandleTwoImagePressed.Reset();
- mSelectionHandleTwoImage.Reset();
- mSelectionHandleOne.Reset();
- mSelectionHandleTwo.Reset();
- }
-}
-
-void TextInputHandles::SetSelectionHandleOneVisibility( bool visibility )
-{
- if ( mSelectionHandleOne )
- {
- mSelectionHandleOne.SetVisible( visibility );
- }
-}
-
-void TextInputHandles::SetSelectionHandleTwoVisibility( bool visibility )
-{
- if ( mSelectionHandleTwo )
- {
- mSelectionHandleTwo.SetVisible( visibility );
- }
-}
-
-void TextInputHandles::AttachSelectionHandlesToGivenPanGesture( PanGestureDetector& panGestureDetector )
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: AttachSelectionHandlesToGivenPanGesture\n" );
-
- panGestureDetector.Attach( mHandleOneGrabArea );
- panGestureDetector.Attach( mHandleTwoGrabArea );
-}
-
-void TextInputHandles::AttachSelectionHandlesToGivenTapDetector(TapGestureDetector& tapGestureDetector )
-{
- tapGestureDetector.Attach( mHandleOneGrabArea );
- tapGestureDetector.Attach( mHandleTwoGrabArea );
-}
-
-void TextInputHandles::AttachGrabHandleToGivenPanGesture( PanGestureDetector& panGestureDetector )
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: AttachGrabHandleToGivenPanGesture\n" );
-
- panGestureDetector.Attach( mGrabHandleGrabArea );
-}
-
-Actor TextInputHandles::GetSelectionHandleOne()
-{
- return mSelectionHandleOne;
-}
-
-Actor TextInputHandles::GetSelectionHandleTwo()
-{
- return mSelectionHandleTwo;
-}
-
-bool TextInputHandles::OnSelectionHandleTouched(Dali::Actor actor, const TouchEvent& touch)
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: OnSelectionHandleTouched\n" );
-
- Image pressedImage;
- Image normalImage;
-
- ImageActor handleTouched = ImageActor::DownCast( actor.GetParent() ); // Hit actor would be the GrabArea hence get parent.
-
- if ( handleTouched == mSelectionHandleOne )
- {
- pressedImage = mSelectionHandleOneImagePressed;
- normalImage = mSelectionHandleOneImage;
- }
- else
- {
- pressedImage = mSelectionHandleTwoImagePressed;
- normalImage = mSelectionHandleTwoImage;
- }
-
- if (touch.GetPoint(0).state == TouchPoint::Down)
- {
- handleTouched.SetImage( pressedImage );
- }
- else if (touch.GetPoint(0).state == TouchPoint::Up )
- {
- handleTouched.SetImage( normalImage );
- }
- return false;
-}
-
-// Grab handle
-
-Actor TextInputHandles::GetGrabHandle()
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: GetGrabHandle\n" );
-
- return mGrabHandle;
-}
-
-void TextInputHandles::CreateGrabHandle()
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateGrabHandle\n" );
-
- if ( !mGrabHandle )
- {
- if ( !mGrabHandleImage )
- {
- mGrabHandleImage = ResourceImage::New( DEFAULT_GRAB_HANDLE );
- }
-
- mGrabHandle = CreateHandle( AnchorPoint::TOP_CENTER, mGrabHandleImage, "GrabHandle" );
- mGrabHandleGrabArea = CreateGrabArea( GRABHANDLE_GRAB_AREA, DEFAULT_GRAB_HANDLE_RELATIVE_SCALE );
- mGrabHandle.Add( mGrabHandleGrabArea );
- }
-}
-
-void TextInputHandles::DestoryGrabHandle()
-{
- if ( mGrabHandle )
- {
- mGrabHandle.Unparent();
- mGrabHandleImage.Reset();
- mGrabHandle.Reset();
- }
-}
-
-void TextInputHandles::SetGrabHandleImage( Dali::Image image )
-{
- if ( mGrabHandle )
- {
- mGrabHandleImage = image;
- mGrabHandle.SetImage( mGrabHandleImage );
- }
-}
-
-void TextInputHandles::SetGrabHandleVisibility( bool visibility )
-{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: SetGrabHandleVisibility (%s) \n", ( visibility )?"true":"false" );
-
- if ( mGrabHandle )
- {
- mGrabHandle.SetVisible( visibility );
- }
-}
-
-} // Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_HANDLES_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_HANDLES_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/actors/image-actor.h>
-#include <dali/public-api/events/pan-gesture-detector.h>
-#include <dali/public-api/events/tap-gesture-detector.h>
-#include <dali/public-api/events/touch-event.h>
-#include <dali/public-api/images/image.h>
-#include <dali/public-api/signals/connection-tracker.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-/**
- * Class to create handles and alter their visualisation.
- * Not responsible for positioning.
- */
-
-class TextInputHandles : public ConnectionTracker
-{
-
-public:
-
- /**
- * Default constructor
- */
- TextInputHandles();
-
- /**
- * Destructor
- */
- ~TextInputHandles();
-
- /**
- * Create the selection handles
- */
- void CreateSelectionHandles();
-
- /**
- * Un-parents the Selection Handles and resets their Image Actors
- */
- void DestorySelectionHandles();
-
- /**
- * Set the Actor visibility on Selection Handle One
- * @param[in] visibility visibility flag
- */
- void SetSelectionHandleOneVisibility( bool visibility );
-
- /**
- * Set the Actor visibility on Selection Handle Two
- * @param[in] visibility visibility flag
- */
- void SetSelectionHandleTwoVisibility( bool visibility );
-
- /**
- * Attach the two selection handles to the pan gesture detector
- * @param[in] panGestureDetector the PanGestureDetector to attach to
- */
- void AttachSelectionHandlesToGivenPanGesture(PanGestureDetector& panGestureDetector );
-
- /**
- * Attach the two selection handles to the tap gesture detector
- * @param[in] tapGestureDetector the TapGestureDetector to attach to
- */
- void AttachSelectionHandlesToGivenTapDetector(TapGestureDetector& tapGestureDetector );
-
- /**
- * Attach the grab handle to the pan gesture detector
- * @param[in] panGestureDetector the PanGestureDetector to attach to
- */
- void AttachGrabHandleToGivenPanGesture( PanGestureDetector& panGestureDetector );
-
- /**
- * Get Selection handle one
- * @return selection handle actor
- */
- Actor GetSelectionHandleOne();
-
- /**
- * Get Selection handle two
- * @return selection handle actor
- */
- Actor GetSelectionHandleTwo();
-
- /**
- * Get the grab handle
- * @return grab handle Actor
- */
- Actor GetGrabHandle();
-
- /**
- * Create the grab handle that positions the cursor
- * @param[in] image the image to be used.
- */
- void CreateGrabHandle();
-
- /**
- * Removes and Resets GrabHandle
- */
- void DestoryGrabHandle();
-
- /**
- * Set the image to be used as the cursor grab hander
- * @pre The text input actor has been initialised.
- * @param[in] image The image to be used.
- */
- void SetGrabHandleImage( Dali::Image image );
-
- /**
- * Set the Actor visibility on the GrabHandle
- * @param[in] visibility visibility flag
- */
- void SetGrabHandleVisibility( bool visibility );
-
- /* Touch Event Callbacks */
-
- /**
- * Callback on selection handle touched.
- * Sets the image depending if handle in pressed or normal state
- * @param[in] actor touched
- * @param[in] touch touch event, used to determine if down or up event
- */
- bool OnSelectionHandleTouched(Dali::Actor actor, const TouchEvent& touch);
-
-private:
-
- /**
- * @brief Copy Constructor
- * @param[in] handles
- * Undefined/Hidden.
- */
- TextInputHandles(const TextInputHandles& handles);
-
- /**
- * @Assignment Constructor
- * @param[in] rhs
- * Undefined/Hidden.
- */
- TextInputHandles& operator=(const TextInputHandles& rhs);
-
-private:
-
- ImageActor mSelectionHandleOne; // First selection handle used for selecting text to cut&paste
- ImageActor mSelectionHandleTwo; // Second selection handle used for selecting text to cut&paste
- Actor mHandleOneGrabArea; // Invisible actor that receives pans events for the selection handle.
- Actor mHandleTwoGrabArea; // Invisible actor that receives pans events for the selection handle.
-
- Image mSelectionHandleOneImage; // image used for selection handle one
- Image mSelectionHandleOneImagePressed; // image used for selection handle one pressed state
- Image mSelectionHandleTwoImage; // image used for selection handle two
- Image mSelectionHandleTwoImagePressed; // image used for selection handle two pressed state
-
- Vector3 mSelectionHandleOneOffset; // Handle One's Offset
- Vector3 mSelectionHandleTwoOffset; // Handle Two's Offset
- Vector3 mSelectionHandleOneCoordinatePosition; // Actual x y z position of handle
- Vector3 mSelectionHandleTwoCoordinatePosition; // Actual x y z position of handle
- std::size_t mSelectionHandleOneStringPosition; // Position of handle along the string of text
- std::size_t mSelectionHandleTwoStringPosition; // Position of handle along the string of text
-
- Image mGrabHandleImage; // Image to be used for grab handle
- ImageActor mGrabHandle; // Handle used to move cursor for editing
- Actor mGrabHandleGrabArea; // invisible actor that receives pans events for the grab handle.
-
- bool mIsSelectionHandleOneFlipped:1; // Flag to know whether the handle one is flipped or not.
- bool mIsSelectionHandleTwoFlipped:1; // Flag to know whether the handle two is flipped or not.
-};
-
-
-} // namespace Internal
-
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_HANDLES_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali-toolkit/internal/controls/text-input/text-input-impl.h>
-
-// EXTERNAL INCLUDES
-#include <math.h>
-#include <sstream>
-#include <algorithm>
-#include <dali/public-api/adaptor-framework/virtual-keyboard.h>
-#include <dali/public-api/animation/constraints.h>
-#include <dali/public-api/common/stage.h>
-#include <dali/public-api/events/key-event.h>
-#include <dali/public-api/events/touch-event.h>
-#include <dali/public-api/object/type-registry.h>
-#include <dali/public-api/object/property-notification.h>
-#include <dali/integration-api/debug.h>
-#include <dali/public-api/images/resource-image.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-processor.h>
-#include <dali-toolkit/public-api/controls/buttons/push-button.h>
-#include <dali-toolkit/public-api/controls/alignment/alignment.h>
-#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
-
-using namespace Dali;
-
-// Local Data
-namespace
-{
-
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TEXT_INPUT");
-#endif
-
-const std::size_t DEFAULT_MAX_SIZE( std::numeric_limits<std::size_t>::max() ); // Max possible number
-const std::size_t DEFAULT_NUMBER_OF_LINES_LIMIT( std::numeric_limits<std::size_t>::max() ); // Max possible number
-const Vector3 DEFAULT_SELECTION_HANDLE_SIZE( 51.0f, 79.0f, 0.0f ); // Selection cursor image size
-const Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SIZE( 1.5f, 2.0f, 1.0f );
-const Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE( 1.5f, 1.5f, 1.0f );
-const Vector4 LIGHTBLUE( 0.07f, 0.41f, 0.59f, 1.0f ); // Used for Selection highlight
-
-const char* DEFAULT_GRAB_HANDLE( DALI_IMAGE_DIR "insertpoint-icon.png" );
-const char* DEFAULT_SELECTION_HANDLE_ONE( DALI_IMAGE_DIR "text-input-selection-handle-left.png" );
-const char* DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
-const char* DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" );
-const char* DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" );
-
-const std::size_t CURSOR_BLINK_INTERVAL = 500; ///< Cursor blink interval
-const float CHARACTER_THRESHOLD( 2.5f ); ///< the threshold of a line.
-const float DISPLAYED_HIGHLIGHT_Z_OFFSET( 0.1f ); ///< 1. Highlight rendered (z-offset).
-const float DISPLAYED_TEXT_VIEW_Z_OFFSET( 0.2f ); ///< 2. Text rendered (z-offset).
-const float UI_Z_OFFSET( 0.2f ); ///< 3. Text Selection Handles/Cursor z-offset.
-
-const Vector3 UI_OFFSET(0.0f, 0.0f, UI_Z_OFFSET); ///< Text Selection Handles/Cursor offset.
-const Vector3 DEFAULT_HANDLE_ONE_OFFSET(0.0f, -5.0f, 0.0f); ///< Handle One's Offset
-const Vector3 DEFAULT_HANDLE_TWO_OFFSET(0.0f, -5.0f, 0.0f); ///< Handle Two's Offset
-const float TOP_HANDLE_TOP_OFFSET( 34.0f); ///< Offset between top handle and cutCopyPaste pop-up
-const float BOTTOM_HANDLE_BOTTOM_OFFSET(34.0f); ///< Offset between bottom handle and cutCopyPaste pop-up
-const float CURSOR_THICKNESS(4.0f);
-const Degree CURSOR_ANGLE_OFFSET(2.0f); ///< Offset from the angle of italic angle.
-const Vector4 DEFAULT_CURSOR_COLOR(1.0f, 1.0f, 1.0f, 1.0f);
-
-const std::string NEWLINE( "\n" );
-
-const TextStyle DEFAULT_TEXT_STYLE;
-
-const unsigned int SCROLL_TICK_INTERVAL = 50u;
-const float SCROLL_THRESHOLD = 10.f;
-const float SCROLL_SPEED = 15.f;
-
-/**
- * Selection state enumeration (FSM)
- */
-enum SelectionState
-{
- SelectionNone, ///< Currently not encountered selected section.
- SelectionStarted, ///< Encountered selected section
- SelectionFinished ///< Finished selected section
-};
-
-std::size_t FindVisibleCharacterLeft( std::size_t cursorPosition, const Toolkit::TextView::CharacterLayoutInfoContainer& characterLayoutInfoTable )
-{
- for( Toolkit::TextView::CharacterLayoutInfoContainer::const_reverse_iterator it = characterLayoutInfoTable.rbegin() + characterLayoutInfoTable.size() - cursorPosition, endIt = characterLayoutInfoTable.rend();
- it != endIt;
- ++it )
- {
- if( ( *it ).mIsVisible )
- {
- return --cursorPosition;
- }
-
- --cursorPosition;
- }
-
- return 0u;
-}
-
-std::size_t FindVisibleCharacterRight( std::size_t cursorPosition, const Toolkit::TextView::CharacterLayoutInfoContainer& characterLayoutInfoTable )
-{
- for( Toolkit::TextView::CharacterLayoutInfoContainer::const_iterator it = characterLayoutInfoTable.begin() + cursorPosition, endIt = characterLayoutInfoTable.end(); it < endIt; ++it )
- {
- if( ( *it ).mIsVisible )
- {
- return cursorPosition;
- }
-
- ++cursorPosition;
- }
-
- return cursorPosition;
-}
-
-/**
- * Whether the given position plus the cursor size offset is inside the given boundary.
- *
- * @param[in] position The given position.
- * @param[in] cursorSize The cursor size.
- * @param[in] controlSize The given boundary.
- *
- * @return whether the given position is inside the given boundary.
- */
-bool IsPositionInsideBoundaries( const Vector3& position, const Size& cursorSize, const Vector3& controlSize )
-{
- return ( position.x >= -Math::MACHINE_EPSILON_1000 ) &&
- ( position.x <= controlSize.width + Math::MACHINE_EPSILON_1000 ) &&
- ( position.y - cursorSize.height >= -Math::MACHINE_EPSILON_1000 ) &&
- ( position.y <= controlSize.height + Math::MACHINE_EPSILON_1000 );
-}
-
-/**
- * Splits a text in two halves.
- *
- * If the text's number of characters is odd, firstHalf has one more character.
- *
- * @param[in] text The text to be split.
- * @param[out] firstHalf The first half of the text.
- * @param[out] secondHalf The second half of the text.
- */
-void SplitText( const Toolkit::MarkupProcessor::StyledTextArray& text,
- Toolkit::MarkupProcessor::StyledTextArray& firstHalf,
- Toolkit::MarkupProcessor::StyledTextArray& secondHalf )
-{
- firstHalf.clear();
- secondHalf.clear();
-
- const std::size_t textLength = text.size();
- const std::size_t half = ( textLength / 2 ) + ( textLength % 2 );
-
- firstHalf.insert( firstHalf.end(), text.begin(), text.begin() + half );
- secondHalf.insert( secondHalf.end(), text.begin() + half, text.end() );
-}
-
-} // end of namespace
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-// Properties
-const Property::Index TextInput::HIGHLIGHT_COLOR_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX;
-const Property::Index TextInput::CUT_AND_PASTE_COLOR_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+1;
-const Property::Index TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+2;
-const Property::Index TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+3;
-const Property::Index TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+4;
-const Property::Index TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+5;
-const Property::Index TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+6;
-const Property::Index TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+7;
-const Property::Index TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+8;
-const Property::Index TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+9;
-const Property::Index TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+10;
-const Property::Index TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+11;
-const Property::Index TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+12;
-const Property::Index TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+13;
-const Property::Index TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+14;
-const Property::Index TextInput::CURSOR_COLOR_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+15;
-
-
-namespace Internal
-{
-
-namespace
-{
-
-// Signals
-
-const char* const SIGNAL_START_INPUT = "start-input";
-const char* const SIGNAL_END_INPUT = "end-input";
-const char* const SIGNAL_STYLE_CHANGED = "style-changed";
-const char* const SIGNAL_MAX_INPUT_CHARACTERS_REACHED = "max-input-characters-reached";
-const char* const SIGNAL_TOOLBAR_DISPLAYED = "toolbar-displayed";
-const char* const SIGNAL_TEXT_EXCEED_BOUNDARIES = "text-exceed-boundaries";
-
-BaseHandle Create()
-{
- return Toolkit::TextInput::New();
-}
-
-TypeRegistration typeRegistration( typeid( Toolkit::TextInput ), typeid( Toolkit::Control ), Create );
-
-SignalConnectorType signalConnector1( typeRegistration, SIGNAL_START_INPUT, &TextInput::DoConnectSignal );
-SignalConnectorType signalConnector2( typeRegistration, SIGNAL_END_INPUT, &TextInput::DoConnectSignal );
-SignalConnectorType signalConnector3( typeRegistration, SIGNAL_STYLE_CHANGED, &TextInput::DoConnectSignal );
-SignalConnectorType signalConnector4( typeRegistration, SIGNAL_MAX_INPUT_CHARACTERS_REACHED, &TextInput::DoConnectSignal );
-SignalConnectorType signalConnector5( typeRegistration, SIGNAL_TOOLBAR_DISPLAYED, &TextInput::DoConnectSignal );
-SignalConnectorType signalConnector6( typeRegistration, SIGNAL_TEXT_EXCEED_BOUNDARIES, &TextInput::DoConnectSignal );
-
-}
-
-PropertyRegistration property1( typeRegistration, "highlight-color", Toolkit::TextInput::HIGHLIGHT_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property2( typeRegistration, "cut-and-paste-bg-color", Toolkit::TextInput::CUT_AND_PASTE_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property3( typeRegistration, "cut-and-paste-pressed-color", Toolkit::TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property4( typeRegistration, "cut-and-paste-icon-color", Toolkit::TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property5( typeRegistration, "cut-and-paste-icon-pressed-color", Toolkit::TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property6( typeRegistration, "cut-and-paste-text-color", Toolkit::TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property7( typeRegistration, "cut-and-paste-text-pressed-color", Toolkit::TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property8( typeRegistration, "cut-and-paste-border-color", Toolkit::TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property9( typeRegistration, "cut-button-position-priority", Toolkit::TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property10( typeRegistration, "copy-button-position-priority", Toolkit::TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property11( typeRegistration, "paste-button-position-priority", Toolkit::TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property12( typeRegistration, "select-button-position-priority", Toolkit::TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property13( typeRegistration, "select-all-button-position-priority", Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property14( typeRegistration, "clipboard-button-position-priority", Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property15( typeRegistration, "popup-offset-from-text", Toolkit::TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property16( typeRegistration, "cursor-color", Toolkit::TextInput::CURSOR_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
-
-
-// [TextInput::HighlightInfo] /////////////////////////////////////////////////
-
-void TextInput::HighlightInfo::AddQuad( float x1, float y1, float x2, float y2 )
-{
- QuadCoordinates quad(x1, y1, x2, y2);
- mQuadList.push_back( quad );
-}
-
-void TextInput::HighlightInfo::Clamp2D(const Vector2& min, const Vector2& max)
-{
- for(std::size_t i = 0;i < mQuadList.size(); i++)
- {
- QuadCoordinates& quad = mQuadList[i];
-
- quad.min.Clamp(min, max);
- quad.max.Clamp(min, max);
- } // end for
-}
-
-// [TextInput] ////////////////////////////////////////////////////////////////
-
-Dali::Toolkit::TextInput TextInput::New()
-{
- // Create the implementation
- TextInputPtr textInput(new TextInput());
- // Pass ownership to CustomActor via derived handle
- Dali::Toolkit::TextInput handle(*textInput);
- handle.SetName( "TextInput");
-
- textInput->Initialize();
- return handle;
-}
-
-TextInput::TextInput()
-:Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ),
- mState( StateEdit ),
- mStyledText(),
- mInputStyle(),
- mLineHeight( 0.f ),
- mDisplayedTextView(),
- mStyledPlaceHolderText(),
- mMaxStringLength( DEFAULT_MAX_SIZE ),
- mNumberOflinesLimit( DEFAULT_NUMBER_OF_LINES_LIMIT ),
- mCursorPosition( 0 ),
- mActualGrabHandlePosition( 0.0f, 0.0f, 0.0f ),
- mIsSelectionHandleOneFlipped( false ),
- mIsSelectionHandleTwoFlipped( false ),
- mSelectionHandleOneOffset( DEFAULT_HANDLE_ONE_OFFSET ),
- mSelectionHandleTwoOffset( DEFAULT_HANDLE_TWO_OFFSET ),
- mSelectionHandleOneActualPosition( 0.0f, 0.0f , 0.0f ),
- mSelectionHandleTwoActualPosition( 0.0f, 0.0f , 0.0f ),
- mSelectionHandleOnePosition( 0 ),
- mSelectionHandleTwoPosition( 0 ),
- mPreEditString(),
- mPreEditStartPosition( 0 ),
- mPreEditLength ( 0 ),
- mNumberOfSurroundingCharactersDeleted( 0 ),
- mTouchStartTime( 0 ),
- mTextLayoutInfo(),
- mCurrentCopySelecton(),
- mPopupPanel(),
- mScrollTimer(),
- mScrollDisplacement(),
- mCurrentHandlePosition(),
- mCurrentSelectionId(),
- mCurrentSelectionHandlePosition(),
- mRequestedSelection( 0, 0 ),
- mSelectionHandleFlipMargin( 0.0f, 0.0f, 0.0f, 0.0f ),
- mBoundingRectangleWorldCoordinates( 0.0f, 0.0f, 0.0f, 0.0f ),
- mClipboard(),
- mMaterialColor( LIGHTBLUE ),
- mPopupOffsetFromText ( Vector4( 0.0f, TOP_HANDLE_TOP_OFFSET, 0.0f, BOTTOM_HANDLE_BOTTOM_OFFSET ) ),
- mOverrideAutomaticAlignment( false ),
- mCursorRTLEnabled( false ),
- mClosestCursorPositionEOL ( false ),
- mCursorBlinkStatus( true ),
- mCursorVisibility( false ),
- mGrabHandleVisibility( false ),
- mIsCursorInScrollArea( true ),
- mIsGrabHandleInScrollArea( true ),
- mEditModeActive( false ),
- mEditOnTouch( true ),
- mTextSelection( true ),
- mExceedEnabled( true ),
- mGrabHandleEnabled( true ),
- mIsSelectionHandleFlipEnabled( true ),
- mPreEditFlag( false ),
- mIgnoreCommitFlag( false ),
- mIgnoreFirstCommitFlag( false ),
- mSelectingText( false ),
- mPreserveCursorPosition( false ),
- mSelectTextOnCommit( false ),
- mUnderlinedPriorToPreEdit ( false ),
- mCommitByKeyInput( false ),
- mPlaceHolderSet( false ),
- mMarkUpEnabled( false )
-{
- // Updates the line height accordingly with the input style.
- UpdateLineHeight();
-}
-
-TextInput::~TextInput()
-{
- StopCursorBlinkTimer();
-}
-
-// Public
-
-std::string TextInput::GetText() const
-{
- std::string text;
-
- // Return text-view's text only if the text-input's text is not empty
- // in order to not to return the placeholder text.
- if( !mStyledText.empty() )
- {
- text = mDisplayedTextView.GetText();
- }
-
- return text;
-}
-
-std::string TextInput::GetMarkupText() const
-{
- std::string markupString;
- MarkupProcessor::GetMarkupString( mStyledText, markupString );
-
- return markupString;
-}
-
-void TextInput::ShowPlaceholderText( const MarkupProcessor::StyledTextArray& stylePlaceHolderText )
-{
- mDisplayedTextView.SetText( stylePlaceHolderText );
- mPlaceHolderSet = true;
- mDisplayedTextView.SetScrollPosition( Vector2( 0.0f,0.0f ) );
-}
-
-void TextInput::SetPlaceholderText( const std::string& placeHolderText )
-{
- // Get the placeholder styled text array from the markup string.
- MarkupProcessor::GetStyledTextArray( placeHolderText, mStyledPlaceHolderText, IsMarkupProcessingEnabled() );
- if( mStyledText.empty() )
- {
- ShowPlaceholderText( mStyledPlaceHolderText );
- }
-}
-
-std::string TextInput::GetPlaceholderText()
-{
- // Traverses the styled placeholder array getting only the text.
- // Note that for some languages a 'character' could be represented by more than one 'char'
-
- std::string placeholderText;
- for( MarkupProcessor::StyledTextArray::const_iterator it = mStyledPlaceHolderText.begin(), endIt = mStyledPlaceHolderText.end(); it != endIt; ++it )
- {
- placeholderText.append( (*it).mText.GetText() );
- }
-
- return placeholderText ;
-}
-
-void TextInput::SetInitialText(const std::string& initialText)
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, "SetInitialText string[%s]\n", initialText.c_str() );
-
- if ( mPreEditFlag ) // If in the pre-edit state and text is being set then discard text being inserted.
- {
- mPreEditFlag = false;
- mIgnoreCommitFlag = true;
- }
-
- SetText( initialText );
- PreEditReset( false ); // Reset keyboard as text changed
-}
-
-void TextInput::SetText(const std::string& initialText)
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, "SetText string[%s]\n", initialText.c_str() );
-
- GetStyledTextArray( initialText, mStyledText, IsMarkupProcessingEnabled() );
-
- if( mStyledText.empty() )
- {
- ShowPlaceholderText( mStyledPlaceHolderText );
- }
- else
- {
- mDisplayedTextView.SetText( mStyledText );
- mPlaceHolderSet = false;
- }
-
- GetTextLayoutInfo();
-
- mCursorPosition = mTextLayoutInfo.mCharacterLayoutInfoTable.size();
-
- ImfManager imfManager = ImfManager::Get();
- if ( imfManager )
- {
- imfManager.SetCursorPosition( mCursorPosition );
- imfManager.SetSurroundingText( initialText );
- imfManager.NotifyCursorPosition();
- }
-
- if( IsScrollEnabled() )
- {
- ScrollTextViewToMakeCursorVisible( Vector3( mTextLayoutInfo.mScrollOffset.x, mTextLayoutInfo.mScrollOffset.y, 0.f ) );
- }
-
- ShowGrabHandleAndSetVisibility( false );
-
- RemoveHighlight();
-
- DrawCursor();
-
- EmitTextModified();
-}
-
-void TextInput::SetText( const MarkupProcessor::StyledTextArray& styleText )
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, "SetText markup text\n" );
-
- mDisplayedTextView.SetText( styleText );
- mPlaceHolderSet = false;
-
- // If text alignment hasn't been manually set by application developer, then we
- // automatically determine the alignment based on the content of the text i.e. what
- // language the text begins with.
- // TODO: This should determine different alignments for each line (broken by '\n') of text.
- if(!mOverrideAutomaticAlignment)
- {
- // Determine bidi direction of first character (skipping past whitespace, numbers, and symbols)
- bool leftToRight(true);
-
- if( !styleText.empty() )
- {
- bool breakOut(false);
-
- for( MarkupProcessor::StyledTextArray::const_iterator textIter = styleText.begin(), textEndIter = styleText.end(); ( textIter != textEndIter ) && ( !breakOut ); ++textIter )
- {
- const Text& text = textIter->mText;
-
- for( std::size_t i = 0; i < text.GetLength(); ++i )
- {
- Character character( text[i] );
- if( character.GetCharacterDirection() != Character::Neutral )
- {
- leftToRight = ( character.GetCharacterDirection() == Character::LeftToRight );
- breakOut = true;
- break;
- }
- }
- }
- }
-
- // Based on this direction, either left or right align text if not manually set by application developer.
- mDisplayedTextView.SetTextAlignment( static_cast<Toolkit::Alignment::Type>(
- ( leftToRight ? Toolkit::Alignment::HorizontalLeft : Toolkit::Alignment::HorizontalRight) |
- Toolkit::Alignment::VerticalTop ) );
- mDisplayedTextView.SetLineJustification( leftToRight ? Toolkit::TextView::Left : Toolkit::TextView::Right);
- }
-
- EmitTextModified();
-}
-
-void TextInput::SetMaxCharacterLength(std::size_t maxChars)
-{
- mMaxStringLength = maxChars;
-}
-
-void TextInput::SetNumberOfLinesLimit(std::size_t maxLines)
-{
- DALI_ASSERT_DEBUG( maxLines > 0 )
-
- if ( maxLines > 0)
- {
- mNumberOflinesLimit = maxLines;
- }
-}
-
-std::size_t TextInput::GetNumberOfLinesLimit() const
-{
- return mNumberOflinesLimit;
-}
-
-std::size_t TextInput::GetNumberOfCharacters() const
-{
- return mStyledText.size();
-}
-
-// Styling
-void TextInput::SetMaterialDiffuseColor( const Vector4& color )
-{
- mMaterialColor = color;
- if ( mCustomMaterial )
- {
- mCustomMaterial.SetDiffuseColor( mMaterialColor );
- mMeshData.SetMaterial( mCustomMaterial );
- }
-}
-
-const Vector4& TextInput::GetMaterialDiffuseColor() const
-{
- return mMaterialColor;
-}
-
-// Signals
-
-Toolkit::TextInput::InputSignalType& TextInput::InputStartedSignal()
-{
- return mInputStartedSignal;
-}
-
-Toolkit::TextInput::InputSignalType& TextInput::InputFinishedSignal()
-{
- return mInputFinishedSignal;
-}
-
-Toolkit::TextInput::InputSignalType& TextInput::CutAndPasteToolBarDisplayedSignal()
-{
- return mCutAndPasteToolBarDisplayed;
-}
-
-Toolkit::TextInput::StyleChangedSignalType& TextInput::StyleChangedSignal()
-{
- return mStyleChangedSignal;
-}
-
-Toolkit::TextInput::TextModifiedSignalType& TextInput::TextModifiedSignal()
-{
- return mTextModifiedSignal;
-}
-
-Toolkit::TextInput::MaxInputCharactersReachedSignalType& TextInput::MaxInputCharactersReachedSignal()
-{
- return mMaxInputCharactersReachedSignal;
-}
-
-Toolkit::TextInput::InputTextExceedBoundariesSignalType& TextInput::InputTextExceedBoundariesSignal()
-{
- return mInputTextExceedBoundariesSignal;
-}
-
-bool TextInput::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
-{
- Dali::BaseHandle handle( object );
-
- bool connected( true );
- Toolkit::TextInput textInput = Toolkit::TextInput::DownCast( handle );
-
- if( 0 == strcmp( signalName.c_str(), SIGNAL_START_INPUT ) )
- {
- textInput.InputStartedSignal().Connect( tracker, functor );
- }
- else if( 0 == strcmp( signalName.c_str(), SIGNAL_END_INPUT ) )
- {
- textInput.InputFinishedSignal().Connect( tracker, functor );
- }
- else if( 0 == strcmp( signalName.c_str(), SIGNAL_STYLE_CHANGED ) )
- {
- textInput.StyleChangedSignal().Connect( tracker, functor );
- }
- else if( 0 == strcmp( signalName.c_str(), SIGNAL_MAX_INPUT_CHARACTERS_REACHED ) )
- {
- textInput.MaxInputCharactersReachedSignal().Connect( tracker, functor );
- }
- else if( 0 == strcmp( signalName.c_str(), SIGNAL_TOOLBAR_DISPLAYED ) )
- {
- textInput.CutAndPasteToolBarDisplayedSignal().Connect( tracker, functor );
- }
- else if( 0 == strcmp( signalName.c_str(), SIGNAL_TEXT_EXCEED_BOUNDARIES ) )
- {
- textInput.InputTextExceedBoundariesSignal().Connect( tracker, functor );
- }
- else
- {
- // signalName does not match any signal
- connected = false;
- }
-
- return connected;
-}
-
-void TextInput::SetEditable(bool editMode, bool setCursorOnTouchPoint, const Vector2& touchPoint)
-{
- if(editMode)
- {
- // update line height before calculate the actual position.
- UpdateLineHeight();
-
- if(!mEditModeActive)
- {
- if( setCursorOnTouchPoint )
- {
- // Sets the cursor position for the given touch point.
- ReturnClosestIndex( touchPoint, mCursorPosition );
-
- // Creates the grab handle.
- if( IsGrabHandleEnabled() )
- {
- const Vector3 cursorPosition = GetActualPositionFromCharacterPosition(mCursorPosition);
-
- CreateGrabHandle();
-
- mActualGrabHandlePosition.x = cursorPosition.x; // Set grab handle to be at the cursor position
- mActualGrabHandlePosition.y = cursorPosition.y; // Set grab handle to be at the cursor position
- mGrabHandle.SetPosition( mActualGrabHandlePosition + UI_OFFSET );
- ShowGrabHandleAndSetVisibility( true );
-
- // Scrolls the text-view if needed.
- if( IsScrollEnabled() )
- {
- ScrollTextViewToMakeCursorVisible( cursorPosition );
- }
- }
- }
- else
- {
- mCursorPosition = mStyledText.size(); // Initially set cursor position to end of string.
- }
- }
-
- StartEditMode();
- }
- else
- {
- EndEditMode();
- }
-}
-
-bool TextInput::IsEditable() const
-{
- return mEditModeActive;
-}
-
-void TextInput::SetEditOnTouch( bool editOnTouch )
-{
- mEditOnTouch = editOnTouch;
-}
-
-bool TextInput::IsEditOnTouch() const
-{
- return mEditOnTouch;
-}
-
-void TextInput::SetTextSelectable( bool textSelectable )
-{
- mTextSelection = textSelectable;
-}
-
-bool TextInput::IsTextSelectable() const
-{
- return mTextSelection;
-}
-
-bool TextInput::IsTextSelected() const
-{
- return mHighlightMeshActor;
-}
-
-void TextInput::DeSelectText()
-{
- RemoveHighlight();
- HidePopup();
- CursorUpdate();
-}
-
-void TextInput::SetGrabHandleImage(Dali::Image image )
-{
- if (image)
- {
- CreateGrabHandle(image);
- }
-}
-
-void TextInput::SetCursorImage(Dali::Image image, const Vector4& border )
-{
- DALI_ASSERT_DEBUG ( image && "Create cursor image invalid")
-
- if ( image )
- {
- mCursor.SetImage( image );
- mCursor.SetNinePatchBorder( border );
- }
-}
-
-Vector3 TextInput::GetSelectionHandleSize()
-{
- return DEFAULT_SELECTION_HANDLE_SIZE;
-}
-
-void TextInput::SetRTLCursorImage(Dali::Image image, const Vector4& border )
-{
- DALI_ASSERT_DEBUG ( image && "Create cursor image invalid")
-
- if ( image )
- {
- mCursorRTL.SetImage( image);
- mCursorRTL.SetNinePatchBorder( border );
- }
-}
-
-void TextInput::EnableGrabHandle(bool toggle)
-{
- // enables grab handle with will in turn de-activate magnifier
- mGrabHandleEnabled = toggle;
-}
-
-bool TextInput::IsGrabHandleEnabled()
-{
- // if false then magnifier will be shown instead.
- return mGrabHandleEnabled;
-}
-
-void TextInput::EnableSelectionHandleFlip( bool toggle )
-{
- // Deprecated function. To be removed.
- mIsSelectionHandleFlipEnabled = toggle;
-}
-
-bool TextInput::IsSelectionHandleFlipEnabled()
-{
- // Deprecated function, To be removed. Returns true as handle flipping always enabled by default so handles do not exceed screen.
- return true;
-}
-
-void TextInput::SetSelectionHandleFlipMargin( const Vector4& margin )
-{
- // Deprecated function, now just stores margin for retreival, remove completely once depricated Public API removed.
- Vector3 textInputSize = mDisplayedTextView.GetCurrentSize();
- const Vector4 flipBoundary( -margin.x, -margin.y, textInputSize.width + margin.z, textInputSize.height + margin.w );
-
- mSelectionHandleFlipMargin = margin;
-}
-
-void TextInput::SetBoundingRectangle( const Rect<float>& boundingRectangle )
-{
- // Convert to world coordinates and store as a Vector4 to be compatiable with Property Notifications.
- Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
-
- const float originX = boundingRectangle.x - 0.5f * stageSize.width;
- const float originY = boundingRectangle.y - 0.5f * stageSize.height;
-
- const Vector4 boundary( originX,
- originY,
- originX + boundingRectangle.width,
- originY + boundingRectangle.height );
-
- mBoundingRectangleWorldCoordinates = boundary;
-}
-
-const Rect<float> TextInput::GetBoundingRectangle() const
-{
- Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
-
- const float originX = mBoundingRectangleWorldCoordinates.x + 0.5f * stageSize.width;
- const float originY = mBoundingRectangleWorldCoordinates.y + 0.5f * stageSize.height;
-
- Rect<float>boundingRect( originX, originY, mBoundingRectangleWorldCoordinates.z - mBoundingRectangleWorldCoordinates.x, mBoundingRectangleWorldCoordinates.w - mBoundingRectangleWorldCoordinates.y);
-
- return boundingRect;
-}
-
-const Vector4& TextInput::GetSelectionHandleFlipMargin()
-{
- return mSelectionHandleFlipMargin;
-}
-
-void TextInput::SetTextColor( const Vector4& color )
-{
- mDisplayedTextView.SetColor( color );
-}
-
-void TextInput::SetActiveStyle( const TextStyle& style, const TextStyle::Mask mask )
-{
- if( style != mInputStyle )
- {
- // different style.
- bool emitSignal = false;
-
- // mask: modify style according to mask, if different emit signal.
- const TextStyle oldInputStyle( mInputStyle );
-
- // Copy the new style.
- mInputStyle.Copy( style, mask );
-
- // if style has changed, emit signal.
- if( oldInputStyle != mInputStyle )
- {
- emitSignal = true;
- }
-
- // Updates the line height accordingly with the input style.
- UpdateLineHeight();
-
- // Changing font point size will require the cursor to be re-sized
- DrawCursor();
-
- if( emitSignal )
- {
- EmitStyleChangedSignal();
- }
- }
-}
-
-void TextInput::ApplyStyle( const TextStyle& style, const TextStyle::Mask mask )
-{
- if ( IsTextSelected() )
- {
- const std::size_t begin = std::min(mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
- const std::size_t end = std::max(mSelectionHandleOnePosition, mSelectionHandleTwoPosition) - 1;
-
- if( !mTextLayoutInfo.mCharacterLogicalToVisualMap.empty() )
- {
- ApplyStyleToRange(style, mask, mTextLayoutInfo.mCharacterLogicalToVisualMap[begin], mTextLayoutInfo.mCharacterLogicalToVisualMap[end]);
- }
-
- // Keeps the old style to be compared with the new one.
- const TextStyle oldInputStyle( mInputStyle );
-
- // Copy only those parameters from the style which are set in the mask.
- mInputStyle.Copy( style, mask );
-
- if( mInputStyle != oldInputStyle )
- {
- // Updates the line height accordingly with the input style.
- UpdateLineHeight();
-
- EmitStyleChangedSignal();
- }
- }
-}
-
-void TextInput::ApplyStyleToAll( const TextStyle& style, const TextStyle::Mask mask )
-{
- if( !mStyledText.empty() )
- {
- ApplyStyleToRange( style, mask, 0, mStyledText.size() - 1 );
- }
-}
-
-TextStyle TextInput::GetStyleAtCursor() const
-{
- TextStyle style;
-
- if ( !mStyledText.empty() && ( mCursorPosition > 0 ) )
- {
- DALI_ASSERT_DEBUG( ( 0 <= mCursorPosition-1 ) && ( mCursorPosition-1 < mStyledText.size() ) );
- style = mStyledText.at( mCursorPosition-1 ).mStyle;
- }
- else // No text.
- {
- style = mInputStyle;
-
- if ( mInputStyle.GetFontPointSize() < Math::MACHINE_EPSILON_1000 )
- {
- Dali::Font defaultFont = Dali::Font::New();
- style.SetFontPointSize( PointSize( defaultFont.GetPointSize()) );
- }
- }
-
- return style;
-}
-
-TextStyle TextInput::GetStyleAt( std::size_t position ) const
-{
- DALI_ASSERT_DEBUG( ( 0 <= position ) && ( position <= mStyledText.size() ) );
-
- if( position >= mStyledText.size() )
- {
- position = mStyledText.size() - 1;
- }
-
- return mStyledText.at( position ).mStyle;
-}
-
-void TextInput::SetTextAlignment( Toolkit::Alignment::Type align )
-{
- mDisplayedTextView.SetTextAlignment( align );
- mOverrideAutomaticAlignment = true;
-}
-
-void TextInput::SetTextLineJustification( Toolkit::TextView::LineJustification justification )
-{
- mDisplayedTextView.SetLineJustification( justification );
- mOverrideAutomaticAlignment = true;
-}
-
-void TextInput::SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary )
-{
- mDisplayedTextView.SetFadeBoundary( fadeBoundary );
-}
-
-const Toolkit::TextView::FadeBoundary& TextInput::GetFadeBoundary() const
-{
- return mDisplayedTextView.GetFadeBoundary();
-}
-
-Toolkit::Alignment::Type TextInput::GetTextAlignment() const
-{
- return mDisplayedTextView.GetTextAlignment();
-}
-
-void TextInput::SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy )
-{
- mDisplayedTextView.SetMultilinePolicy( policy );
-}
-
-Toolkit::TextView::MultilinePolicy TextInput::GetMultilinePolicy() const
-{
- return mDisplayedTextView.GetMultilinePolicy();
-}
-
-void TextInput::SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
-{
- mDisplayedTextView.SetWidthExceedPolicy( policy );
-}
-
-Toolkit::TextView::ExceedPolicy TextInput::GetWidthExceedPolicy() const
-{
- return mDisplayedTextView.GetWidthExceedPolicy();
-}
-
-void TextInput::SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
-{
- mDisplayedTextView.SetHeightExceedPolicy( policy );
-}
-
-Toolkit::TextView::ExceedPolicy TextInput::GetHeightExceedPolicy() const
-{
- return mDisplayedTextView.GetHeightExceedPolicy();
-}
-
-void TextInput::SetExceedEnabled( bool enable )
-{
- mExceedEnabled = enable;
-}
-
-bool TextInput::GetExceedEnabled() const
-{
- return mExceedEnabled;
-}
-
-void TextInput::SetBackground(Dali::Image image )
-{
- // TODO Should add this function and add public api to match.
-}
-
-bool TextInput::OnTouchEvent(const TouchEvent& event)
-{
- return false;
-}
-
-bool TextInput::OnKeyEvent(const KeyEvent& event)
-{
- switch( event.state )
- {
- case KeyEvent::Down:
- {
- return OnKeyDownEvent(event);
- }
- break;
-
- case KeyEvent::Up:
- {
- return OnKeyUpEvent(event);
- }
- break;
-
- default:
- {
- return false;
- }
- break;
- }
-}
-
-void TextInput::OnKeyInputFocusGained()
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, ">>OnKeyInputFocusGained\n" );
-
- mEditModeActive = true;
-
- mActiveLayer.RaiseToTop(); // Ensure layer holding handles is on top
-
- mInputStyle = GetStyleAtCursor(); // Inherit style from cursor position
-
- // Updates the line height accordingly with the input style.
- UpdateLineHeight();
-
- // Connect the signals to use in text input.
- VirtualKeyboard::StatusChangedSignal().Connect( this, &TextInput::KeyboardStatusChanged );
- VirtualKeyboard::LanguageChangedSignal().Connect( this, &TextInput::SetTextDirection );
-
- // Set the text direction if empty and connect to the signal to ensure we change direction when the language changes.
- SetTextDirection();
-
- GetTextLayoutInfo();
-
- DrawCursor();
- SetCursorVisibility( true );
- StartCursorBlinkTimer();
-
- Toolkit::TextInput handle( GetOwner() );
- mInputStartedSignal.Emit( handle );
-
- ImfManager imfManager = ImfManager::Get();
-
- if ( imfManager )
- {
- imfManager.EventReceivedSignal().Connect(this, &TextInput::ImfEventReceived);
-
- // Notify that the text editing start.
- imfManager.Activate();
-
- // When window gain lost focus, the imf manager is deactivated. Thus when window gain focus again, the imf manager must be activated.
- imfManager.SetRestoreAfterFocusLost( true );
-
- imfManager.SetCursorPosition( mCursorPosition );
- imfManager.NotifyCursorPosition();
- }
-
- mClipboard = Clipboard::Get(); // Store handle to clipboard
-
- // Now in edit mode we can accept string to paste from clipboard
- ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
- if ( notifier )
- {
- notifier.ContentSelectedSignal().Connect( this, &TextInput::OnClipboardTextSelected );
- }
-}
-
-void TextInput::OnKeyInputFocusLost()
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, ">>OnKeyInputFocusLost\n" );
-
- if( mPreEditFlag )
- {
- // If key input focus is lost, it removes the
- // underline from the last pre-edit text.
- RemovePreEditStyle();
- const std::size_t numberOfCharactersDeleted = DeletePreEdit();
- InsertAt( mPreEditString, mPreEditStartPosition, numberOfCharactersDeleted );
- EmitTextModified();
- }
-
- ImfManager imfManager = ImfManager::Get();
- if ( imfManager )
- {
- // The text editing is finished. Therefore the imf manager don't have restore activation.
- imfManager.SetRestoreAfterFocusLost( false );
-
- // Notify that the text editing finish.
- imfManager.Deactivate();
-
- imfManager.EventReceivedSignal().Disconnect(this, &TextInput::ImfEventReceived);
- }
- // Disconnect signal used the text input.
- VirtualKeyboard::LanguageChangedSignal().Disconnect( this, &TextInput::SetTextDirection );
-
- Toolkit::TextInput handle( GetOwner() );
- mInputFinishedSignal.Emit( handle );
- mEditModeActive = false;
- mPreEditFlag = false;
- RemoveHighlight();
- SetCursorVisibility( false );
- StopCursorBlinkTimer();
-
- ShowGrabHandleAndSetVisibility( false );
-
- mClipboard.Reset();
- // No longer in edit mode so do not want to receive string from clipboard
- ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
- if ( notifier )
- {
- notifier.ContentSelectedSignal().Disconnect( this, &TextInput::OnClipboardTextSelected );
- }
-
- Clipboard clipboard = Clipboard::Get();
- if ( clipboard )
- {
- clipboard.HideClipboard();
- }
-}
-
-void TextInput::OnControlStageConnection()
-{
- Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
-
- if ( mBoundingRectangleWorldCoordinates == Vector4::ZERO )
- {
- SetBoundingRectangle( Rect<float>( 0.0f, 0.0f, stageSize.width, stageSize.height ));
- }
-}
-
-void TextInput::CreateActiveLayer()
-{
- Actor self = Self();
- mActiveLayer = Layer::New();
- mActiveLayer.SetName ( "ActiveLayerActor" );
-
- mActiveLayer.SetAnchorPoint( AnchorPoint::CENTER);
- mActiveLayer.SetParentOrigin( ParentOrigin::CENTER);
- mActiveLayer.SetPositionInheritanceMode( USE_PARENT_POSITION );
-
- self.Add( mActiveLayer );
- mActiveLayer.RaiseToTop();
-}
-
-void TextInput::OnInitialize()
-{
- CreateTextViewActor();
-
- SetUpTouchEvents();
-
- // Create 2 cursors (standard LTR and RTL cursor for when text can be added at
- // different positions depending on language)
- mCursor = CreateCursor(DEFAULT_CURSOR_COLOR);
- mCursorRTL = CreateCursor(DEFAULT_CURSOR_COLOR);
-
- Actor self = Self();
- self.Add( mCursor );
- self.Add( mCursorRTL );
-
- mCursorVisibility = false;
-
- CreateActiveLayer(); // todo move this so layer only created when needed.
-
- // Assign names to image actors
- mCursor.SetName("mainCursor");
- mCursorRTL.SetName("rtlCursor");
-}
-
-void TextInput::OnControlSizeSet(const Vector3& targetSize)
-{
- mDisplayedTextView.SetSize( targetSize );
- GetTextLayoutInfo();
- mActiveLayer.SetSize(targetSize);
-}
-
-void TextInput::OnRelayout( const Vector2& size, ActorSizeContainer& container )
-{
- Relayout( mDisplayedTextView, size, container );
- Relayout( mPopupPanel.GetRootActor(), size, container );
-
- GetTextLayoutInfo();
-
- DrawCursor();
-}
-
-Vector3 TextInput::GetNaturalSize()
-{
- Vector3 naturalSize = mDisplayedTextView.GetNaturalSize();
-
- if( mEditModeActive && ( Vector3::ZERO == naturalSize ) )
- {
- // If the natural is zero, it means there is no text. Let's return the cursor height as the natural height.
- naturalSize.height = mLineHeight;
- }
-
- return naturalSize;
-}
-
-float TextInput::GetHeightForWidth( float width )
-{
- float height = mDisplayedTextView.GetHeightForWidth( width );
-
- if( mEditModeActive && ( fabsf( height ) < Math::MACHINE_EPSILON_1000 ) )
- {
- // If the height is zero, it means there is no text. Let's return the cursor height.
- height = mLineHeight;
- }
-
- return height;
-}
-
-/*end of Virtual methods from parent*/
-
-// Private Internal methods
-
-void TextInput::OnHandlePan(Actor actor, const PanGesture& gesture)
-{
- switch (gesture.state)
- {
- case Gesture::Started:
- // fall through so code not duplicated
- case Gesture::Continuing:
- {
- if (actor == mGrabArea)
- {
- SetCursorVisibility( true );
- ShowGrabHandle( mGrabHandleVisibility && mIsGrabHandleInScrollArea );
- MoveGrabHandle( gesture.displacement );
- HidePopup(); // Do not show popup whilst handle is moving
- }
- else if (actor == mHandleOneGrabArea)
- {
- // the displacement in PanGesture is affected by the actor's rotation.
- mSelectionHandleOneActualPosition.x += gesture.displacement.x * mSelectionHandleOne.GetCurrentScale().x;
- mSelectionHandleOneActualPosition.y += gesture.displacement.y * mSelectionHandleOne.GetCurrentScale().y;
-
- MoveSelectionHandle( HandleOne, gesture.displacement );
-
- mState = StateDraggingHandle;
- HidePopup();
- }
- else if (actor == mHandleTwoGrabArea)
- {
- // the displacement in PanGesture is affected by the actor's rotation.
- mSelectionHandleTwoActualPosition.x += gesture.displacement.x * mSelectionHandleTwo.GetCurrentScale().x;
- mSelectionHandleTwoActualPosition.y += gesture.displacement.y * mSelectionHandleTwo.GetCurrentScale().y;
-
- MoveSelectionHandle( HandleTwo, gesture.displacement );
-
- mState = StateDraggingHandle;
- HidePopup();
- }
- }
- break;
-
- case Gesture::Finished:
- {
- // Revert back to non-pressed selection handle images
- if (actor == mGrabArea)
- {
- mActualGrabHandlePosition = MoveGrabHandle( gesture.displacement );
- SetCursorVisibility( true );
- SetUpPopupSelection();
- ShowPopup();
- }
- if (actor == mHandleOneGrabArea)
- {
- // the displacement in PanGesture is affected by the actor's rotation.
- mSelectionHandleOneActualPosition.x += gesture.displacement.x * mSelectionHandleOne.GetCurrentScale().x;
- mSelectionHandleOneActualPosition.y += gesture.displacement.y * mSelectionHandleOne.GetCurrentScale().y;
-
- mSelectionHandleOneActualPosition = MoveSelectionHandle( HandleOne, gesture.displacement );
-
- mSelectionHandleOne.SetImage( mSelectionHandleOneImage );
- mState = StateEdit;
- ShowPopupCutCopyPaste();
- }
- if (actor == mHandleTwoGrabArea)
- {
- // the displacement in PanGesture is affected by the actor's rotation.
- mSelectionHandleTwoActualPosition.x += gesture.displacement.x * mSelectionHandleTwo.GetCurrentScale().x;
- mSelectionHandleTwoActualPosition.y += gesture.displacement.y * mSelectionHandleTwo.GetCurrentScale().y;
-
- mSelectionHandleTwoActualPosition = MoveSelectionHandle( HandleTwo, gesture.displacement );
-
- mSelectionHandleTwo.SetImage( mSelectionHandleTwoImage );
- mState = StateEdit;
- ShowPopupCutCopyPaste();
- }
- }
- break;
- default:
- break;
- }
-}
-
-// Stop the flashing animation so easy to see when moved.
-bool TextInput::OnPressDown(Dali::Actor actor, const TouchEvent& touch)
-{
- if (touch.GetPoint(0).state == TouchPoint::Down)
- {
- SetCursorVisibility( true );
- StopCursorBlinkTimer();
- }
- else if (touch.GetPoint(0).state == TouchPoint::Up)
- {
- SetCursorVisibility( true );
- StartCursorBlinkTimer();
- }
- return false;
-}
-
-// selection handle one
-bool TextInput::OnHandleOneTouched(Dali::Actor actor, const TouchEvent& touch)
-{
- if (touch.GetPoint(0).state == TouchPoint::Down)
- {
- mSelectionHandleOne.SetImage( mSelectionHandleOneImagePressed );
- }
- else if (touch.GetPoint(0).state == TouchPoint::Up)
- {
- mSelectionHandleOne.SetImage( mSelectionHandleOneImage );
- }
- return false;
-}
-
-// selection handle two
-bool TextInput::OnHandleTwoTouched(Dali::Actor actor, const TouchEvent& touch)
-{
- if (touch.GetPoint(0).state == TouchPoint::Down)
- {
- mSelectionHandleTwo.SetImage( mSelectionHandleTwoImagePressed );
- }
- else if (touch.GetPoint(0).state == TouchPoint::Up)
- {
- mSelectionHandleTwo.SetImage( mSelectionHandleTwoImage );
- }
- return false;
-}
-
-void TextInput::OnDoubleTap(Dali::Actor actor, const Dali::TapGesture& tap)
-{
- // If text exists then select nearest word.
- if ( !mStyledText.empty())
- {
- HidePopup();
-
- ShowGrabHandleAndSetVisibility( false );
-
-
- if ( mPreEditFlag )
- {
- // PreEdit will be committed here without needing a commit from IMF. Remove pre-edit underline and reset flags which
- // converts the pre-edit word being displayed to a committed word.
- if ( !mUnderlinedPriorToPreEdit )
- {
- TextStyle style;
- style.SetUnderline( false );
- ApplyStyleToRange( style, TextStyle::UNDERLINE , mPreEditStartPosition, mPreEditStartPosition + mPreEditLength -1 );
- }
- mPreEditFlag = false;
- mIgnoreCommitFlag = true; // Predictive word interrupted, text displayed will not change, no need to actually commit.
- // Reset keyboard and set true so cursor position is preserved. Otherwise cursor position will that of the committed text not new tap location.
- PreEditReset( false );
- }
- mCursorPosition = 0;
-
- mTextLayoutInfo.mScrollOffset = mDisplayedTextView.GetScrollPosition();
- ReturnClosestIndex( tap.localPoint, mCursorPosition );
-
- std::size_t start = 0;
- std::size_t end = 0;
- Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
-
- mCursorPosition = end; // Ensure cursor is positioned at end of selected word
-
- ImfManager imfManager = ImfManager::Get();
- if ( imfManager )
- {
- imfManager.SetCursorPosition ( mCursorPosition );
- imfManager.NotifyCursorPosition();
- }
-
- if ( !mStyledText.at(end-1).mText[0].IsWhiteSpace() )
- {
- SelectText( start, end );
- ShowPopupCutCopyPaste();
- }
- else
- {
- RemoveHighlight( false ); // Remove highlight but do not auto hide popup
- HidePopup( false ); // Hide popup with setting to do auto show.
- SetUpPopupSelection( false ); // Set to false so if nearest word is whitespace it will not show cut button.
- ShowPopup();
- }
- }
- else if ( mClipboard && mClipboard.NumberOfItems() )
- {
- ShowPopupCutCopyPaste();
- }
-
- // If no text and clipboard empty then do nothing
-}
-
-// TODO: Change the function name to be more general.
-void TextInput::OnTextTap(Dali::Actor actor, const Dali::TapGesture& tap)
-{
- DALI_LOG_INFO( gLogFilter, Debug::General, "OnTap mPreEditFlag[%s] mEditOnTouch[%s] mEditModeActive[%s] ", (mPreEditFlag)?"true":"false"
- , (mEditOnTouch)?"true":"false"
- , (mEditModeActive)?"true":"false");
-
- if( mHandleOneGrabArea == actor || mHandleTwoGrabArea == actor )
- {
- return;
- }
-
- if( mGrabArea == actor )
- {
- if( mPopupPanel.GetState() == TextInputPopup::StateHidden || mPopupPanel.GetState() == TextInputPopup::StateHiding )
- {
- SetUpPopupSelection();
- ShowPopup();
- }
-
- return;
- }
-
- HidePopup();
- RemoveHighlight();
-
- mTextLayoutInfo.mScrollOffset = mDisplayedTextView.GetScrollPosition();
-
- // Initially don't create the grab handle.
- bool createGrabHandle = false;
-
- if ( !mEditModeActive )
- {
- // update line height before calculate the actual position.
- UpdateLineHeight();
-
- // Only start edit mode if TextInput configured to edit on touch
- if ( mEditOnTouch )
- {
- // Set the initial cursor position in the tap point.
- ReturnClosestIndex(tap.localPoint, mCursorPosition );
- StartEditMode();
- }
- }
- else
- {
- // Show the keyboard if it was hidden.
- if (!VirtualKeyboard::IsVisible())
- {
- VirtualKeyboard::Show();
- }
-
- // Reset keyboard as tap event has occurred.
- // Set true so cursor position is preserved. Otherwise cursor position will that of the committed text not new tap location.
- PreEditReset( true );
-
- GetTextLayoutInfo();
-
- if( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() ) // If string empty we do not need a grab handle.
- {
- // As already in edit mode, reposition cursor near tap and show grab handle for cursor, if grab handle not enabled then magnifier will be used instead.
-
- ReturnClosestIndex(tap.localPoint, mCursorPosition );
-
- DALI_LOG_INFO( gLogFilter, Debug::General, "mCursorPosition[%u]", mCursorPosition );
-
- // Notify keyboard so it can 're-capture' word for predictive text.
- // As we have done a reset, is this required, expect IMF keyboard to request this information.
- ImfManager imfManager = ImfManager::Get();
- if ( imfManager )
- {
- imfManager.SetCursorPosition ( mCursorPosition );
- imfManager.NotifyCursorPosition();
- }
- const TextStyle oldInputStyle( mInputStyle );
-
- mInputStyle = GetStyleAtCursor(); // Inherit style from cursor position
-
- DrawCursor();
-
- // Create the grab handle.
- // Grab handle is created later.
- createGrabHandle = true;
-
- if( oldInputStyle != mInputStyle )
- {
- // Updates the line height accordingly with the input style.
- UpdateLineHeight();
-
- EmitStyleChangedSignal();
- }
- }
- }
-
- // Edit mode started after grab handle created to ensure the signal InputStarted is sent last.
- // This is used to ensure if selecting text hides the grab handle then this code is run after grab handle is created,
- // otherwise the Grab handle will be shown when selecting.
- if ( createGrabHandle && IsGrabHandleEnabled() )
- {
- Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
- bool altPositionValid; // Alternate cursor validity flag.
- bool directionRTL; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
- Vector3 cursorPosition = GetActualPositionFromCharacterPosition( mCursorPosition, directionRTL, altPosition, altPositionValid );
-
- if( altPositionValid )
- {
- // Check which of the positions is the closest.
- if( fabsf( altPosition.x - tap.localPoint.x ) < fabsf( cursorPosition.x - tap.localPoint.x ) )
- {
- cursorPosition = altPosition;
- }
- }
-
- CreateGrabHandle();
-
- mActualGrabHandlePosition.x = cursorPosition.x; // Set grab handle to be at the cursor position
- mActualGrabHandlePosition.y = cursorPosition.y; // Set grab handle to be at the cursor position
- mGrabHandle.SetPosition( mActualGrabHandlePosition + UI_OFFSET );
- ShowGrabHandleAndSetVisibility( mIsGrabHandleInScrollArea );
-
- }
-}
-
-void TextInput::OnLongPress(Dali::Actor actor, const Dali::LongPressGesture& longPress)
-{
- DALI_LOG_INFO( gLogFilter, Debug::General, "OnLongPress\n" );
-
- // Ignore longpress if in selection mode already
- if( mHighlightMeshActor )
- {
- return;
- }
-
- if(longPress.state == Dali::Gesture::Started)
- {
- // Start edit mode on long press
- if ( !mEditModeActive )
- {
- StartEditMode();
- }
-
- // If text exists then select nearest word.
- if ( !mStyledText.empty())
- {
- HidePopup();
-
- ShowGrabHandleAndSetVisibility( false );
-
-
- if ( mPreEditFlag )
- {
- // PreEdit will be committed here without needing a commit from IMF. Remove pre-edit underline and reset flags which
- // converts the pre-edit word being displayed to a committed word.
- if ( !mUnderlinedPriorToPreEdit )
- {
- TextStyle style;
- style.SetUnderline( false );
- ApplyStyleToRange( style, TextStyle::UNDERLINE , mPreEditStartPosition, mPreEditStartPosition + mPreEditLength -1 );
- }
- mPreEditFlag = false;
- mIgnoreCommitFlag = true; // Predictive word interrupted, text displayed will not change, no need to actually commit.
- // Reset keyboard and set true so cursor position is preserved. Otherwise cursor position will that of the committed text not new tap location.
- PreEditReset( false );
- }
- mCursorPosition = 0;
-
- mTextLayoutInfo.mScrollOffset = mDisplayedTextView.GetScrollPosition();
- ReturnClosestIndex( longPress.localPoint, mCursorPosition );
-
- std::size_t start = 0;
- std::size_t end = 0;
- Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
-
- mCursorPosition = end; // Ensure cursor is positioned at end of selected word
-
- ImfManager imfManager = ImfManager::Get();
- if ( imfManager )
- {
- imfManager.SetCursorPosition ( mCursorPosition );
- imfManager.NotifyCursorPosition();
- }
-
- SelectText( start, end );
- }
-
- // if no text but clipboard has content then show paste option, if no text and clipboard empty then do nothing
- if ( ( mClipboard && mClipboard.NumberOfItems() ) || !mStyledText.empty() )
- {
- ShowPopupCutCopyPaste();
- }
- }
-}
-
-void TextInput::OnClipboardTextSelected( ClipboardEventNotifier& notifier )
-{
- const Text clipboardText( notifier.GetContent() );
- PasteText( clipboardText );
-
- SetCursorVisibility( true );
- StartCursorBlinkTimer();
-
- ShowGrabHandleAndSetVisibility( false );
-
-
- HidePopup();
-}
-
-bool TextInput::OnPopupButtonPressed( Toolkit::Button button )
-{
- mPopupPanel.PressedSignal().Disconnect( this, &TextInput::OnPopupButtonPressed );
-
- const std::string& name = button.GetName();
-
- if(name == TextInputPopup::OPTION_SELECT_WORD)
- {
- std::size_t start = 0;
- std::size_t end = 0;
- Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
-
- SelectText( start, end );
- }
- else if(name == TextInputPopup::OPTION_SELECT_ALL)
- {
- SetCursorVisibility(false);
- StopCursorBlinkTimer();
-
- std::size_t end = mTextLayoutInfo.mCharacterLayoutInfoTable.size();
- std::size_t start = 0;
-
- SelectText( start, end );
- }
- else if(name == TextInputPopup::OPTION_CUT)
- {
- bool ret = CopySelectedTextToClipboard();
-
- if ( ret )
- {
- DeleteHighlightedText( true );
- CursorUpdate();
- }
-
- SetCursorVisibility( true );
- StartCursorBlinkTimer();
-
- HidePopup();
- }
- else if(name == TextInputPopup::OPTION_COPY)
- {
- CopySelectedTextToClipboard();
-
- RemoveHighlight();
-
- SetCursorVisibility( true );
- StartCursorBlinkTimer();
-
- HidePopup();
- }
- else if(name == TextInputPopup::OPTION_PASTE)
- {
- const Text retrievedString( mClipboard.GetItem( 0 ) ); // currently can only get first item in clip board, index 0;
-
- PasteText(retrievedString);
-
- SetCursorVisibility( true );
- StartCursorBlinkTimer();
-
- ShowGrabHandleAndSetVisibility( false );
-
- HidePopup();
- }
- else if(name == TextInputPopup::OPTION_CLIPBOARD)
- {
- // In the case of clipboard being shown we do not want to show updated pop-up after hide animation completes
- // Hence pass the false parameter for signalFinished.
- HidePopup( true, false );
- mClipboard.ShowClipboard();
- }
-
- return false;
-}
-
-bool TextInput::OnCursorBlinkTimerTick()
-{
- // Cursor blinking
- mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea && mCursorBlinkStatus );
- if ( mCursorRTLEnabled )
- {
- mCursorRTL.SetVisible( mCursorVisibility && mIsCursorInScrollArea && mCursorBlinkStatus );
- }
- mCursorBlinkStatus = !mCursorBlinkStatus;
-
- return true;
-}
-
-void TextInput::OnPopupHideFinished(TextInputPopup& popup)
-{
- popup.HideFinishedSignal().Disconnect( this, &TextInput::OnPopupHideFinished );
-
- // Change Popup menu to Cut/Copy/Paste if text has been selected.
- if(mHighlightMeshActor && mState == StateEdit)
- {
- ShowPopupCutCopyPaste();
- }
-}
-
-//FIXME this routine needs to be re-written as it contains too many branches.
-bool TextInput::OnKeyDownEvent(const KeyEvent& event)
-{
- std::string keyName = event.keyPressedName;
- std::string keyString = event.keyPressed;
-
- DALI_LOG_INFO(gLogFilter, Debug::General, "OnKeyDownEvent keyName[%s] KeyString[%s]\n", keyName.c_str(), keyString.c_str() );
-
- // Do not consume "Tab" and "Escape" keys.
- if(keyName == "Tab" || keyName == "Escape")
- {
- // Escape key to end the edit mode
- EndEditMode();
-
- return false;
- }
-
- HidePopup(); // If Pop-up shown then hides it as editing text.
-
- // Update Flag, indicates whether to update the text-input contents or not.
- // Any key stroke that results in a visual change of the text-input should
- // set this flag to true.
- bool update(false);
-
- // Whether to scroll text to cursor position.
- // Scroll is needed always the cursor is updated and after the pre-edit is received.
- bool scroll = false;
-
- if (keyName == "Return")
- {
- if ( mNumberOflinesLimit > 1) // Prevents New line character / Return adding an extra line if limit set to 1
- {
- bool preEditFlagPreviouslySet( mPreEditFlag );
-
- // replaces highlighted text with new line
- DeleteHighlightedText( false );
-
- mCursorPosition = mCursorPosition + InsertAt( Text( NEWLINE ), mCursorPosition, 0 );
-
- // If we are in pre-edit mode then pressing enter will cause a commit. But the commit string does not include the
- // '\n' character so we need to ensure that the immediately following commit knows how it occurred.
- if ( mPreEditFlag )
- {
- mCommitByKeyInput = true;
- }
-
- // If attempting to insert a new-line brings us out of PreEdit mode, then we should not ignore the next commit.
- if ( preEditFlagPreviouslySet && !mPreEditFlag )
- {
- mPreEditFlag = true;
- mIgnoreCommitFlag = false;
- }
- EmitTextModified();
- update = true;
- }
- else
- {
- RemoveHighlight();
- }
- } // Return
- else if ( keyName == "space" )
- {
- if ( mHighlightMeshActor )
- {
- // Some text is selected so erase it before adding space.
- DeleteHighlightedText( true );
- }
-
- mCursorPosition = mCursorPosition + InsertAt(Text(keyString), mCursorPosition, 0);
-
- // If we are in pre-edit mode then pressing the space-bar will cause a commit. But the commit string does not include the
- // ' ' character so we need to ensure that the immediately following commit knows how it occurred.
- if ( mPreEditFlag )
- {
- mCommitByKeyInput = true;
- }
- EmitTextModified();
- update = true;
- } // space
- else if (keyName == "BackSpace")
- {
- if ( mHighlightMeshActor )
- {
- // Some text is selected so erase it
- DeleteHighlightedText( true );
- update = true;
- }
- else
- {
- if ( mCursorPosition > 0 )
- {
- DeleteCharacter( mCursorPosition );
- update = true;
- }
- }
- EmitTextModified();
- } // BackSpace
- else if (keyName == "Right")
- {
- AdvanceCursor();
- RemoveHighlight();
- }
- else if (keyName == "Left")
- {
- AdvanceCursor(true);
- RemoveHighlight();
- }
- else // event is a character
- {
- // Some text may be selected, hiding keyboard causes an empty keystring to be sent, we don't want to delete highlight in this case
- if ( !keyString.empty() )
- {
- // replaces highlighted text with new character
- DeleteHighlightedText( false );
-
- // Received key String
- mCursorPosition += InsertAt( Text( keyString ), mCursorPosition, 0 );
- update = true;
- EmitTextModified();
- }
- }
-
- // If key event has resulted in a change in the text/cursor, then trigger a relayout of text
- // as this is a costly operation.
- if(update)
- {
- CursorUpdate();
- }
-
- if(update || scroll)
- {
- if( IsScrollEnabled() )
- {
- // Calculates the new cursor position (in actor coordinates)
- const Vector3 cursorPosition = GetActualPositionFromCharacterPosition( mCursorPosition );
-
- ScrollTextViewToMakeCursorVisible( cursorPosition );
- }
- }
-
- return true;
-}
-
-bool TextInput::OnKeyUpEvent(const KeyEvent& event)
-{
- std::string keyName = event.keyPressedName;
- std::string keyString = event.keyPressed;
-
- DALI_LOG_INFO(gLogFilter, Debug::General, "OnKeyUpEvent keyName[%s] KeyString[%s]\n", keyName.c_str(), keyString.c_str() );
-
- // The selected text become deselected when the key code is DALI_KEY_BACK.
- if( IsTextSelected() && ( keyName == "XF86Stop" || keyName == "XF86Send") )
- {
- DeSelectText();
- return true;
- }
-
- return false;
-}
-
-void TextInput::ChooseRtlSelectionHandlePosition( const Vector3& cursorPositionOne,
- const Vector3& cursorPositionTwo,
- bool altPositionValidOne,
- bool altPositionValidTwo,
- const Vector3& altPositionOne,
- const Vector3& altPositionTwo )
-{
- // TODO VCC Valid for one line.
- // Try to place the selection handles. TODO think in something better. Probably need to know the direction of the paragraph.
- if( cursorPositionOne != cursorPositionTwo )
- {
- if( cursorPositionOne.x < cursorPositionTwo.x )
- {
- mSelectionHandleOneActualPosition = cursorPositionOne;
- mSelectionHandleTwoActualPosition = cursorPositionTwo;
- }
- else
- {
- mSelectionHandleOneActualPosition = cursorPositionTwo;
- mSelectionHandleTwoActualPosition = cursorPositionOne;
- }
- }
- else
- {
- mSelectionHandleOneActualPosition = cursorPositionOne;
- if( altPositionValidOne )
- {
- if( altPositionOne.x < mSelectionHandleOneActualPosition.x )
- {
- mSelectionHandleOneActualPosition = altPositionOne;
- }
- }
- if( altPositionValidTwo )
- {
- if( altPositionTwo.x < mSelectionHandleOneActualPosition.x )
- {
- mSelectionHandleOneActualPosition = altPositionTwo;
- }
- }
-
- mSelectionHandleTwoActualPosition = cursorPositionTwo;
- if( altPositionValidTwo )
- {
- if( altPositionTwo.x > mSelectionHandleTwoActualPosition.x )
- {
- mSelectionHandleTwoActualPosition = altPositionTwo;
- }
- }
- if( altPositionValidOne )
- {
- if( altPositionOne.x > mSelectionHandleTwoActualPosition.x )
- {
- mSelectionHandleTwoActualPosition = altPositionOne;
- }
- }
- }
-}
-
-void TextInput::OnTextViewScrolled( Toolkit::TextView textView, Vector2 scrollPosition )
-{
- // Updates the stored scroll position.
- mTextLayoutInfo.mScrollOffset = textView.GetScrollPosition();
-
- const Vector3& controlSize = GetControlSize();
- Size cursorSize( CURSOR_THICKNESS, 0.f );
-
- // Updates the cursor and grab handle position and visibility.
- if( mGrabHandle || mCursor )
- {
- cursorSize.height = GetRowRectFromCharacterPosition( mCursorPosition ).height;
-
- Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
- bool altPositionValid; // Alternate cursor validity flag.
- bool directionRTL; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
- Vector3 cursorPosition = GetActualPositionFromCharacterPosition( mCursorPosition, directionRTL, altPosition, altPositionValid );
-
- if( altPositionValid )
- {
- // Check which of the positions is the closest.
- if( fabsf( altPosition.x - mActualGrabHandlePosition.x ) < fabsf( cursorPosition.x - mActualGrabHandlePosition.x ) )
- {
- cursorPosition = altPosition;
- }
- }
-
- mIsCursorInScrollArea = mIsGrabHandleInScrollArea = IsPositionInsideBoundaries( cursorPosition, cursorSize, controlSize );
-
- mActualGrabHandlePosition = cursorPosition.GetVectorXY();
-
- if( mGrabHandle )
- {
- ShowGrabHandle( mGrabHandleVisibility && mIsGrabHandleInScrollArea );
- mGrabHandle.SetPosition( mActualGrabHandlePosition + UI_OFFSET );
- }
-
- if( mCursor )
- {
- mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea );
- mCursor.SetPosition( mActualGrabHandlePosition + UI_OFFSET );
- }
- }
-
- // Updates the selection handles and highlighted text position and visibility.
- if( mSelectionHandleOne && mSelectionHandleTwo )
- {
- Vector3 altPositionOne; // Alternate (i.e. opposite direction) cursor position.
- bool altPositionValidOne; // Alternate cursor validity flag.
- bool directionRTLOne; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
- Vector3 cursorPositionOne = GetActualPositionFromCharacterPosition( mSelectionHandleOnePosition, directionRTLOne, altPositionOne, altPositionValidOne );
-
- Vector3 altPositionTwo; // Alternate (i.e. opposite direction) cursor position.
- bool altPositionValidTwo; // Alternate cursor validity flag.
- bool directionRTLTwo; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
- Vector3 cursorPositionTwo = GetActualPositionFromCharacterPosition( mSelectionHandleTwoPosition, directionRTLTwo, altPositionTwo, altPositionValidTwo );
-
- // VCC TODO: This method is a hack for one line.
- ChooseRtlSelectionHandlePosition( cursorPositionOne,
- cursorPositionTwo,
- altPositionValidOne,
- altPositionValidTwo,
- altPositionOne,
- altPositionTwo );
-
- cursorSize.height = ( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + mSelectionHandleOnePosition ) ).mSize.height;
- const bool isSelectionHandleOneVisible = IsPositionInsideBoundaries( cursorPositionOne, cursorSize, controlSize );
- cursorSize.height = ( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + mSelectionHandleTwoPosition ) ).mSize.height;
- const bool isSelectionHandleTwoVisible = IsPositionInsideBoundaries( cursorPositionTwo, cursorSize, controlSize );
-
- mSelectionHandleOne.SetVisible( isSelectionHandleOneVisible );
- mSelectionHandleTwo.SetVisible( isSelectionHandleTwoVisible );
- mSelectionHandleOne.SetPosition( mSelectionHandleOneActualPosition + UI_OFFSET + mSelectionHandleOneOffset );
- mSelectionHandleTwo.SetPosition( mSelectionHandleTwoActualPosition + UI_OFFSET + mSelectionHandleTwoOffset );
-
- if( mHighlightMeshActor )
- {
- mHighlightMeshActor.SetVisible( true );
- UpdateHighlight();
- }
- }
-}
-
-void TextInput::ScrollTextViewToMakeCursorVisible( const Vector3& cursorPosition )
-{
- // Scroll the text to make the cursor visible.
- const Size cursorSize( CURSOR_THICKNESS,
- GetRowRectFromCharacterPosition( mCursorPosition ).height );
-
- // Need to scroll the text to make the cursor visible and to cover the whole text-input area.
-
- const Vector3& controlSize = GetControlSize();
-
- // Calculates the new scroll position.
- Vector2 scrollOffset = mTextLayoutInfo.mScrollOffset;
- if( ( cursorPosition.x < 0.f ) || ( cursorPosition.x > controlSize.width ) )
- {
- scrollOffset.x += cursorPosition.x;
- }
-
- if( cursorPosition.y - cursorSize.height < 0.f || cursorPosition.y > controlSize.height )
- {
- scrollOffset.y += cursorPosition.y;
- }
-
- // Sets the new scroll position.
- SetScrollPosition( Vector2::ZERO ); // TODO: need to reset to the zero position in order to make the scroll trim to work.
- SetScrollPosition( scrollOffset );
-}
-
-void TextInput::StartScrollTimer()
-{
- if( !mScrollTimer )
- {
- mScrollTimer = Timer::New( SCROLL_TICK_INTERVAL );
- mScrollTimer.TickSignal().Connect( this, &TextInput::OnScrollTimerTick );
- }
-
- if( !mScrollTimer.IsRunning() )
- {
- mScrollTimer.Start();
- }
-}
-
-void TextInput::StopScrollTimer()
-{
- if( mScrollTimer )
- {
- mScrollTimer.Stop();
- }
-}
-
-bool TextInput::OnScrollTimerTick()
-{
- // TODO: need to set the new style accordingly the new handle position.
-
- if( !( mGrabHandleVisibility && mGrabHandle ) && !( mSelectionHandleOne && mSelectionHandleTwo ) )
- {
- // nothing to do if all handles are invisible or doesn't exist.
- return true;
- }
-
- // Text scrolling
-
- // Choose between the grab handle or the selection handles.
- Vector3& actualHandlePosition = ( mGrabHandleVisibility && mGrabHandle ) ? mActualGrabHandlePosition : ( mCurrentSelectionId == HandleOne ) ? mSelectionHandleOneActualPosition : mSelectionHandleTwoActualPosition;
- std::size_t& handlePosition = ( mGrabHandleVisibility && mGrabHandle ) ? mCursorPosition : ( mCurrentSelectionId == HandleOne ) ? mSelectionHandleOnePosition : mSelectionHandleTwoPosition;
- Vector3& currentHandlePosition = ( mGrabHandleVisibility && mGrabHandle ) ? mCurrentHandlePosition : mCurrentSelectionHandlePosition;
-
- std::size_t newCursorPosition = 0;
- ReturnClosestIndex( actualHandlePosition.GetVectorXY(), newCursorPosition );
-
- // Whether the handle's position is different of the previous one and in the case of the selection handle,
- // the new selection handle's position needs to be different of the other one.
- const bool differentSelectionHandles = ( mGrabHandleVisibility && mGrabHandle ) ? newCursorPosition != handlePosition :
- ( mCurrentSelectionId == HandleOne ) ? ( newCursorPosition != handlePosition ) && ( newCursorPosition != mSelectionHandleTwoPosition ) :
- ( newCursorPosition != handlePosition ) && ( newCursorPosition != mSelectionHandleOnePosition );
-
- if( differentSelectionHandles )
- {
- handlePosition = newCursorPosition;
-
- const Vector3 actualPosition = GetActualPositionFromCharacterPosition( newCursorPosition );
-
- Vector2 scrollDelta = ( actualPosition - currentHandlePosition ).GetVectorXY();
-
- Vector2 scrollPosition = mDisplayedTextView.GetScrollPosition();
- scrollPosition += scrollDelta;
- SetScrollPosition( scrollPosition );
-
- if( mDisplayedTextView.IsScrollPositionTrimmed() )
- {
- StopScrollTimer();
- }
-
- currentHandlePosition = GetActualPositionFromCharacterPosition( newCursorPosition ).GetVectorXY();
- }
-
- actualHandlePosition.x += mScrollDisplacement.x;
- actualHandlePosition.y += mScrollDisplacement.y;
-
- return true;
-}
-
-// Public Internal Methods (public for testing purpose)
-
-void TextInput::SetUpTouchEvents()
-{
- if ( !mTapDetector )
- {
- mTapDetector = TapGestureDetector::New();
- // Attach the actors and connect the signal
- mTapDetector.Attach(Self());
-
- // As contains children which may register for tap the default control detector is not used.
- mTapDetector.DetectedSignal().Connect(this, &TextInput::OnTextTap);
- }
-
- if ( !mDoubleTapDetector )
- {
- mDoubleTapDetector = TapGestureDetector::New( 2 );
- mDoubleTapDetector.DetectedSignal().Connect(this, &TextInput::OnDoubleTap);
-
- // Only attach and detach the actor to the double tap detector when we enter/leave edit mode
- // so that we do not, unnecessarily, have a double tap request all the time
- }
-
- if ( !mPanGestureDetector )
- {
- mPanGestureDetector = PanGestureDetector::New();
- mPanGestureDetector.DetectedSignal().Connect(this, &TextInput::OnHandlePan);
- }
-
- if ( !mLongPressDetector )
- {
- mLongPressDetector = LongPressGestureDetector::New();
- mLongPressDetector.DetectedSignal().Connect(this, &TextInput::OnLongPress);
- mLongPressDetector.Attach(Self());
- }
-}
-
-void TextInput::CreateTextViewActor()
-{
- mDisplayedTextView = Toolkit::TextView::New();
- mDisplayedTextView.SetName( "DisplayedTextView ");
- mDisplayedTextView.SetMarkupProcessingEnabled( mMarkUpEnabled );
- mDisplayedTextView.SetParentOrigin(ParentOrigin::TOP_LEFT);
- mDisplayedTextView.SetAnchorPoint(AnchorPoint::TOP_LEFT);
- mDisplayedTextView.SetMultilinePolicy(Toolkit::TextView::SplitByWord);
- mDisplayedTextView.SetWidthExceedPolicy( Toolkit::TextView::Original );
- mDisplayedTextView.SetHeightExceedPolicy( Toolkit::TextView::Original );
- mDisplayedTextView.SetLineJustification( Toolkit::TextView::Left );
- mDisplayedTextView.SetTextAlignment( static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalLeft | Toolkit::Alignment::VerticalTop ) );
- mDisplayedTextView.SetPosition( Vector3( 0.0f, 0.0f, DISPLAYED_TEXT_VIEW_Z_OFFSET ) );
- mDisplayedTextView.SetSizePolicy( Toolkit::Control::Fixed, Toolkit::Control::Fixed );
-
- mDisplayedTextView.ScrolledSignal().Connect( this, &TextInput::OnTextViewScrolled );
-
- Self().Add( mDisplayedTextView );
-}
-
-// Start a timer to initiate, used by the cursor to blink.
-void TextInput::StartCursorBlinkTimer()
-{
- if ( !mCursorBlinkTimer )
- {
- mCursorBlinkTimer = Timer::New( CURSOR_BLINK_INTERVAL );
- mCursorBlinkTimer.TickSignal().Connect( this, &TextInput::OnCursorBlinkTimerTick );
- }
-
- if ( !mCursorBlinkTimer.IsRunning() )
- {
- mCursorBlinkTimer.Start();
- }
-}
-
-// Start a timer to initiate, used by the cursor to blink.
-void TextInput::StopCursorBlinkTimer()
-{
- if ( mCursorBlinkTimer )
- {
- mCursorBlinkTimer.Stop();
- }
-}
-
-void TextInput::StartEditMode()
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextInput StartEditMode mEditModeActive[%s]\n", (mEditModeActive)?"true":"false" );
-
- if(!mEditModeActive)
- {
- SetKeyInputFocus();
- }
-
- if ( mDoubleTapDetector )
- {
- mDoubleTapDetector.Attach( Self() );
- }
-}
-
-void TextInput::EndEditMode()
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextInput EndEditMode mEditModeActive[%s]\n", (mEditModeActive)?"true":"false" );
-
- ClearKeyInputFocus();
-
- if ( mDoubleTapDetector )
- {
- mDoubleTapDetector.Detach( Self() );
- }
-}
-
-void TextInput::ApplyPreEditStyle( std::size_t preEditStartPosition, std::size_t preEditStringLength )
-{
- if ( mPreEditFlag && ( preEditStringLength > 0 ) )
- {
- mUnderlinedPriorToPreEdit = mInputStyle.IsUnderlineEnabled();
- TextStyle style;
- style.SetUnderline( true );
- ApplyStyleToRange( style, TextStyle::UNDERLINE , preEditStartPosition, preEditStartPosition + preEditStringLength -1 );
- }
-}
-
-void TextInput::RemovePreEditStyle()
-{
- if ( !mUnderlinedPriorToPreEdit )
- {
- TextStyle style;
- style.SetUnderline( false );
- SetActiveStyle( style, TextStyle::UNDERLINE );
- }
-}
-
-// IMF related methods
-
-
-ImfManager::ImfCallbackData TextInput::ImfEventReceived( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
-{
- bool update( false );
- bool preeditResetRequired ( false );
-
- if (imfEvent.eventName != ImfManager::GETSURROUNDING )
- {
- HidePopup(); // If Pop-up shown then hides it as editing text.
- }
-
- switch ( imfEvent.eventName )
- {
- case ImfManager::PREEDIT:
- {
- mIgnoreFirstCommitFlag = false;
-
- // Some text may be selected, hiding keyboard causes an empty predictive string to be sent, we don't want to delete highlight in this case
- if ( mHighlightMeshActor && (!imfEvent.predictiveString.empty()) )
- {
- // replaces highlighted text with new character
- DeleteHighlightedText( false );
- }
-
- preeditResetRequired = PreEditReceived( imfEvent.predictiveString, imfEvent.cursorOffset );
-
- if( IsScrollEnabled() )
- {
- // Calculates the new cursor position (in actor coordinates)
- const Vector3 cursorPosition = GetActualPositionFromCharacterPosition( mCursorPosition );
- ScrollTextViewToMakeCursorVisible( cursorPosition );
- }
-
- update = true;
-
- break;
- }
- case ImfManager::COMMIT:
- {
- if( mIgnoreFirstCommitFlag )
- {
- // Do not commit in this case when keyboard sends a commit when shows for the first time (work-around for imf keyboard).
- mIgnoreFirstCommitFlag = false;
- }
- else
- {
- // A Commit message is a word that has been accepted, it may have been a pre-edit word previously but now commited.
-
- // Some text may be selected, hiding keyboard causes an empty predictive string to be sent, we don't want to delete highlight in this case
- if ( mHighlightMeshActor && (!imfEvent.predictiveString.empty()) )
- {
- // replaces highlighted text with new character
- DeleteHighlightedText( false );
- }
-
- // A PreEditReset can cause a commit message to be sent, the Ignore Commit flag is used in scenarios where the word is
- // not needed, one such scenario is when the pre-edit word is too long to fit.
- if ( !mIgnoreCommitFlag )
- {
- update = CommitReceived( imfEvent.predictiveString );
- }
- else
- {
- mIgnoreCommitFlag = false; // reset ignore flag so next commit is acted upon.
- }
- }
-
- if( update )
- {
- if( IsScrollEnabled() )
- {
- // Calculates the new cursor position (in actor coordinates)
- const Vector3 cursorPosition = GetActualPositionFromCharacterPosition( mCursorPosition );
-
- ScrollTextViewToMakeCursorVisible( cursorPosition );
- }
- }
- break;
- }
- case ImfManager::DELETESURROUNDING:
- {
- DALI_LOG_INFO( gLogFilter, Debug::General, "ImfEventReceived - delete surrounding mPreEditFlag[%s] cursor offset[%d] characters to delete[%d] position to delete[%u] \n",
- (mPreEditFlag)?"true":"false", imfEvent.cursorOffset, imfEvent.numberOfChars, static_cast<std::size_t>( mCursorPosition+imfEvent.cursorOffset) );
-
- mPreEditFlag = false;
-
- std::size_t toDelete = 0;
- std::size_t numberOfCharacters = 0;
-
- if( mHighlightMeshActor )
- {
- // delete highlighted text.
- toDelete = std::min( mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
- numberOfCharacters = std::max( mSelectionHandleOnePosition, mSelectionHandleTwoPosition ) - toDelete;
- }
- else
- {
- if( static_cast<std::size_t>(std::abs( imfEvent.cursorOffset )) < mCursorPosition )
- {
- toDelete = mCursorPosition + imfEvent.cursorOffset;
- }
- if( toDelete + imfEvent.numberOfChars > mStyledText.size() )
- {
- numberOfCharacters = mStyledText.size() - toDelete;
- }
- else
- {
- numberOfCharacters = imfEvent.numberOfChars;
- }
- }
- DALI_LOG_INFO( gLogFilter, Debug::General, "ImfEventReceived - deleteSurrounding pre-delete range mCursorPosition[%u] \n", mCursorPosition);
- DeleteRange( toDelete, numberOfCharacters );
-
- mCursorPosition = toDelete;
- mNumberOfSurroundingCharactersDeleted = numberOfCharacters;
-
- EmitTextModified();
-
- DALI_LOG_INFO( gLogFilter, Debug::General, "ImfEventReceived - deleteSurrounding post-delete range mCursorPosition[%u] \n", mCursorPosition);
- break;
- }
- case ImfManager::GETSURROUNDING:
- {
- // If text is selected/highlighted and surrounding text received we do not want the keyboard to store the word at cursor and return it as a predictive word along with
- // the next key pressed. Instead the Select function sets the cursor position and surrounding text.
- if (! ( mHighlightMeshActor || mSelectingText ) )
- {
- std::string text( GetText() );
- DALI_LOG_INFO( gLogFilter, Debug::General, "OnKey - surrounding text - set text [%s] and cursor[%u] \n", text.c_str(), mCursorPosition );
-
- imfManager.SetCursorPosition( mCursorPosition );
- imfManager.SetSurroundingText( text );
- }
-
- if( 0 != mNumberOfSurroundingCharactersDeleted )
- {
- mDisplayedTextView.RemoveTextFrom( mCursorPosition, mNumberOfSurroundingCharactersDeleted );
- mNumberOfSurroundingCharactersDeleted = 0;
-
- if( mStyledText.empty() )
- {
- ShowPlaceholderText( mStyledPlaceHolderText );
- }
- }
- break;
- }
- case ImfManager::VOID:
- {
- DALI_ASSERT_DEBUG( false );
- }
- } // end switch
-
- ImfManager::ImfCallbackData callbackData( update, mCursorPosition, GetText(), preeditResetRequired );
-
- return callbackData;
-}
-
-bool TextInput::PreEditReceived(const std::string& keyString, std::size_t cursorOffset )
-{
- mPreserveCursorPosition = false; // As in pre-edit state we should have the cursor at the end of the word displayed not last touch position.
-
- DALI_LOG_INFO(gLogFilter, Debug::General, ">>PreEditReceived preserveCursorPos[%d] mCursorPos[%d] mPreEditFlag[%d]\n",
- mPreserveCursorPosition, mCursorPosition, mPreEditFlag );
-
- bool preeditResetRequest ( false );
-
- if( mPreEditFlag ) // Already in pre-edit state.
- {
- if( mStyledText.size() >= mMaxStringLength )
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, "PreEditReceived styledTextSize >= mMaxStringLength \n");
- // Cannot fit these characters into field, clear pre-edit.
- if ( !mUnderlinedPriorToPreEdit )
- {
- TextStyle style;
- style.SetUnderline( false );
- ApplyStyleToRange( style, TextStyle::UNDERLINE , mPreEditStartPosition, mPreEditStartPosition + mPreEditLength -1 );
- }
- mIgnoreCommitFlag = true;
- preeditResetRequest = false; // this will reset the keyboard's predictive suggestions.
- mPreEditFlag = false;
- EmitMaxInputCharactersReachedSignal();
- }
- else
- {
- // delete existing pre-edit string
- const std::size_t numberOfCharactersToReplace = DeletePreEdit();
-
- // Store new pre-edit string
- mPreEditString.SetText( keyString );
-
- if ( keyString.empty() )
- {
- mPreEditFlag = false;
- mCursorPosition = mPreEditStartPosition;
-
- if( mStyledText.empty() )
- {
- ShowPlaceholderText( mStyledPlaceHolderText );
- }
- else
- {
- mDisplayedTextView.RemoveTextFrom( mPreEditStartPosition, numberOfCharactersToReplace );
- }
-
- GetTextLayoutInfo();
- EmitTextModified();
- }
- else
- {
- // Insert new pre-edit string. InsertAt updates the size and position table.
- mPreEditLength = InsertAt( mPreEditString, mPreEditStartPosition, numberOfCharactersToReplace );
- // If word was too long to be inserted then cursorOffset would be out of range as keyboard assumes there is not limit. Hence use of std::min.
- mCursorPosition = mPreEditStartPosition + std::min( cursorOffset, mPreEditLength );
- ApplyPreEditStyle( mPreEditStartPosition, mPreEditLength );
- DALI_LOG_INFO(gLogFilter, Debug::General, "PreEditReceived mCursorPosition[%u] \n", mCursorPosition);
- EmitTextModified();
- }
- // cursor update to keyboard is not done here as the keyboard knows the cursor position and provides the 'cursorOffset'.
- DrawCursor();
- }
- }
- else // mPreEditFlag not set
- {
- if ( !keyString.empty() ) // Imf can send an empty pre-edit followed by Backspace instead of a commit.
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, "PreEditReceived Initial Pre-Edit string \n");
- // new pre-edit so move into pre-edit state by setting flag
- mPreEditFlag = true;
- mPreEditString.SetText( keyString ); // store new pre-edit string
- mPreEditStartPosition = mCursorPosition; // store starting cursor position of pre-edit so know where to re-start from
- mPreEditLength = InsertAt( mPreEditString, mPreEditStartPosition, 0 );
- // If word was too long to be inserted then cursorOffset would be out of range as keyboard assumes there is not limit. Hence use of std::min.
- mCursorPosition = mPreEditStartPosition + std::min( cursorOffset, mPreEditLength );
- ApplyPreEditStyle( mPreEditStartPosition, mPreEditLength );
- DALI_LOG_INFO(gLogFilter, Debug::General, "PreEditReceived mCursorPosition[%u] mPreEditStartPosition[%u]\n", mCursorPosition, mPreEditStartPosition);
- // cursor update to keyboard is not done here as the keyboard knows the cursor position and provides the 'cursorOffset'.
- DrawCursor();
- EmitTextModified();
- }
- else
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, "PreEditReceived with empty keyString\n");
- }
- }
-
- return preeditResetRequest;
-}
-
-bool TextInput::CommitReceived(const std::string& keyString )
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, ">>CommitReceived preserveCursorPos[%d] mPreEditStartPosition [%d] mCursorPos[%d] mPreEditFlag[%d] mIgnoreCommitFlag[%s]\n",
- mPreserveCursorPosition, mPreEditStartPosition, mCursorPosition, mPreEditFlag, (mIgnoreCommitFlag)?"true":"false" );
-
- bool update( false );
-
- RemovePreEditStyle();
-
- const std::size_t styledTextSize( mStyledText.size() );
- if( styledTextSize >= mMaxStringLength )
- {
- // Cannot fit these characters into field, clear pre-edit.
- if ( mPreEditFlag )
- {
- mIgnoreCommitFlag = true;
- mPreEditFlag = false;
- }
- EmitMaxInputCharactersReachedSignal();
- }
- else
- {
- if( mPreEditFlag )
- {
- // delete existing pre-edit string
- const std::size_t numberOfCharactersToReplace = DeletePreEdit();
- mPreEditFlag = false;
-
- DALI_LOG_INFO(gLogFilter, Debug::General, "CommitReceived mPreserveCursorPosition[%s] mPreEditStartPosition[%u]\n",
- (mPreserveCursorPosition)?"true":"false", mPreEditStartPosition );
-
- if ( mPreserveCursorPosition ) // PreEditReset has been called triggering this commit.
- {
- // No need to update cursor position as Cursor location given by touch.
- InsertAt( Text( keyString ), mPreEditStartPosition, numberOfCharactersToReplace );
- mPreserveCursorPosition = false;
- }
- else
- {
- // Cursor not set by touch so needs to be re-positioned to input more text
- mCursorPosition = mPreEditStartPosition + InsertAt( Text(keyString), mPreEditStartPosition, numberOfCharactersToReplace ); // update cursor position as InsertAt, re-draw cursor with this
-
- // If a space or enter caused the commit then our string is one longer than the string given to us by the commit key.
- if ( mCommitByKeyInput )
- {
- mCursorPosition = std::min ( mCursorPosition + 1, mStyledText.size() );
- mCommitByKeyInput = false;
- }
- }
-
- EmitTextModified();
-
- if ( mSelectTextOnCommit )
- {
- SelectText(mRequestedSelection.mStartOfSelection, mRequestedSelection.mEndOfSelection );
- }
-
- update = true;
- }
- else // mPreEditFlag not set
- {
- if ( !mIgnoreCommitFlag ) // Check if this commit should be ignored.
- {
- if( mStyledText.empty() && mPlaceHolderSet )
- {
- // If the styled text is empty and the placeholder text is set, it needs to be cleared.
- mDisplayedTextView.SetText( "" );
- mNumberOfSurroundingCharactersDeleted = 0;
- mPlaceHolderSet = false;
- }
- mCursorPosition = mCursorPosition + InsertAt( Text( keyString ), mCursorPosition, mNumberOfSurroundingCharactersDeleted );
- update = true;
- mNumberOfSurroundingCharactersDeleted = 0;
- EmitTextModified();
- }
- else
- {
- mIgnoreCommitFlag = false; // Reset flag so future commits will not be ignored.
- }
- }
- }
-
- mSelectTextOnCommit = false;
-
- DALI_LOG_INFO(gLogFilter, Debug::General, "CommitReceived << mCursorPos[%d] mPreEditFlag[%d] update[%s] \n",
- mCursorPosition, mPreEditFlag, (update)?"true":"false" );
-
- return update;
-}
-
-// End of IMF related methods
-
-std::size_t TextInput::DeletePreEdit()
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, ">>DeletePreEdit mPreEditFlag[%s] \n", (mPreEditFlag)?"true":"false");
-
- DALI_ASSERT_DEBUG( mPreEditFlag );
-
- const std::size_t preEditStringLength = mPreEditString.GetLength();
- const std::size_t styledTextSize = mStyledText.size();
-
- std::size_t endPosition = mPreEditStartPosition + preEditStringLength;
-
- // Prevents erase items outside mStyledText bounds.
- if( mPreEditStartPosition > styledTextSize )
- {
- DALI_ASSERT_DEBUG( !"TextInput::DeletePreEdit. mPreEditStartPosition > mStyledText.size()" );
- mPreEditStartPosition = styledTextSize;
- }
-
- if( ( endPosition > styledTextSize ) || ( endPosition < mPreEditStartPosition ) )
- {
- DALI_ASSERT_DEBUG( !"TextInput::DeletePreEdit. ( endPosition > mStyledText.size() ) || ( endPosition < mPreEditStartPosition )" );
- endPosition = styledTextSize;
- }
-
- mStyledText.erase( mStyledText.begin() + mPreEditStartPosition, mStyledText.begin() + endPosition );
-
- // DeletePreEdit() doesn't remove characters from the text-view because may be followed by an InsertAt() which inserts characters,
- // in that case, the Insert should use the returned number of deleted characters and replace the text which helps the text-view to
- // reuse glyphs.
- // In case DeletePreEdit() is not followed by an InsertAt() characters must be deleted after this call.
-
- return preEditStringLength;
-}
-
-void TextInput::PreEditReset( bool preserveCursorPosition )
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, "PreEditReset preserveCursorPos[%d] mCursorPos[%d] \n",
- preserveCursorPosition, mCursorPosition);
-
- // Store flag to indicate that we do not want to lose the cursor position as the reset may have occurred due to touch event moving the cursor.
- mPreserveCursorPosition = preserveCursorPosition;
-
- // Reset incase we are in a pre-edit state.
- ImfManager imfManager = ImfManager::Get();
- if ( imfManager )
- {
- imfManager.Reset(); // Will trigger a commit message
- }
-}
-
-void TextInput::CursorUpdate()
-{
- DrawCursor();
-
- ImfManager imfManager = ImfManager::Get();
- if ( imfManager )
- {
- std::string text( GetText() );
- imfManager.SetSurroundingText( text ); // Notifying IMF of a cursor change triggers a surrounding text request so updating it now.
- imfManager.SetCursorPosition ( mCursorPosition );
- imfManager.NotifyCursorPosition();
- }
-}
-
-/* Delete highlighted characters redisplay*/
-void TextInput::DeleteHighlightedText( bool inheritStyle )
-{
- DALI_LOG_INFO( gLogFilter, Debug::General, "DeleteHighlightedText handlePosOne[%u] handlePosTwo[%u]\n", mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
-
- if( mHighlightMeshActor )
- {
- mCursorPosition = std::min( mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
-
- MarkupProcessor::StyledTextArray::iterator start = mStyledText.begin() + mCursorPosition;
- MarkupProcessor::StyledTextArray::iterator end = mStyledText.begin() + std::max( mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
-
- // Get the styled text of the characters to be deleted as it may be needed if
- // the "exceed the text-input's boundaries" option is disabled.
- MarkupProcessor::StyledTextArray styledCharactersToDelete;
-
- styledCharactersToDelete.insert( styledCharactersToDelete.begin(), start, end );
-
- mStyledText.erase( start, end ); // erase range of characters
-
- // Remove text from TextView and update place holder text if required
-
- // Set the placeholder text only if the styled text is empty.
- if( mStyledText.empty() )
- {
- ShowPlaceholderText( mStyledPlaceHolderText );
- }
- else
- {
- const std::size_t numberOfCharacters = std::max( mSelectionHandleOnePosition, mSelectionHandleTwoPosition ) - mCursorPosition;
-
- mDisplayedTextView.RemoveTextFrom( mCursorPosition, numberOfCharacters );
-
- // It may happen than after removing a white space or a new line character,
- // two words merge, this new word could be big enough to not fit in its
- // current line, so moved to the next one, and make some part of the text to
- // exceed the text-input's boundary.
- if( !mExceedEnabled )
- {
- // Get the new text layout after removing some characters.
- mDisplayedTextView.GetTextLayoutInfo( mTextLayoutInfo );
-
- // Get text-input's size.
- const Vector3& size = GetControlSize();
-
- if( ( mTextLayoutInfo.mTextSize.width > size.width ) ||
- ( mTextLayoutInfo.mTextSize.height > size.height ) )
- {
- mDisplayedTextView.InsertTextAt( mCursorPosition, styledCharactersToDelete );
-
- mStyledText.insert( mStyledText.begin() + mCursorPosition,
- styledCharactersToDelete.begin(),
- styledCharactersToDelete.end() );
- }
- }
- }
- GetTextLayoutInfo();
-
- RemoveHighlight();
-
- EmitTextModified();
-
- if( inheritStyle )
- {
- const TextStyle oldInputStyle( mInputStyle );
-
- mInputStyle = GetStyleAtCursor(); // Inherit style from cursor position
-
- if( oldInputStyle != mInputStyle )
- {
- // Updates the line height accordingly with the input style.
- UpdateLineHeight();
-
- EmitStyleChangedSignal();
- }
- }
- }
-}
-
-void TextInput::DeleteRange( const std::size_t start, const std::size_t ncharacters )
-{
- DALI_ASSERT_DEBUG( start <= mStyledText.size() );
- DALI_ASSERT_DEBUG( !mStyledText.empty() );
-
- DALI_LOG_INFO(gLogFilter, Debug::General, ">>DeleteRange pre mStyledText[%s] mPreEditFlag[%s] \n", GetText().c_str(), (mPreEditFlag)?"true":"false");
-
-
- if ( ( !mStyledText.empty()) && ( ( start + ncharacters ) <= mStyledText.size() ) )
- {
- MarkupProcessor::StyledTextArray::iterator itStart = mStyledText.begin() + start;
- MarkupProcessor::StyledTextArray::iterator itEnd = mStyledText.begin() + start + ncharacters;
-
- mStyledText.erase(itStart, itEnd);
-
- // update the selection handles if they are visible.
- if( mHighlightMeshActor )
- {
- std::size_t& minHandle = ( mSelectionHandleOnePosition <= mSelectionHandleTwoPosition ? mSelectionHandleOnePosition : mSelectionHandleTwoPosition );
- std::size_t& maxHandle = ( mSelectionHandleTwoPosition > mSelectionHandleOnePosition ? mSelectionHandleTwoPosition : mSelectionHandleOnePosition );
-
- if( minHandle >= start + ncharacters )
- {
- minHandle -= ncharacters;
- }
- else if( ( minHandle > start ) && ( minHandle < start + ncharacters ) )
- {
- minHandle = start;
- }
-
- if( maxHandle >= start + ncharacters )
- {
- maxHandle -= ncharacters;
- }
- else if( ( maxHandle > start ) && ( maxHandle < start + ncharacters ) )
- {
- maxHandle = start;
- }
- }
-
- // Set text is not called here as currently it can not process the set text from deletion and then the set text from the in-coming pre-edit.
- }
-
- DALI_LOG_INFO(gLogFilter, Debug::General, "DeleteRange<< post mStyledText[%s] mPreEditFlag[%s] \n", GetText().c_str(), (mPreEditFlag)?"true":"false");
-
- // Although mStyledText has been set to a new text string we no longer re-draw the text or notify the cursor change.
- // This is a performance decision as the use of this function often means the text is being replaced or just deleted.
- // Mean we do not re-draw the text more than we have too.
-}
-
-/* Delete character at current cursor position and redisplay*/
-void TextInput::DeleteCharacter( std::size_t positionToDelete )
-{
- // Ensure positionToDelete is not out of bounds.
- DALI_ASSERT_DEBUG( positionToDelete <= mStyledText.size() );
- DALI_ASSERT_DEBUG( !mStyledText.empty() );
- DALI_ASSERT_DEBUG( positionToDelete > 0 );
-
- DALI_LOG_INFO(gLogFilter, Debug::General, "DeleteCharacter positionToDelete[%u]", positionToDelete );
-
-
- if ( ( !mStyledText.empty()) && ( positionToDelete > 0 ) && positionToDelete <= mStyledText.size() ) // don't try to delete if no characters left of cursor
- {
- MarkupProcessor::StyledTextArray::iterator it = mStyledText.begin() + positionToDelete - 1;
-
- // Get the styled text of the character to be deleted as it may be needed if
- // the "exceed the text-input's boundaries" option is disabled.
- const MarkupProcessor::StyledText styledCharacterToDelete( *it );
-
- mStyledText.erase(it); // erase the character left of positionToDelete
-
- if( mStyledText.empty() )
- {
- ShowPlaceholderText( mStyledPlaceHolderText );
- }
- else
- {
- mDisplayedTextView.RemoveTextFrom( positionToDelete - 1, 1 );
-
- const Character characterToDelete = styledCharacterToDelete.mText[0];
-
- // It may happen than after removing a white space or a new line character,
- // two words merge, this new word could be big enough to not fit in its
- // current line, so moved to the next one, and make some part of the text to
- // exceed the text-input's boundary.
- if( !mExceedEnabled )
- {
- if( characterToDelete.IsWhiteSpace() || characterToDelete.IsNewLine() )
- {
- // Get the new text layout after removing one character.
- mDisplayedTextView.GetTextLayoutInfo( mTextLayoutInfo );
-
- // Get text-input's size.
- const Vector3& size = GetControlSize();
-
- if( ( mTextLayoutInfo.mTextSize.width > size.width ) ||
- ( mTextLayoutInfo.mTextSize.height > size.height ) )
- {
- MarkupProcessor::StyledTextArray array;
- array.push_back( styledCharacterToDelete );
- mDisplayedTextView.InsertTextAt( positionToDelete - 1, array );
-
- mStyledText.insert( mStyledText.begin() + ( positionToDelete - 1 ), styledCharacterToDelete );
- }
- }
- }
- }
- GetTextLayoutInfo();
-
- ShowGrabHandleAndSetVisibility( false );
-
- mCursorPosition = positionToDelete -1;
-
- const TextStyle oldInputStyle( mInputStyle );
-
- mInputStyle = GetStyleAtCursor(); // Inherit style from cursor position
-
- if( oldInputStyle != mInputStyle )
- {
- // Updates the line height accordingly with the input style.
- UpdateLineHeight();
-
- EmitStyleChangedSignal();
- }
- }
-}
-
-/*Insert new character into the string and (optionally) redisplay text-input*/
-std::size_t TextInput::InsertAt( const Text& newText, const std::size_t insertionPosition, const std::size_t numberOfCharactersToReplace )
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, "InsertAt insertionPosition[%u]\n", insertionPosition );
-
- // Ensure insertionPosition is not out of bounds.
- DALI_ASSERT_ALWAYS( insertionPosition <= mStyledText.size() );
-
- bool textExceedsMaximunNumberOfCharacters = false;
- bool textExceedsBoundary = false;
- std::size_t insertedStringLength = DoInsertAt( newText, insertionPosition, numberOfCharactersToReplace, textExceedsMaximunNumberOfCharacters, textExceedsBoundary );
-
- ShowGrabHandleAndSetVisibility( false );
-
- if( textExceedsMaximunNumberOfCharacters || textExceedsBoundary )
- {
- if( mPreEditFlag )
- {
- mIgnoreCommitFlag = true;
- mPreEditFlag = false;
- // A PreEditReset( false ) should be triggered from here if the keyboards predictive suggestions must be cleared.
- // Although can not directly call PreEditReset() as it will cause a recursive emit loop.
- }
-
- if( textExceedsMaximunNumberOfCharacters )
- {
- EmitMaxInputCharactersReachedSignal();
- }
-
- if( textExceedsBoundary )
- {
- EmitInputTextExceedsBoundariesSignal();
- PreEditReset( false );
- }
- }
-
- return insertedStringLength;
-}
-
-ImageActor TextInput::CreateCursor( const Vector4& color)
-{
- ImageActor cursor;
- cursor = CreateSolidColorActor(color);
- cursor.SetName( "Cursor" );
-
- cursor.SetParentOrigin(ParentOrigin::TOP_LEFT);
- cursor.SetAnchorPoint(AnchorPoint::BOTTOM_LEFT);
- cursor.SetVisible(false);
-
- return cursor;
-}
-
-void TextInput::AdvanceCursor(bool reverse, std::size_t places)
-{
- // As cursor is not moving due to grab handle, handle should be hidden.
- ShowGrabHandleAndSetVisibility( false );
-
- bool cursorPositionChanged = false;
- if (reverse)
- {
- if ( mCursorPosition >= places )
- {
- mCursorPosition = mCursorPosition - places;
- cursorPositionChanged = true;
- }
- }
- else
- {
- if ((mCursorPosition + places) <= mStyledText.size())
- {
- mCursorPosition = mCursorPosition + places;
- cursorPositionChanged = true;
- }
- }
-
- if( cursorPositionChanged )
- {
- const std::size_t cursorPositionForStyle = ( 0 == mCursorPosition ? 0 : mCursorPosition - 1 );
-
- const TextStyle oldInputStyle( mInputStyle );
- mInputStyle = GetStyleAt( cursorPositionForStyle ); // Inherit style from selected position.
-
- DrawCursor();
-
- if( oldInputStyle != mInputStyle )
- {
- // Updates the line height accordingly with the input style.
- UpdateLineHeight();
-
- EmitStyleChangedSignal();
- }
-
- ImfManager imfManager = ImfManager::Get();
- if ( imfManager )
- {
- imfManager.SetCursorPosition ( mCursorPosition );
- imfManager.NotifyCursorPosition();
- }
- }
-}
-
-void TextInput::DrawCursor()
-{
- const Size rowRect = GetRowRectFromCharacterPosition( mCursorPosition );
-
- // Get height of cursor and set its size
- Size size( CURSOR_THICKNESS, 0.0f );
- if( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() )
- {
- size.height = rowRect.height;
- }
- else
- {
- // Measure Font so know how big text will be if no initial text to measure.
- size.height = mLineHeight;
- }
-
- mCursor.SetSize(size);
-
- // If the character is italic then the cursor also tilts.
- mCursor.SetRotation( mInputStyle.IsItalicsEnabled() ? Degree( mInputStyle.GetItalicsAngle() - CURSOR_ANGLE_OFFSET ) : Degree( 0.f ), Vector3::ZAXIS );
-
- DALI_ASSERT_DEBUG( mCursorPosition <= mTextLayoutInfo.mCharacterLayoutInfoTable.size() );
-
- if( ( mCursorPosition <= mTextLayoutInfo.mCharacterLayoutInfoTable.size() ) )
- {
- Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
- bool altPositionValid; // Alternate cursor validity flag.
- bool directionRTL; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
- Vector3 position = GetActualPositionFromCharacterPosition( mCursorPosition, directionRTL, altPosition, altPositionValid );
-
- SetAltCursorEnabled( altPositionValid );
-
- if( !altPositionValid )
- {
- mCursor.SetPosition( position + UI_OFFSET );
- }
- else
- {
- size.height *= 0.5f;
- mCursor.SetSize(size);
- mCursor.SetPosition( position + UI_OFFSET - Vector3( 0.0f, directionRTL ? 0.0f : size.height, 0.0f ) );
-
- // TODO: change this cursor pos, to be the one where the cursor is sourced from.
- size.height = rowRect.height * 0.5f;
- mCursorRTL.SetSize(size);
- mCursorRTL.SetPosition( altPosition + UI_OFFSET - Vector3( 0.0f, directionRTL ? size.height : 0.0f, 0.0f ) );
- }
-
- if( IsScrollEnabled() )
- {
- // Whether cursor and grab handle are inside the boundaries of the text-input when text scroll is enabled.
- mIsCursorInScrollArea = mIsGrabHandleInScrollArea = IsPositionInsideBoundaries( position, size, GetControlSize() );
- }
- } // EditMode
-}
-
-void TextInput::SetAltCursorEnabled( bool enabled )
-{
- mCursorRTLEnabled = enabled;
- mCursorRTL.SetVisible( mCursorVisibility && mCursorRTLEnabled );
-}
-
-void TextInput::SetCursorVisibility( bool visible )
-{
- mCursorVisibility = visible;
- mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea );
- mCursorRTL.SetVisible( mCursorVisibility && mCursorRTLEnabled );
-}
-
-void TextInput::CreateGrabHandle( Dali::Image image )
-{
- if ( !mGrabHandle )
- {
- if ( !image )
- {
- mGrabHandleImage = ResourceImage::New(DEFAULT_GRAB_HANDLE);
- }
- else
- {
- mGrabHandleImage = image;
- }
-
- mGrabHandle = ImageActor::New(mGrabHandleImage);
- mGrabHandle.SetParentOrigin(ParentOrigin::TOP_LEFT);
- mGrabHandle.SetAnchorPoint(AnchorPoint::TOP_CENTER);
-
- mGrabHandle.SetDrawMode(DrawMode::OVERLAY);
-
- ShowGrabHandleAndSetVisibility( false );
-
- CreateGrabArea( mGrabHandle );
-
- mActiveLayer.Add(mGrabHandle);
- }
-}
-
-void TextInput::CreateGrabArea( Actor& parent )
-{
- mGrabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
- mGrabArea.SetName( "GrabArea" );
- mGrabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
- mGrabArea.SetSizeMode( SIZE_RELATIVE_TO_PARENT );
- mGrabArea.SetSizeModeFactor( DEFAULT_GRAB_HANDLE_RELATIVE_SIZE );
- mGrabArea.TouchedSignal().Connect(this,&TextInput::OnPressDown);
- mTapDetector.Attach( mGrabArea );
- mPanGestureDetector.Attach( mGrabArea );
- mLongPressDetector.Attach( mGrabArea );
-
- parent.Add(mGrabArea);
-}
-
-Vector3 TextInput::MoveGrabHandle( const Vector2& displacement )
-{
- Vector3 actualHandlePosition;
-
- if (mGrabHandle)
- {
- mActualGrabHandlePosition.x += displacement.x;
- mActualGrabHandlePosition.y += displacement.y;
-
- // Grab handle should jump to the nearest character and take cursor with it
- std::size_t newCursorPosition = 0;
- ReturnClosestIndex( mActualGrabHandlePosition.GetVectorXY(), newCursorPosition );
-
- Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
- bool altPositionValid; // Alternate cursor validity flag.
- bool directionRTL; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
- actualHandlePosition = GetActualPositionFromCharacterPosition( newCursorPosition, directionRTL, altPosition, altPositionValid );
-
- if( altPositionValid )
- {
- // Check which of the positions is the closest.
- if( fabsf( altPosition.x - mActualGrabHandlePosition.x ) < fabsf( actualHandlePosition.x - mActualGrabHandlePosition.x ) )
- {
- actualHandlePosition = altPosition;
- }
- }
-
- bool handleVisible = true;
-
- if( IsScrollEnabled() )
- {
- const Vector3 controlSize = GetControlSize();
- const Size cursorSize = GetRowRectFromCharacterPosition( newCursorPosition );
- // Scrolls the text if the handle is not in a visible position
- handleVisible = IsPositionInsideBoundaries( actualHandlePosition,
- cursorSize,
- controlSize );
-
- if( handleVisible )
- {
- StopScrollTimer();
- mCurrentHandlePosition = actualHandlePosition;
- mScrollDisplacement = Vector2::ZERO;
- }
- else
- {
- if( ( actualHandlePosition.x < SCROLL_THRESHOLD ) && ( displacement.x <= 0.f ) )
- {
- mScrollDisplacement.x = -SCROLL_SPEED;
- }
- else if( ( actualHandlePosition.x > controlSize.width - SCROLL_THRESHOLD ) && ( displacement.x >= 0.f ) )
- {
- mScrollDisplacement.x = SCROLL_SPEED;
- }
- if( ( actualHandlePosition.y < SCROLL_THRESHOLD ) && ( displacement.y <= 0.f ) )
- {
- mScrollDisplacement.y = -SCROLL_SPEED;
- }
- else if( ( actualHandlePosition.y > controlSize.height - SCROLL_THRESHOLD ) && ( displacement.y >= 0.f ) )
- {
- mScrollDisplacement.y = SCROLL_SPEED;
- }
- StartScrollTimer();
- }
- }
-
- if( handleVisible && // Only redraw cursor and do updates if position changed
- ( newCursorPosition != mCursorPosition ) ) // and the new position is visible (if scroll is not enabled, it's always true).
- {
- mCursorPosition = newCursorPosition;
-
- mGrabHandle.SetPosition( actualHandlePosition + UI_OFFSET );
-
- const TextStyle oldInputStyle( mInputStyle );
-
- mInputStyle = GetStyleAtCursor(); //Inherit style from cursor position
-
- CursorUpdate(); // Let keyboard know the new cursor position so can 're-capture' for prediction.
-
- if( oldInputStyle != mInputStyle )
- {
- // Updates the line height accordingly with the input style.
- UpdateLineHeight();
-
- EmitStyleChangedSignal();
- }
- }
- }
-
- return actualHandlePosition;
-}
-
-void TextInput::ShowGrabHandle( bool visible )
-{
- if ( IsGrabHandleEnabled() )
- {
- if( mGrabHandle )
- {
- mGrabHandle.SetVisible( mGrabHandleVisibility );
- }
- StartMonitoringStageForTouch();
- }
-}
-
-void TextInput::ShowGrabHandleAndSetVisibility( bool visible )
-{
- mGrabHandleVisibility = visible;
- ShowGrabHandle( visible );
-}
-
-// Callbacks connected to be Property notifications for Boundary checking.
-
-void TextInput::OnLeftBoundaryExceeded(PropertyNotification& source)
-{
- mIsSelectionHandleOneFlipped = true;
- mSelectionHandleOne.SetScale( -1.0f, 1.0f, 1.0f );
- mSelectionHandleOne.SetAnchorPoint( AnchorPoint::TOP_LEFT);
-}
-
-void TextInput::OnReturnToLeftBoundary(PropertyNotification& source)
-{
- mIsSelectionHandleOneFlipped = false;
- mSelectionHandleOne.SetScale( 1.0f, 1.0f, 1.0f );
- mSelectionHandleOne.SetAnchorPoint( AnchorPoint::TOP_RIGHT);
-}
-
-void TextInput::OnRightBoundaryExceeded(PropertyNotification& source)
-{
- mIsSelectionHandleTwoFlipped = true;
- mSelectionHandleTwo.SetScale( -1.0f, 1.0f, 1.0f );
- mSelectionHandleTwo.SetAnchorPoint( AnchorPoint::TOP_RIGHT);
-}
-
-void TextInput::OnReturnToRightBoundary(PropertyNotification& source)
-{
- mIsSelectionHandleTwoFlipped = false;
- mSelectionHandleTwo.SetScale( 1.0f, 1.0f, 1.0f );
- mSelectionHandleTwo.SetAnchorPoint( AnchorPoint::TOP_LEFT);
-}
-
-// todo change PropertyNotification signal definition to include Actor. Hence won't need duplicate functions.
-void TextInput::OnHandleOneLeavesBoundary( PropertyNotification& source)
-{
- mSelectionHandleOne.SetOpacity(0.0f);
-}
-
-void TextInput::OnHandleOneWithinBoundary(PropertyNotification& source)
-{
- mSelectionHandleOne.SetOpacity(1.0f);
-}
-
-void TextInput::OnHandleTwoLeavesBoundary( PropertyNotification& source)
-{
- mSelectionHandleTwo.SetOpacity(0.0f);
-}
-
-void TextInput::OnHandleTwoWithinBoundary(PropertyNotification& source)
-{
- mSelectionHandleTwo.SetOpacity(1.0f);
-}
-
-// End of Callbacks connected to be Property notifications for Boundary checking.
-
-void TextInput::SetUpHandlePropertyNotifications()
-{
- /* Property notifications for handles exceeding the boundary and returning back within boundary */
-
- Vector3 handlesize = GetSelectionHandleSize();
-
- // Exceeding horizontal boundary
- PropertyNotification leftNotification = mSelectionHandleOne.AddPropertyNotification( Actor::Property::WorldPositionX, LessThanCondition( mBoundingRectangleWorldCoordinates.x + handlesize.x) );
- leftNotification.NotifySignal().Connect( this, &TextInput::OnLeftBoundaryExceeded );
-
- PropertyNotification rightNotification = mSelectionHandleTwo.AddPropertyNotification( Actor::Property::WorldPositionX, GreaterThanCondition( mBoundingRectangleWorldCoordinates.z - handlesize.x ) );
- rightNotification.NotifySignal().Connect( this, &TextInput::OnRightBoundaryExceeded );
-
- // Within horizontal boundary
- PropertyNotification leftLeaveNotification = mSelectionHandleOne.AddPropertyNotification( Actor::Property::WorldPositionX, GreaterThanCondition( mBoundingRectangleWorldCoordinates.x + 2*handlesize.x ) );
- leftLeaveNotification.NotifySignal().Connect( this, &TextInput::OnReturnToLeftBoundary );
-
- PropertyNotification rightLeaveNotification = mSelectionHandleTwo.AddPropertyNotification( Actor::Property::WorldPositionX, LessThanCondition( mBoundingRectangleWorldCoordinates.z - 2*handlesize.x ) );
- rightLeaveNotification.NotifySignal().Connect( this, &TextInput::OnReturnToRightBoundary );
-
- // Exceeding vertical boundary
- PropertyNotification verticalExceedNotificationOne = mSelectionHandleOne.AddPropertyNotification( Actor::Property::WorldPositionY,
- OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalExceedNotificationOne.NotifySignal().Connect( this, &TextInput::OnHandleOneLeavesBoundary );
-
- PropertyNotification verticalExceedNotificationTwo = mSelectionHandleTwo.AddPropertyNotification( Actor::Property::WorldPositionY,
- OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalExceedNotificationTwo.NotifySignal().Connect( this, &TextInput::OnHandleTwoLeavesBoundary );
-
- // Within vertical boundary
- PropertyNotification verticalWithinNotificationOne = mSelectionHandleOne.AddPropertyNotification( Actor::Property::WorldPositionY,
- InsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalWithinNotificationOne.NotifySignal().Connect( this, &TextInput::OnHandleOneWithinBoundary );
-
- PropertyNotification verticalWithinNotificationTwo = mSelectionHandleTwo.AddPropertyNotification( Actor::Property::WorldPositionY,
- InsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalWithinNotificationTwo.NotifySignal().Connect( this, &TextInput::OnHandleTwoWithinBoundary );
-}
-
-void TextInput::CreateSelectionHandles( std::size_t start, std::size_t end, Dali::Image handleOneImage, Dali::Image handleTwoImage )
-{
- mSelectionHandleOnePosition = start;
- mSelectionHandleTwoPosition = end;
-
- if ( !mSelectionHandleOne )
- {
- // create normal and pressed images
- mSelectionHandleOneImage = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE );
- mSelectionHandleOneImagePressed = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE_PRESSED );
-
- mSelectionHandleOne = ImageActor::New( mSelectionHandleOneImage );
- mSelectionHandleOne.SetName("SelectionHandleOne");
- mSelectionHandleOne.SetParentOrigin( ParentOrigin::TOP_LEFT );
- mSelectionHandleOne.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text.
- mIsSelectionHandleOneFlipped = false;
- mSelectionHandleOne.SetDrawMode( DrawMode::OVERLAY ); // ensure grab handle above text
-
- mHandleOneGrabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
- mHandleOneGrabArea.SetName("SelectionHandleOneGrabArea");
-
- mHandleOneGrabArea.SetSizeMode( SIZE_RELATIVE_TO_PARENT );
- mHandleOneGrabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
- mHandleOneGrabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
-
- mTapDetector.Attach( mHandleOneGrabArea );
- mPanGestureDetector.Attach( mHandleOneGrabArea );
-
- mHandleOneGrabArea.TouchedSignal().Connect(this,&TextInput::OnHandleOneTouched);
-
- mSelectionHandleOne.Add( mHandleOneGrabArea );
- mActiveLayer.Add( mSelectionHandleOne );
- }
-
- if ( !mSelectionHandleTwo )
- {
- // create normal and pressed images
- mSelectionHandleTwoImage = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO );
- mSelectionHandleTwoImagePressed = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO_PRESSED );
-
- mSelectionHandleTwo = ImageActor::New( mSelectionHandleTwoImage );
- mSelectionHandleTwo.SetName("SelectionHandleTwo");
- mSelectionHandleTwo.SetParentOrigin( ParentOrigin::TOP_LEFT );
- mSelectionHandleTwo.SetAnchorPoint( AnchorPoint::TOP_LEFT );
- mIsSelectionHandleTwoFlipped = false;
- mSelectionHandleTwo.SetDrawMode(DrawMode::OVERLAY); // ensure grab handle above text
-
- mHandleTwoGrabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
- mHandleTwoGrabArea.SetName("SelectionHandleTwoGrabArea");
- mHandleTwoGrabArea.SetSizeMode( SIZE_RELATIVE_TO_PARENT );
- mHandleTwoGrabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
- mHandleTwoGrabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
-
- mTapDetector.Attach( mHandleTwoGrabArea );
- mPanGestureDetector.Attach( mHandleTwoGrabArea );
-
- mHandleTwoGrabArea.TouchedSignal().Connect(this, &TextInput::OnHandleTwoTouched);
-
- mSelectionHandleTwo.Add( mHandleTwoGrabArea );
-
- mActiveLayer.Add( mSelectionHandleTwo );
- }
-
- SetUpHandlePropertyNotifications();
-
- // update table as text may have changed.
- GetTextLayoutInfo();
-
- Vector3 altPositionOne; // Alternate (i.e. opposite direction) cursor position.
- bool altPositionValidOne; // Alternate cursor validity flag.
- bool directionRTLOne; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
- Vector3 cursorPositionOne = GetActualPositionFromCharacterPosition( mSelectionHandleOnePosition, directionRTLOne, altPositionOne, altPositionValidOne );
-
- Vector3 altPositionTwo; // Alternate (i.e. opposite direction) cursor position.
- bool altPositionValidTwo; // Alternate cursor validity flag.
- bool directionRTLTwo; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
- Vector3 cursorPositionTwo = GetActualPositionFromCharacterPosition( mSelectionHandleTwoPosition, directionRTLTwo, altPositionTwo, altPositionValidTwo );
-
- // VCC TODO: This method is a hack for one line.
- ChooseRtlSelectionHandlePosition( cursorPositionOne,
- cursorPositionTwo,
- altPositionValidOne,
- altPositionValidTwo,
- altPositionOne,
- altPositionTwo );
-
- mSelectionHandleOne.SetPosition( mSelectionHandleOneActualPosition + UI_OFFSET + mSelectionHandleOneOffset );
- mSelectionHandleTwo.SetPosition( mSelectionHandleTwoActualPosition + UI_OFFSET + mSelectionHandleTwoOffset );
-
- // Calculates and set the visibility if the scroll mode is enabled.
- bool isSelectionHandleOneVisible = true;
- bool isSelectionHandleTwoVisible = true;
- if( IsScrollEnabled() )
- {
- const Vector3& controlSize( GetControlSize() );
- isSelectionHandleOneVisible = IsPositionInsideBoundaries( mSelectionHandleOneActualPosition, Size::ZERO, controlSize );
- isSelectionHandleTwoVisible = IsPositionInsideBoundaries( mSelectionHandleTwoActualPosition, Size::ZERO, controlSize );
- mSelectionHandleOne.SetVisible( isSelectionHandleOneVisible );
- mSelectionHandleTwo.SetVisible( isSelectionHandleTwoVisible );
- }
-
- CreateHighlight(); // function will only create highlight if not already created.
-}
-
-Vector3 TextInput::MoveSelectionHandle( SelectionHandleId handleId, const Vector2& displacement )
-{
- Vector3 actualHandlePosition;
-
- if ( mSelectionHandleOne && mSelectionHandleTwo )
- {
- const Vector3& controlSize = GetControlSize();
-
- Size cursorSize( CURSOR_THICKNESS, 0.f );
-
- // Get a reference of the wanted selection handle (handle one or two).
- Vector3& actualSelectionHandlePosition = ( handleId == HandleOne ) ? mSelectionHandleOneActualPosition : mSelectionHandleTwoActualPosition;
-
- // Get a reference for the current position of the handle and a copy of its pair
- std::size_t& currentSelectionHandlePosition = ( handleId == HandleOne ) ? mSelectionHandleOnePosition : mSelectionHandleTwoPosition;
- const std::size_t pairSelectionHandlePosition = ( handleId == HandleOne ) ? mSelectionHandleTwoPosition : mSelectionHandleOnePosition;
-
- // Get a handle of the selection handle actor
- ImageActor selectionHandleActor = ( handleId == HandleOne ) ? mSelectionHandleOne : mSelectionHandleTwo;
-
- // Selection handles should jump to the nearest character
- std::size_t newHandlePosition = 0;
- ReturnClosestIndex( actualSelectionHandlePosition.GetVectorXY(), newHandlePosition );
-
- Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
- bool altPositionValid; // Alternate cursor validity flag.
- bool directionRTL; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
- actualHandlePosition = GetActualPositionFromCharacterPosition( newHandlePosition, directionRTL, altPosition, altPositionValid );
- if( altPositionValid )
- {
- // Check which of the positions is the closest.
- if( fabsf( altPosition.x - actualSelectionHandlePosition.x ) < fabsf( actualHandlePosition.x - actualSelectionHandlePosition.x ) )
- {
- actualHandlePosition = altPosition;
- }
- }
-
- bool handleVisible = true;
-
- if( IsScrollEnabled() )
- {
- mCurrentSelectionId = handleId;
-
- cursorSize.height = GetRowRectFromCharacterPosition( newHandlePosition ).height;
- // Restricts the movement of the grab handle inside the boundaries of the text-input.
- handleVisible = IsPositionInsideBoundaries( actualHandlePosition,
- cursorSize,
- controlSize );
-
- if( handleVisible )
- {
- StopScrollTimer();
- mCurrentSelectionHandlePosition = actualHandlePosition;
- mScrollDisplacement = Vector2::ZERO;
- }
- else
- {
- if( ( actualHandlePosition.x < SCROLL_THRESHOLD ) && ( displacement.x <= 0.f ) )
- {
- mScrollDisplacement.x = -SCROLL_SPEED;
- }
- else if( ( actualHandlePosition.x > controlSize.width - SCROLL_THRESHOLD ) && ( displacement.x >= 0.f ) )
- {
- mScrollDisplacement.x = SCROLL_SPEED;
- }
- if( ( actualHandlePosition.y < SCROLL_THRESHOLD ) && ( displacement.y <= 0.f ) )
- {
- mScrollDisplacement.y = -SCROLL_SPEED;
- }
- else if( ( actualHandlePosition.y > controlSize.height - SCROLL_THRESHOLD ) && ( displacement.y >= 0.f ) )
- {
- mScrollDisplacement.y = SCROLL_SPEED;
- }
- StartScrollTimer();
- }
- }
-
- if ( handleVisible && // Ensure the handle is visible.
- ( newHandlePosition != pairSelectionHandlePosition ) && // Ensure handle one is not the same position as handle two.
- ( newHandlePosition != currentSelectionHandlePosition ) ) // Ensure the handle has moved.
- {
- currentSelectionHandlePosition = newHandlePosition;
-
- Vector3 selectionHandleOffset = ( handleId == HandleOne ) ? mSelectionHandleOneOffset : mSelectionHandleTwoOffset;
- selectionHandleActor.SetPosition( actualHandlePosition + UI_OFFSET + selectionHandleOffset );
-
- UpdateHighlight();
-
- if ( handleId == HandleOne )
- {
- const TextStyle oldInputStyle( mInputStyle );
-
- // Set Active Style to that of first character in selection
- if( mSelectionHandleOnePosition < mStyledText.size() )
- {
- mInputStyle = ( mStyledText.at( mSelectionHandleOnePosition ) ).mStyle;
- }
-
- if( oldInputStyle != mInputStyle )
- {
- // Updates the line height accordingly with the input style.
- UpdateLineHeight();
-
- EmitStyleChangedSignal();
- }
- }
- }
- }
-
- return actualHandlePosition; // Returns Handle position passed in if new value not assigned.
-}
-
-void TextInput::SetSelectionHandlePosition(SelectionHandleId handleId)
-{
- const std::size_t selectionHandlePosition = ( handleId == HandleOne ) ? mSelectionHandleOnePosition : mSelectionHandleTwoPosition;
- ImageActor selectionHandleActor = ( handleId == HandleOne ) ? mSelectionHandleOne : mSelectionHandleTwo;
-
- if ( selectionHandleActor )
- {
- const Vector3 actualHandlePosition = GetActualPositionFromCharacterPosition( selectionHandlePosition );
- Vector3 selectionHandleOffset = ( handleId == HandleOne ) ? mSelectionHandleOneOffset : mSelectionHandleTwoOffset;
- selectionHandleActor.SetPosition( actualHandlePosition + UI_OFFSET + selectionHandleOffset );
-
- if( IsScrollEnabled() )
- {
- const Size cursorSize( CURSOR_THICKNESS,
- GetRowRectFromCharacterPosition( selectionHandlePosition ).height );
- selectionHandleActor.SetVisible( IsPositionInsideBoundaries( actualHandlePosition,
- cursorSize,
- GetControlSize() ) );
- }
- }
-}
-
-void TextInput::GetVisualTextSelection( std::vector<bool>& selectedVisualText, std::size_t startSelection, std::size_t endSelection )
-{
- selectedVisualText.resize( mTextLayoutInfo.mCharacterLogicalToVisualMap.size(), false );
-
- // VCC Set true/false in logical order. TODO : It needs to be checked.
-
- if( startSelection > endSelection )
- {
- std::swap( startSelection, endSelection );
- }
- std::size_t index = 0u;
- for( std::vector<bool>::iterator it = selectedVisualText.begin(), endIt = selectedVisualText.end(); it != endIt; ++it, ++index )
- {
- if( ( index < startSelection ) || ( endSelection <= index ) )
- {
- *it = false;
- }
- else
- {
- *it = true;
- }
- }
-}
-
-// Calculate the dimensions of the quads they will make the highlight mesh
-TextInput::HighlightInfo TextInput::CalculateHighlightInfo()
-{
- // At the moment there is no public API to modify the block alignment option.
-
- mNewHighlightInfo.mQuadList.clear(); // clear last quad information.
-
- if ( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() && !mTextLayoutInfo.mCharacterLogicalToVisualMap.empty() )
- {
- Toolkit::TextView::CharacterLayoutInfoContainer::iterator it = mTextLayoutInfo.mCharacterLayoutInfoTable.begin();
- Toolkit::TextView::CharacterLayoutInfoContainer::iterator end = mTextLayoutInfo.mCharacterLayoutInfoTable.end();
-
- // Get vector of flags representing characters that are selected (true) vs unselected (false).
- std::vector<bool> selectedVisualText;
- GetVisualTextSelection( selectedVisualText, mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
- std::vector<bool>::iterator selectedIt = selectedVisualText.begin();
- std::vector<bool>::iterator selectedEndIt = selectedVisualText.end();
-
- SelectionState selectionState = SelectionNone; ///< Current selection status of cursor over entire text.
- float rowLeft = 0.0f;
- float rowRight = 0.0f;
- // Keep track of the TextView's min/max extents. Should be able to query this from TextView.
- float maxRowLeft = std::numeric_limits<float>::max();
- float maxRowRight = 0.0f;
-
- Toolkit::TextView::CharacterLayoutInfoContainer::iterator lastIt = it;
-
- // Scan through entire text.
- while(it != end)
- {
- // selectionState: None when not in selection, Started when in selection, and Ended when reached end of selection.
-
- Toolkit::TextView::CharacterLayoutInfo& charInfo(*it);
- bool charSelected = false;
- if( selectedIt != selectedEndIt )
- {
- charSelected = *selectedIt++;
- }
-
- if( selectionState == SelectionNone )
- {
- if( charSelected )
- {
- selectionState = SelectionStarted;
- rowLeft = charInfo.mPosition.x - mTextLayoutInfo.mScrollOffset.x;
- rowRight = rowLeft + charInfo.mSize.width;
- }
- }
- else if( selectionState == SelectionStarted )
- {
- // break selection on:
- // 1. new line causing selection break. (\n or wordwrap)
- // 2. character not selected.
- if( !charSelected ||
- ( charInfo.mPosition.y - lastIt->mPosition.y > CHARACTER_THRESHOLD ) )
- {
- // finished selection.
- // TODO: TextView should have a table of visual rows, and each character a reference to the row
- // that it resides on. That way this enumeration is not necessary.
- Vector2 min, max;
- if(lastIt->mIsNewParagraphChar)
- {
- // If the last character is a new line, then to get the row rect, we need to scan from the character before the new line.
- lastIt = std::max( mTextLayoutInfo.mCharacterLayoutInfoTable.begin(), lastIt - 1 );
- }
- const Size rowSize( GetRowRectFromCharacterPosition( lastIt - mTextLayoutInfo.mCharacterLayoutInfoTable.begin(), min, max ) );
- maxRowLeft = std::min(maxRowLeft, min.x);
- maxRowRight = std::max(maxRowRight, max.x);
- float rowBottom = lastIt->mPosition.y - mTextLayoutInfo.mScrollOffset.y;
- float rowTop = rowBottom - rowSize.height;
-
- // Still selected, and block-align mode then set rowRight to max, so it can be clamped afterwards
- if(charSelected)
- {
- rowRight = std::numeric_limits<float>::max();
- }
- mNewHighlightInfo.AddQuad( rowLeft, rowTop, rowRight, rowBottom );
-
- selectionState = SelectionNone;
-
- // Still selected? start a new selection
- if( charSelected )
- {
- // if block-align mode then set rowLeft to min, so it can be clamped afterwards
- rowLeft = 0.0f;
- rowRight = ( charInfo.mPosition.x - mTextLayoutInfo.mScrollOffset.x ) + charInfo.mSize.width;
- selectionState = SelectionStarted;
- }
- }
- else
- {
- // build up highlight(s) with this selection data.
- rowLeft = std::min( charInfo.mPosition.x - mTextLayoutInfo.mScrollOffset.x, rowLeft );
- rowRight = std::max( ( charInfo.mPosition.x - mTextLayoutInfo.mScrollOffset.x ) + charInfo.mSize.width, rowRight );
- }
- }
-
- lastIt = it++;
- }
-
- // If reached end, and still on selection, then close selection.
- if(it == end)
- {
- if(selectionState == SelectionStarted)
- {
- // finished selection.
- Vector2 min, max;
- if(lastIt->mIsNewParagraphChar)
- {
- lastIt = std::max( mTextLayoutInfo.mCharacterLayoutInfoTable.begin(), lastIt - 1 );
- }
- const Size rowSize( GetRowRectFromCharacterPosition( lastIt - mTextLayoutInfo.mCharacterLayoutInfoTable.begin(), min, max ) );
- maxRowLeft = std::min(maxRowLeft, min.x);
- maxRowRight = std::max(maxRowRight, max.x);
- float rowBottom = lastIt->mPosition.y - mTextLayoutInfo.mScrollOffset.y;
- float rowTop = rowBottom - rowSize.height;
- mNewHighlightInfo.AddQuad( rowLeft, rowTop, rowRight, rowBottom );
- }
- }
-
- // Get the top left and bottom right corners.
- const Toolkit::TextView::CharacterLayoutInfo& firstCharacter( *mTextLayoutInfo.mCharacterLayoutInfoTable.begin() );
- const Vector2 topLeft( maxRowLeft, firstCharacter.mPosition.y - firstCharacter.mSize.height );
- const Vector2 bottomRight( topLeft.x + mTextLayoutInfo.mTextSize.width, topLeft.y + mTextLayoutInfo.mTextSize.height );
-
- // Clamp quads so they appear to clip to borders of the whole text.
- mNewHighlightInfo.Clamp2D( topLeft, bottomRight );
-
- // For block-align align Further Clamp quads to max left and right extents
- // BlockAlign: Will adjust highlight to block:
- // i.e.
- // H[ello] (top row right = max of all rows right)
- // [--this-] (middle rows' left = min of all rows left, middle rows' right = max of all rows right)
- // [is some] (middle rows' left = min of all rows left, middle rows' right = max of all rows right)
- // [text] (bottom row left = min of all rows left)
- // (common in SMS messaging selection)
- //
- // As opposed to the default which is tight text highlighting.
- // H[ello]
- // [this]
- // [is some]
- // [text]
- // (common in regular text editors/web browser selection)
- mNewHighlightInfo.Clamp2D( Vector2(maxRowLeft, topLeft.y), Vector2(maxRowRight, bottomRight.y ) );
-
- // Finally clamp quads again so they don't exceed the boundry of the control.
- const Vector3& controlSize = GetControlSize();
- mNewHighlightInfo.Clamp2D( Vector2::ZERO, Vector2(controlSize.x, controlSize.y) );
- } // end if
-
- return mNewHighlightInfo;
-}
-
-// VCC TODO: two methods are not needed. this one is a quick hack to fix PLMs. Should implement one which support both directions.
-// This method creates one quad per character so different selection boxes for a mix of LTR and RTL languages are created.
-TextInput::HighlightInfo TextInput::CalculateHighlightInfoRtl()
-{
- // At the moment there is no public API to modify the block alignment option.
-
- mNewHighlightInfo.mQuadList.clear(); // clear last quad information.
-
- if ( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() && !mTextLayoutInfo.mCharacterLogicalToVisualMap.empty() )
- {
- Toolkit::TextView::CharacterLayoutInfoContainer::iterator it = mTextLayoutInfo.mCharacterLayoutInfoTable.begin();
- Toolkit::TextView::CharacterLayoutInfoContainer::iterator end = mTextLayoutInfo.mCharacterLayoutInfoTable.end();
-
- // Get vector of flags representing characters that are selected (true) vs unselected (false).
- std::vector<bool> selectedVisualText;
- GetVisualTextSelection( selectedVisualText, mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
- std::vector<bool>::iterator selectedIt = selectedVisualText.begin();
- std::vector<bool>::iterator selectedEndIt = selectedVisualText.end();
-
- // SelectionState selectionState = SelectionNone; ///< Current selection status of cursor over entire text.
- float rowLeft = 0.0f;
- float rowRight = 0.0f;
-
- // VCC TODO this is valid for one line.
- Vector2 min, max;
- const Size rowSize = GetRowRectFromCharacterPosition( 0, min, max );
-
- // Scan through entire text.
- while(it != end)
- {
- // selectionState: None when not in selection, Started when in selection, and Ended when reached end of selection.
-
- Toolkit::TextView::CharacterLayoutInfo& charInfo(*it);
- bool charSelected = false;
- if( selectedIt != selectedEndIt )
- {
- charSelected = *selectedIt++;
- }
-
- if( charSelected )
- {
- rowLeft = charInfo.mPosition.x - mTextLayoutInfo.mScrollOffset.x;
- rowRight = rowLeft + charInfo.mSize.width;
-
- float rowBottom = charInfo.mPosition.y - mTextLayoutInfo.mScrollOffset.y;
- float rowTop = rowBottom - rowSize.height;
- mNewHighlightInfo.AddQuad( rowLeft, rowTop, rowRight, rowBottom );
- }
-
- ++it;
- }
-
- // Finally clamp quads again so they don't exceed the boundry of the control.
- const Vector3& controlSize = GetControlSize();
- mNewHighlightInfo.Clamp2D( Vector2::ZERO, Vector2(controlSize.x, controlSize.y) );
- } // end if
-
- return mNewHighlightInfo;
-}
-
-void TextInput::UpdateHighlight()
-{
-// Construct a Mesh with a texture to be used as the highlight 'box' for selected text
-//
-// Example scenarios where mesh is made from 3, 1, 2, 2 ,3 or 3 quads.
-//
-// [ TOP ] [ TOP ] [TOP ] [ TOP ] [ TOP ] [ TOP ]
-// [ MIDDLE ] [BOTTOM] [BOTTOM] [ MIDDLE ] [ MIDDLE ]
-// [ BOTTOM] [ MIDDLE ] [ MIDDLE ]
-// [BOTTOM] [ MIDDLE ]
-// [BOTTOM]
-//
-// Each quad is created as 2 triangles.
-// Middle is just 1 quad regardless of its size.
-//
-// (0,0) (0,0)
-// 0* *2 0* *2
-// TOP TOP
-// 3* *1 3* *1
-// 4* *1 4* *6
-// MIDDLE BOTTOM
-// 6* *5 7* *5
-// 6* *8
-// BOTTOM
-// 9* *7
-//
-
- if ( mHighlightMeshActor )
- {
- // vertex and triangle buffers should always be present if MeshActor is alive.
- HighlightInfo newHighlightInfo = CalculateHighlightInfoRtl();
- MeshData::VertexContainer vertices;
- Dali::MeshData::FaceIndices faceIndices;
-
- if( !newHighlightInfo.mQuadList.empty() )
- {
- std::vector<QuadCoordinates>::iterator iter = newHighlightInfo.mQuadList.begin();
- std::vector<QuadCoordinates>::iterator endIter = newHighlightInfo.mQuadList.end();
-
- // vertex position defaults to (0 0 0)
- MeshData::Vertex vertex;
- // set normal for all vertices as (0 0 1) pointing outward from TextInput Actor.
- vertex.nZ = 1.0f;
-
- for(std::size_t v = 0; iter != endIter; ++iter,v+=4 )
- {
- // Add each quad geometry (a sub-selection) to the mesh data.
-
- // 0-----1
- // |\ |
- // | \ A |
- // | \ |
- // | B \ |
- // | \|
- // 2-----3
-
- QuadCoordinates& quad = *iter;
- // top-left (v+0)
- vertex.x = quad.min.x;
- vertex.y = quad.min.y;
- vertices.push_back( vertex );
-
- // top-right (v+1)
- vertex.x = quad.max.x;
- vertex.y = quad.min.y;
- vertices.push_back( vertex );
-
- // bottom-left (v+2)
- vertex.x = quad.min.x;
- vertex.y = quad.max.y;
- vertices.push_back( vertex );
-
- // bottom-right (v+3)
- vertex.x = quad.max.x;
- vertex.y = quad.max.y;
- vertices.push_back( vertex );
-
- // triangle A (3, 1, 0)
- faceIndices.push_back( v + 3 );
- faceIndices.push_back( v + 1 );
- faceIndices.push_back( v );
-
- // triangle B (0, 2, 3)
- faceIndices.push_back( v );
- faceIndices.push_back( v + 2 );
- faceIndices.push_back( v + 3 );
-
- mMeshData.SetFaceIndices( faceIndices );
- }
-
- BoneContainer bones(0); // passed empty as bones not required
- mMeshData.SetData( vertices, faceIndices, bones, mCustomMaterial );
- mHighlightMesh.UpdateMeshData(mMeshData);
- }
- }
-}
-
-void TextInput::ClearPopup()
-{
- mPopupPanel.Clear();
-}
-
-void TextInput::AddPopupOptions()
-{
- mPopupPanel.AddPopupOptions();
-}
-
-void TextInput::SetPopupPosition( const Vector3& position, const Vector2& alternativePosition )
-{
- const Vector3& visiblePopUpSize = mPopupPanel.GetVisibileSize();
-
- Vector3 clampedPosition ( position );
- Vector3 tailOffsetPosition ( position );
-
- float xOffSet( 0.0f );
-
- Actor self = Self();
- const Vector3 textViewTopLeftWorldPosition = self.GetCurrentWorldPosition() - self.GetCurrentSize()*0.5f;
-
- const float popUpLeft = textViewTopLeftWorldPosition.x + position.x - visiblePopUpSize.width*0.5f;
- const float popUpTop = textViewTopLeftWorldPosition.y + position.y - visiblePopUpSize.height;
-
- // Clamp to left or right or of boundary
- if( popUpLeft < mBoundingRectangleWorldCoordinates.x )
- {
- xOffSet = mBoundingRectangleWorldCoordinates.x - popUpLeft ;
- }
- else if ( popUpLeft + visiblePopUpSize.width > mBoundingRectangleWorldCoordinates.z )
- {
- xOffSet = mBoundingRectangleWorldCoordinates.z - ( popUpLeft + visiblePopUpSize.width );
- }
-
- clampedPosition.x = position.x + xOffSet;
- tailOffsetPosition.x = -xOffSet;
-
- // Check if top left of PopUp outside of top bounding rectangle, if so then flip to lower position.
- bool flipTail( false );
-
- if ( popUpTop < mBoundingRectangleWorldCoordinates.y )
- {
- clampedPosition.y = alternativePosition.y + visiblePopUpSize.height;
- flipTail = true;
- }
-
- mPopupPanel.GetRootActor().SetPosition( clampedPosition );
- mPopupPanel.SetTailPosition( tailOffsetPosition, flipTail );
-}
-
-void TextInput::HidePopup(bool animate, bool signalFinished )
-{
- if ( ( mPopupPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopupPanel.GetState() == TextInputPopup::StateShown ) )
- {
- mPopupPanel.Hide( animate );
-
- if( animate && signalFinished )
- {
- mPopupPanel.HideFinishedSignal().Connect( this, &TextInput::OnPopupHideFinished );
- }
- }
-}
-
-void TextInput::ShowPopup( bool animate )
-{
- Vector3 position;
- Vector2 alternativePopupPosition;
-
- if(mHighlightMeshActor && mState == StateEdit)
- {
- Vector3 topHandle;
- Vector3 bottomHandle; // referring to the bottom most point of the handle or the bottom line of selection.
- Size rowSize;
- // When text is selected, show popup above top handle (and text), or below bottom handle.
- // topHandle: referring to the top most point of the handle or the top line of selection.
- if ( mSelectionHandleTwoActualPosition.y > mSelectionHandleOneActualPosition.y )
- {
- topHandle = mSelectionHandleOneActualPosition;
- bottomHandle = mSelectionHandleTwoActualPosition;
- rowSize= GetRowRectFromCharacterPosition( mSelectionHandleOnePosition );
- }
- else
- {
- topHandle = mSelectionHandleTwoActualPosition;
- bottomHandle = mSelectionHandleOneActualPosition;
- rowSize = GetRowRectFromCharacterPosition( mSelectionHandleTwoPosition );
- }
- topHandle.y += -mPopupOffsetFromText.y - rowSize.height;
- position = Vector3(topHandle.x, topHandle.y, 0.0f);
-
- float xPosition = ( fabsf( topHandle.x - bottomHandle.x ) )*0.5f + std::min( mSelectionHandleOneActualPosition.x , mSelectionHandleTwoActualPosition.x );
-
- position.x = xPosition;
-
- // Alternative position if no upper space
- bottomHandle.y += GetSelectionHandleSize().y + mPopupOffsetFromText.w;
- alternativePopupPosition = Vector2 ( position.x, bottomHandle.y );
- }
- else
- {
- // When no text is selected, show popup at world position of grab handle or cursor
- position = GetActualPositionFromCharacterPosition( mCursorPosition );
- const Size rowSize = GetRowRectFromCharacterPosition( mCursorPosition );
- position.y -= ( mPopupOffsetFromText.y + rowSize.height );
- // if can't be positioned above, then position below row.
- alternativePopupPosition = Vector2( position.x, position.y ); // default if no grab handle
- if ( mGrabHandle )
- {
- // If grab handle enabled then position pop-up below the grab handle.
- alternativePopupPosition.y = rowSize.height + mGrabHandle.GetCurrentSize().height + mPopupOffsetFromText.w +50.0f;
- }
- }
-
- SetPopupPosition( position, alternativePopupPosition );
-
- // Show popup
- mPopupPanel.Show( Self(), animate );
- StartMonitoringStageForTouch();
-
- mPopupPanel.PressedSignal().Connect( this, &TextInput::OnPopupButtonPressed );
-}
-
-void TextInput::ShowPopupCutCopyPaste()
-{
- ClearPopup();
-
- mPopupPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
- // Check the selected text is whole text or not.
- if( IsTextSelected() && ( mStyledText.size() != GetSelectedText().size() ) )
- {
- mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
- }
-
- if ( !mStyledText.empty() && IsTextSelected() )
- {
- mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCopy, true );
- mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, true );
- }
-
- if( mClipboard && mClipboard.NumberOfItems() )
- {
- mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsPaste, true );
- mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsClipboard, true );
- }
-
- AddPopupOptions();
-
- mPopupPanel.Hide(false);
- ShowPopup();
-}
-
-void TextInput::SetUpPopupSelection( bool showCutButton )
-{
- ClearPopup();
- mPopupPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
- // If no text exists then don't offer to select
- if ( !mStyledText.empty() )
- {
- mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
- mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelect, true );
- mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, ( showCutButton && IsTextSelected() ) );
- }
- // if clipboard has valid contents then offer paste option
- if( mClipboard && mClipboard.NumberOfItems() )
- {
- mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsPaste, true );
- mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsClipboard, true );
- }
-
- AddPopupOptions();
-
- mPopupPanel.Hide(false);
-}
-
-bool TextInput::ReturnClosestIndex(const Vector2& source, std::size_t& closestIndex )
-{
- bool found = false;
- closestIndex = 0;
-
- std::vector<Toolkit::TextView::CharacterLayoutInfo> matchedCharacters;
- bool lastRightToLeftChar(false); /// RTL state of previous character encountered (character on the left of touch point)
- bool rightToLeftChar(false); /// RTL state of current character encountered (character on the right of touch point)
- float glyphIntersection(0.0f); /// Glyph intersection, the point between the two nearest characters touched.
-
- const Vector2 sourceScrollOffset( source + mTextLayoutInfo.mScrollOffset );
-
- if ( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() )
- {
- float closestYdifference = std::numeric_limits<float>::max();
- std::size_t lineOffset = 0; /// Keep track of position of the first character on the matched line of interest.
- std::size_t numberOfMatchedCharacters = 0;
-
- // 1. Find closest character line to y part of source, create vector of all entries in that Y position
- // TODO: There should be an easy call to enumerate through each visual line, instead of each character on all visual lines.
-
- for( std::vector<Toolkit::TextView::CharacterLayoutInfo>::const_iterator it = mTextLayoutInfo.mCharacterLayoutInfoTable.begin(), endIt = mTextLayoutInfo.mCharacterLayoutInfoTable.end(); it != endIt; ++it )
- {
- const Toolkit::TextView::CharacterLayoutInfo& info( *it );
- float baselinePosition = info.mPosition.y - info.mDescender;
-
- if( info.mIsVisible )
- {
- // store difference between source y point and the y position of the current character
- float currentYdifference = fabsf( sourceScrollOffset.y - ( baselinePosition ) );
-
- if( currentYdifference < closestYdifference )
- {
- // closest so far; store this difference and clear previous matchedCharacters as no longer closest
- lineOffset = it - mTextLayoutInfo.mCharacterLayoutInfoTable.begin();
- closestYdifference = currentYdifference;
- matchedCharacters.clear();
- numberOfMatchedCharacters = 0; // reset count
- }
-
- // add all characters that are on the same Y axis (within the CHARACTER_THRESHOLD) to the matched array.
- if( fabsf( closestYdifference - currentYdifference ) < CHARACTER_THRESHOLD )
- {
- // ignore new line character.
- if( !info.mIsNewParagraphChar )
- {
- matchedCharacters.push_back( info );
- numberOfMatchedCharacters++;
- }
- }
- }
- } // End of loop checking each character's y position in the character layout table
-
- // Check if last character is a newline, if it is
- // then need pretend there is an imaginary line afterwards,
- // and check if user is touching below previous line.
- const Toolkit::TextView::CharacterLayoutInfo& lastInfo( mTextLayoutInfo.mCharacterLayoutInfoTable[mTextLayoutInfo.mCharacterLayoutInfoTable.size() - 1] );
-
- if( ( lastInfo.mIsVisible ) && ( lastInfo.mIsNewParagraphChar ) && ( sourceScrollOffset.y > lastInfo.mPosition.y ) )
- {
- closestIndex = mTextLayoutInfo.mCharacterLayoutInfoTable.size();
- }
- else
- {
- // 2 Iterate through matching list of y positions and find closest matching X position.
-
- bool matched( false );
-
- // Traverse the characters in the visual order. VCC TODO: check for more than one line.
- std::size_t visualIndex = 0u;
- const std::size_t matchedCharactersSize = matchedCharacters.size();
- for( ; visualIndex < matchedCharactersSize; ++visualIndex )
- {
- const Toolkit::TextView::CharacterLayoutInfo& info( *( matchedCharacters.begin() + mTextLayoutInfo.mCharacterVisualToLogicalMap[visualIndex] ) );
-
- if( info.mIsVisible )
- {
- // stop when on left side of character's center.
- const float characterMidPointPosition = info.mPosition.x + ( info.mSize.width * 0.5f ) ;
- if( sourceScrollOffset.x < characterMidPointPosition )
- {
- if(info.mIsRightToLeftCharacter)
- {
- rightToLeftChar = true;
- }
- glyphIntersection = info.mPosition.x;
- matched = true;
- break;
- }
-
- lastRightToLeftChar = info.mIsRightToLeftCharacter;
- }
- }
-
- if( visualIndex == matchedCharactersSize )
- {
- rightToLeftChar = lastRightToLeftChar;
- }
-
- closestIndex = lineOffset + visualIndex;
-
- mClosestCursorPositionEOL = false; // reset
- if( ( visualIndex == matchedCharactersSize ) && !matched )
- {
- mClosestCursorPositionEOL = true; // Reached end of matched characters in closest line but no match so cursor should be after last character.
- }
-
- // For RTL characters, need to adjust closestIndex by 1 (as the inequality above would be reverse)
- if( rightToLeftChar && lastRightToLeftChar )
- {
- --closestIndex; // (-1 = numeric_limits<std::size_t>::max())
- }
- }
- }
-
- // closestIndex is the visual index, need to convert it to the logical index
- if( !mTextLayoutInfo.mCharacterVisualToLogicalMap.empty() )
- {
- if( closestIndex < mTextLayoutInfo.mCharacterVisualToLogicalMap.size() )
- {
- // Checks for situations where user is touching between LTR and RTL
- // characters. To identify if the user means the end of a LTR string
- // or the beginning of an RTL string, and vice versa.
- if( closestIndex > 0 )
- {
- if( rightToLeftChar && !lastRightToLeftChar )
- {
- // [LTR] [RTL]
- // |..|..|
- // AAA BBB
- // A: In this touch range, the user is indicating that they wish to place
- // the cursor at the end of the LTR text.
- // B: In this touch range, the user is indicating that they wish to place
- // the cursor at the end of the RTL text.
-
- // Result of touching A area:
- // [.....LTR]|[RTL......]+
- //
- // |: primary cursor (for typing LTR chars)
- // +: secondary cursor (for typing RTL chars)
-
- // Result of touching B area:
- // [.....LTR]+[RTL......]|
- //
- // |: primary cursor (for typing RTL chars)
- // +: secondary cursor (for typing LTR chars)
-
- if( sourceScrollOffset.x < glyphIntersection )
- {
- --closestIndex;
- }
- }
- else if( !rightToLeftChar && lastRightToLeftChar )
- {
- if( sourceScrollOffset.x < glyphIntersection )
- {
- --closestIndex;
- }
- }
- }
-
- closestIndex = mTextLayoutInfo.mCharacterVisualToLogicalMap[closestIndex];
- // If user touched a left-side of RTL char, and the character on the left was an LTR then position logical cursor
- // one further ahead
- if( rightToLeftChar && !lastRightToLeftChar )
- {
- ++closestIndex;
- }
- }
- else if( closestIndex == std::numeric_limits<std::size_t>::max() ) // -1 RTL (after last arabic character on line)
- {
- closestIndex = mTextLayoutInfo.mCharacterVisualToLogicalMap.size();
- }
- else if( mTextLayoutInfo.mCharacterLayoutInfoTable[ mTextLayoutInfo.mCharacterVisualToLogicalMap[ closestIndex - 1 ] ].mIsRightToLeftCharacter ) // size() LTR (after last european character on line)
- {
- closestIndex = 0;
- }
- }
-
- return found;
-}
-
-float TextInput::GetLineJustificationPosition() const
-{
- const Vector3& size = mDisplayedTextView.GetCurrentSize();
- Toolkit::Alignment::Type alignment = mDisplayedTextView.GetTextAlignment();
- float alignmentOffset = 0.f;
-
- // Work out cursor 'x' position when there are any character accordingly with the text view alignment settings.
- if( alignment & Toolkit::Alignment::HorizontalLeft )
- {
- alignmentOffset = 0.f;
- }
- else if( alignment & Toolkit::Alignment::HorizontalCenter )
- {
- alignmentOffset = 0.5f * ( size.width - mTextLayoutInfo.mTextSize.width );
- }
- else if( alignment & Toolkit::Alignment::HorizontalRight )
- {
- alignmentOffset = size.width - mTextLayoutInfo.mTextSize.width;
- }
-
- Toolkit::TextView::LineJustification justification = mDisplayedTextView.GetLineJustification();
- float justificationOffset = 0.f;
-
- switch( justification )
- {
- case Toolkit::TextView::Left:
- {
- justificationOffset = 0.f;
- break;
- }
- case Toolkit::TextView::Center:
- {
- justificationOffset = 0.5f * mTextLayoutInfo.mTextSize.width;
- break;
- }
- case Toolkit::TextView::Right:
- {
- justificationOffset = mTextLayoutInfo.mTextSize.width;
- break;
- }
- case Toolkit::TextView::Justified:
- {
- justificationOffset = 0.f;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( false );
- }
- } // end switch
-
- return alignmentOffset + justificationOffset;
-}
-
-Vector3 TextInput::PositionCursorAfterWordWrap( std::size_t characterPosition ) const
-{
- /* Word wrap occurs automatically in TextView when the exceed policy moves a word to the next line when not enough space on current.
- A newline character is not inserted in this case */
-
- Vector3 cursorPosition;
-
- Toolkit::TextView::CharacterLayoutInfo currentCharInfo = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition ];
-
- bool noWrap = true;
-
- if( characterPosition > 0u )
- {
- Toolkit::TextView::CharacterLayoutInfo previousCharInfo = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition - 1u ];
-
- // If previous character on a different line then use current characters position
- if( fabsf( (currentCharInfo.mPosition.y - currentCharInfo.mDescender ) - ( previousCharInfo.mPosition.y - previousCharInfo.mDescender) ) > Math::MACHINE_EPSILON_1000 )
- {
- // VCC TODO: PositionCursorAfterWordWrap currently doesn't work for multiline. Need to check this branch.
- if ( mClosestCursorPositionEOL )
- {
- cursorPosition = Vector3( previousCharInfo.mPosition.x + previousCharInfo.mSize.width, previousCharInfo.mPosition.y, previousCharInfo.mPosition.z ) ;
- }
- else
- {
- cursorPosition = Vector3( currentCharInfo.mPosition );
- }
-
- noWrap = false;
- }
- }
-
- if( noWrap )
- {
- // If the character is left to right, the position is the character's position plus its width.
- const float ltrOffset = !currentCharInfo.mIsRightToLeftCharacter ? currentCharInfo.mSize.width : 0.f;
-
- cursorPosition.x = currentCharInfo.mPosition.x + ltrOffset;
- cursorPosition.y = currentCharInfo.mPosition.y;
- }
-
- return cursorPosition;
-}
-
-Vector3 TextInput::GetActualPositionFromCharacterPosition( std::size_t characterPosition ) const
-{
- bool direction = false;
- Vector3 alternatePosition;
- bool alternatePositionValid = false;
-
- return GetActualPositionFromCharacterPosition( characterPosition, direction, alternatePosition, alternatePositionValid );
-}
-
-Vector3 TextInput::GetActualPositionFromCharacterPosition( std::size_t characterPosition, bool& directionRTL, Vector3& alternatePosition, bool& alternatePositionValid ) const
-{
- DALI_ASSERT_DEBUG( ( mTextLayoutInfo.mCharacterLayoutInfoTable.size() == mTextLayoutInfo.mCharacterLogicalToVisualMap.size() ) &&
- ( mTextLayoutInfo.mCharacterLayoutInfoTable.size() == mTextLayoutInfo.mCharacterVisualToLogicalMap.size() ) &&
- "TextInput::GetActualPositionFromCharacterPosition. All layout tables must have the same size." );
-
- Vector3 cursorPosition( 0.f, 0.f, 0.f );
-
- alternatePositionValid = false;
- directionRTL = false;
-
- if( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() )
- {
- if( characterPosition == 0u )
- {
- // When the cursor position is at the beginning, it should be at the start of the current character.
- // If the current character is LTR, then the start is on the right side of the glyph.
- // If the current character is RTL, then the start is on the left side of the glyph.
-
- if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() ) ).mIsVisible )
- {
- characterPosition = FindVisibleCharacter( Right, 0u );
- }
-
- const Toolkit::TextView::CharacterLayoutInfo& info = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition ];
- const float rtlOffset = info.mIsRightToLeftCharacter ? info.mSize.width : 0.0f;
-
- cursorPosition.x = info.mPosition.x + rtlOffset;
- cursorPosition.y = info.mPosition.y;
- directionRTL = info.mIsRightToLeftCharacter;
- }
- else if( characterPosition > 0u )
- {
- // Get the direction of the paragraph.
- const std::size_t startCharacterPosition = GetRowStartFromCharacterPosition( characterPosition );
- const bool isParagraphRightToLeft = ( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + startCharacterPosition ) ).mIsRightToLeftCharacter;
-
- // When cursor is not at beginning, consider possibility of
- // showing 2 cursors. (whereas at beginning we only ever show one cursor)
-
- // Cursor position should be the end of the last character.
- // If the last character is LTR, then the end is on the right side of the glyph.
- // If the last character is RTL, then the end is on the left side of the glyph.
-
- --characterPosition;
-
- if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + characterPosition ) ).mIsVisible )
- {
- characterPosition = FindVisibleCharacter( Left, characterPosition );
- }
-
- Toolkit::TextView::CharacterLayoutInfo info = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition ];
- if( ( characterPosition > 0u ) && info.mIsNewParagraphChar && !IsScrollEnabled() )
- {
- // VCC TODO : check for a new paragraph character.
-
- // Prevents the cursor to exceed the boundary if the last visible character is a 'new line character' and the scroll is not enabled.
- const Vector3& size = GetControlSize();
-
- if( info.mPosition.y + info.mSize.height - mDisplayedTextView.GetLineHeightOffset() > size.height )
- {
- --characterPosition;
- }
- info = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition ];
- }
-
- if( !info.mIsNewParagraphChar )
- {
- cursorPosition = PositionCursorAfterWordWrap( characterPosition ); // Get position of cursor/handles taking in account auto word wrap.
- }
- else
- {
- // VCC TODO : check for a new paragraph character.
-
- // When cursor points to first character on new line, position cursor at the start of this glyph.
- if( characterPosition < mTextLayoutInfo.mCharacterLayoutInfoTable.size() )
- {
- const Toolkit::TextView::CharacterLayoutInfo& infoNext = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition ];
- const float start( infoNext.mIsRightToLeftCharacter ? infoNext.mSize.width : 0.0f );
-
- cursorPosition.x = infoNext.mPosition.x + start;
- cursorPosition.y = infoNext.mPosition.y;
- }
- else
- {
- // If cursor points to the end of text, then can only position
- // cursor where the new line starts based on the line-justification position.
- cursorPosition.x = GetLineJustificationPosition();
-
- if( characterPosition == mTextLayoutInfo.mCharacterLogicalToVisualMap.size() )
- {
- // If this is after the last character, then we can assume that the new cursor
- // should be exactly one row below the current row.
-
- const Size rowRect = GetRowRectFromCharacterPosition( characterPosition - 1u );
- cursorPosition.y = info.mPosition.y + rowRect.height;
- }
- else
- {
- // If this is not after last character, then we can use this row's height.
- // should be exactly one row below the current row.
-
- const Size rowRect = GetRowRectFromCharacterPosition( characterPosition );
- cursorPosition.y = info.mPosition.y + rowRect.height;
- }
- }
- }
-
- directionRTL = info.mIsRightToLeftCharacter;
-
- if( 1u < mTextLayoutInfo.mCharacterLayoutInfoTable.size() )
- {
- // 1. When the cursor is neither at the beginning or the end,
- // we can show multiple cursors under situations when the cursor is
- // between RTL and LTR text...
- if( characterPosition + 1u < mTextLayoutInfo.mCharacterLayoutInfoTable.size() )
- {
- std::size_t characterAltPosition = characterPosition + 1u;
-
- const Toolkit::TextView::CharacterLayoutInfo& infoAlt = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterAltPosition ];
-
- if(!info.mIsRightToLeftCharacter && infoAlt.mIsRightToLeftCharacter)
- {
- // Stuation occurs when cursor is at the end of English text (LTR) and beginning of Arabic (RTL)
- // Text: [...LTR...]|[...RTL...]
- // Cursor pos: ^
- // Alternate cursor pos: ^
- // In which case we need to display an alternate cursor for the RTL text.
-
- alternatePosition.x = infoAlt.mPosition.x + infoAlt.mSize.width;
- alternatePosition.y = infoAlt.mPosition.y;
- alternatePositionValid = true;
- }
- else if(info.mIsRightToLeftCharacter && !infoAlt.mIsRightToLeftCharacter)
- {
- // Situation occurs when cursor is at end of the Arabic text (LTR) and beginning of English (RTL)
- // Text: |[...RTL...] [...LTR....]
- // Cursor pos: ^
- // Alternate cursor pos: ^
- // In which case we need to display an alternate cursor for the RTL text.
-
- alternatePosition.x = infoAlt.mPosition.x;
- alternatePosition.y = infoAlt.mPosition.y;
- alternatePositionValid = true;
- }
- }
- else
- {
- // 2. When the cursor is at the end of the text,
- // and we have multi-directional text,
- // we can also consider showing mulitple cursors.
- // The rule here is:
- // If first and last characters on row are different
- // Directions, then two cursors need to be displayed.
-
- if( info.mIsRightToLeftCharacter != isParagraphRightToLeft )
- {
- // The last character's direction is differernt than the first one of current paragraph.
-
- // Get first
- const Toolkit::TextView::CharacterLayoutInfo& infoStart= mTextLayoutInfo.mCharacterLayoutInfoTable[ GetFirstCharacterWithSameDirection( characterPosition ) ];
-
- if(info.mIsRightToLeftCharacter)
- {
- // For text Starting as LTR and ending as RTL. End cursor position is as follows:
- // Text: [...LTR...]|[...RTL...]
- // Cursor pos: ^
- // Alternate cursor pos: ^
- // In which case we need to display an alternate cursor for the RTL text, this cursor
- // should be at the end of the given line.
-
- alternatePosition.x = infoStart.mPosition.x + infoStart.mSize.width;
- alternatePosition.y = infoStart.mPosition.y;
- alternatePositionValid = true;
- }
- else if(!info.mIsRightToLeftCharacter) // starting RTL
- {
- // For text Starting as RTL and ending as LTR. End cursor position is as follows:
- // Text: |[...RTL...] [...LTR....]
- // Cursor pos: ^
- // Alternate cursor pos: ^
- // In which case we need to display an alternate cursor for the RTL text.
-
- alternatePosition.x = infoStart.mPosition.x;
- alternatePosition.y = infoStart.mPosition.y;
- alternatePositionValid = true;
- }
- }
- }
- }
- } // characterPosition > 0
- }
- else
- {
- // If the character table is void, place the cursor accordingly the text alignment.
- const Vector3& size = GetControlSize();
-
- Toolkit::Alignment::Type alignment = mDisplayedTextView.GetTextAlignment();
- float alignmentOffset = 0.f;
-
- // Work out cursor 'x' position when there are any character accordingly with the text view alignment settings.
- if( alignment & Toolkit::Alignment::HorizontalLeft )
- {
- alignmentOffset = 0.f;
- }
- else if( alignment & Toolkit::Alignment::HorizontalCenter )
- {
- alignmentOffset = 0.5f * ( size.width );
- }
- else if( alignment & Toolkit::Alignment::HorizontalRight )
- {
- alignmentOffset = size.width;
- }
-
- // Work out cursor 'x' position when there are any character accordingly with the text view alignment settings.
- cursorPosition.x = alignmentOffset;
-
- // Work out cursor 'y' position when there are any character accordingly with the text view alignment settings.
- if( alignment & Toolkit::Alignment::VerticalTop )
- {
- cursorPosition.y = mLineHeight;
- }
- else if( alignment & Toolkit::Alignment::VerticalCenter )
- {
- cursorPosition.y = 0.5f * ( size.height + mLineHeight );
- }
- else if( alignment & Toolkit::Alignment::VerticalBottom )
- {
- cursorPosition.y = size.height;
- }
- }
-
- cursorPosition.x -= mTextLayoutInfo.mScrollOffset.x;
- cursorPosition.y -= mTextLayoutInfo.mScrollOffset.y;
-
- if( alternatePositionValid )
- {
- alternatePosition.x -= mTextLayoutInfo.mScrollOffset.x;
- alternatePosition.y -= mTextLayoutInfo.mScrollOffset.y;
- }
-
- return cursorPosition;
-}
-
-std::size_t TextInput::GetRowStartFromCharacterPosition( std::size_t logicalPosition ) const
-{
- // scan string from current position to beginning of current line to note direction of line
- while( logicalPosition )
- {
- logicalPosition--;
- if( mTextLayoutInfo.mCharacterLayoutInfoTable[logicalPosition].mIsNewParagraphChar )
- {
- logicalPosition++;
- break;
- }
- }
-
- return logicalPosition;
-}
-
-std::size_t TextInput::GetFirstCharacterWithSameDirection( std::size_t logicalPosition ) const
-{
- const bool isRightToLeft = mTextLayoutInfo.mCharacterLayoutInfoTable[logicalPosition].mIsRightToLeftCharacter;
-
- while( logicalPosition )
- {
- logicalPosition--;
- if( isRightToLeft != mTextLayoutInfo.mCharacterLayoutInfoTable[logicalPosition].mIsRightToLeftCharacter )
- {
- logicalPosition++;
- break;
- }
- }
-
- return logicalPosition;
-}
-
-Size TextInput::GetRowRectFromCharacterPosition(std::size_t characterPosition) const
-{
- Vector2 min, max;
-
- return GetRowRectFromCharacterPosition( characterPosition, min, max );
-}
-
-Size TextInput::GetRowRectFromCharacterPosition( std::size_t characterPosition, Vector2& min, Vector2& max ) const
-{
- // if we have no text content, then return position 0,0 with width 0, and height the same as cursor height.
- if( mTextLayoutInfo.mCharacterLayoutInfoTable.empty() )
- {
- min = Vector2::ZERO;
- max = Vector2(0.0f, mLineHeight);
- return max;
- }
-
- DALI_ASSERT_DEBUG( characterPosition <= mTextLayoutInfo.mCharacterLayoutInfoTable.size() );
-
- // Initializes the min and max position.
- const std::size_t initialPosition = ( characterPosition == mTextLayoutInfo.mCharacterLayoutInfoTable.size() ) ? characterPosition - 1u : characterPosition;
- min = ( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + initialPosition ) ).mPosition.GetVectorXY();
- max = min;
-
- bool found = false;
- // 1) Find the line where the character is laid-out.
- for( Toolkit::TextView::LineLayoutInfoContainer::const_iterator lineIt = mTextLayoutInfo.mLines.begin(), lineEndIt = mTextLayoutInfo.mLines.end();
- !found && ( lineIt != mTextLayoutInfo.mLines.end() );
- ++lineIt )
- {
- const Toolkit::TextView::LineLayoutInfo& lineInfo( *lineIt );
-
- // Index within the whole text to the last character of the current line.
- std::size_t lastCharacterOfLine = 0u;
-
- Toolkit::TextView::LineLayoutInfoContainer::const_iterator lineNextIt = lineIt + 1u;
- if( lineNextIt != lineEndIt )
- {
- lastCharacterOfLine = (*lineNextIt).mCharacterGlobalIndex - 1u;
- }
- else
- {
- lastCharacterOfLine = mTextLayoutInfo.mCharacterLayoutInfoTable.size() - 1u;
- }
-
- // Check if the given chracter position is within the line.
- if( ( lineInfo.mCharacterGlobalIndex <= initialPosition ) && ( initialPosition <= lastCharacterOfLine ) )
- {
- // 2) Get the row rect of all laid-out characters on the line.
-
- // Need to scan all characters of the line because they are in the logical position.
- for( Toolkit::TextView::CharacterLayoutInfoContainer::const_iterator it = mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + lineInfo.mCharacterGlobalIndex,
- endIt = mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + lastCharacterOfLine + 1u;
- it != endIt;
- ++it )
- {
- const Toolkit::TextView::CharacterLayoutInfo& characterInfo( *it );
-
- min.x = std::min( min.x, characterInfo.mPosition.x );
- min.y = std::min( min.y, characterInfo.mPosition.y );
- max.x = std::max( max.x, characterInfo.mPosition.x + characterInfo.mSize.width );
- max.y = std::max( max.y, characterInfo.mPosition.y + characterInfo.mSize.height );
- }
-
- found = true;
- }
- }
-
- return Size( max.x - min.x, max.y - min.y );
-}
-
-bool TextInput::WasTouchedCheck( const Actor& touchedActor ) const
-{
- Actor popUpPanel = mPopupPanel.GetRootActor();
-
- if ( ( touchedActor == Self() ) || ( touchedActor == popUpPanel ) )
- {
- return true;
- }
- else
- {
- Dali::Actor parent( touchedActor.GetParent() );
-
- if ( parent )
- {
- return WasTouchedCheck( parent );
- }
- }
-
- return false;
-}
-
-void TextInput::StartMonitoringStageForTouch()
-{
- Stage stage = Stage::GetCurrent();
- stage.TouchedSignal().Connect( this, &TextInput::OnStageTouched );
-}
-
-void TextInput::EndMonitoringStageForTouch()
-{
- Stage stage = Stage::GetCurrent();
- stage.TouchedSignal().Disconnect( this, &TextInput::OnStageTouched );
-}
-
-void TextInput::OnStageTouched(const TouchEvent& event)
-{
- if( event.GetPointCount() > 0 )
- {
- if ( TouchPoint::Down == event.GetPoint(0).state )
- {
- const Actor touchedActor(event.GetPoint(0).hitActor);
-
- bool popUpShown( false );
-
- if ( ( mPopupPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopupPanel.GetState() == TextInputPopup::StateShown ) )
- {
- popUpShown = true;
- }
-
- bool textInputTouched = (touchedActor && WasTouchedCheck( touchedActor ));
-
- if ( ( mHighlightMeshActor || popUpShown ) && !textInputTouched )
- {
- EndMonitoringStageForTouch();
- HidePopup( true, false );
- }
-
- if ( ( IsGrabHandleEnabled() && mGrabHandle ) && !textInputTouched )
- {
- EndMonitoringStageForTouch();
- ShowGrabHandleAndSetVisibility( false );
- }
- }
- }
-}
-
-void TextInput::SelectText(std::size_t start, std::size_t end)
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, "SelectText mEditModeActive[%s] grabHandle[%s] start[%u] end[%u] size[%u]\n", mEditModeActive?"true":"false",
- IsGrabHandleEnabled()?"true":"false",
- start, end, mTextLayoutInfo.mCharacterLayoutInfoTable.size() );
- DALI_ASSERT_ALWAYS( start <= mTextLayoutInfo.mCharacterLayoutInfoTable.size() && "TextInput::SelectText start out of max range" );
- DALI_ASSERT_ALWAYS( end <= mTextLayoutInfo.mCharacterLayoutInfoTable.size() && "TextInput::SelectText end out of max range" );
-
- StartMonitoringStageForTouch();
-
- if ( mEditModeActive ) // Only allow text selection when in edit mode
- {
- // When replacing highlighted text keyboard should ignore current word at cursor hence notify keyboard that the cursor is at the start of the highlight.
- mSelectingText = true;
-
- std::size_t selectionStartPosition = std::min( start, end );
-
- // Hide grab handle when selecting.
- ShowGrabHandleAndSetVisibility( false );
-
- if( start != end ) // something to select
- {
- SetCursorVisibility( false );
- StopCursorBlinkTimer();
-
- CreateSelectionHandles(start, end);
- UpdateHighlight();
-
- const TextStyle oldInputStyle( mInputStyle );
- mInputStyle = GetStyleAt( selectionStartPosition ); // Inherit style from selected position.
-
- if( oldInputStyle != mInputStyle )
- {
- // Updates the line height accordingly with the input style.
- UpdateLineHeight();
-
- EmitStyleChangedSignal();
- }
-
- HidePopup();
- }
-
- mSelectingText = false;
- }
-}
-
-MarkupProcessor::StyledTextArray TextInput::GetSelectedText()
-{
- MarkupProcessor::StyledTextArray currentSelectedText;
-
- if ( IsTextSelected() )
- {
- MarkupProcessor::StyledTextArray::iterator it = mStyledText.begin() + std::min(mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
- MarkupProcessor::StyledTextArray::iterator end = mStyledText.begin() + std::max(mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
-
- for(; it != end; ++it)
- {
- MarkupProcessor::StyledText& styledText( *it );
- currentSelectedText.push_back( styledText );
- }
- }
- return currentSelectedText;
-}
-
-void TextInput::ApplyStyleToRange(const TextStyle& style, const TextStyle::Mask mask, const std::size_t begin, const std::size_t end)
-{
- const std::size_t beginIndex = std::min( begin, end );
- const std::size_t endIndex = std::max( begin, end );
-
- // Apply the style
- MarkupProcessor::SetTextStyleToRange( mStyledText, style, mask, beginIndex, endIndex );
-
- // Create a styled text array used to replace the text into the text-view.
- MarkupProcessor::StyledTextArray text;
- text.insert( text.begin(), mStyledText.begin() + beginIndex, mStyledText.begin() + endIndex + 1 );
-
- mDisplayedTextView.ReplaceTextFromTo( beginIndex, ( endIndex - beginIndex ) + 1, text );
- GetTextLayoutInfo();
-
- if( IsScrollEnabled() )
- {
- // Need to set the scroll position as the text's size may have changed.
- ScrollTextViewToMakeCursorVisible( Vector3( mTextLayoutInfo.mScrollOffset.x, mTextLayoutInfo.mScrollOffset.y, 0.f ) );
- }
-
- ShowGrabHandleAndSetVisibility( false );
-
- DrawCursor();
-
- UpdateHighlight();
-
- // Set Handle positioning as the new style may have repositioned the characters.
- SetSelectionHandlePosition(HandleOne);
- SetSelectionHandlePosition(HandleTwo);
-}
-
-void TextInput::KeyboardStatusChanged(bool keyboardShown)
-{
- // Just hide the grab handle when keyboard is hidden.
- if (!keyboardShown )
- {
- ShowGrabHandleAndSetVisibility( false );
-
- // If the keyboard is not now being shown, then hide the popup panel
- mPopupPanel.Hide( true );
- }
-}
-
-// Removes highlight and resumes edit mode state
-void TextInput::RemoveHighlight( bool hidePopup )
-{
- DALI_LOG_INFO(gLogFilter, Debug::General, "RemoveHighlight\n");
-
- if ( mHighlightMeshActor )
- {
- if ( mSelectionHandleOne )
- {
- mActiveLayer.Remove( mSelectionHandleOne );
- mSelectionHandleOne.Reset();
- mSelectionHandleOneOffset.x = 0.0f;
- }
- if ( mSelectionHandleTwo )
- {
- mActiveLayer.Remove( mSelectionHandleTwo );
- mSelectionHandleTwo.Reset();
- mSelectionHandleTwoOffset.x = 0.0f;
- }
-
- mNewHighlightInfo.mQuadList.clear();
-
- Self().Remove( mHighlightMeshActor );
-
- SetCursorVisibility( true );
- StartCursorBlinkTimer();
-
- mHighlightMeshActor.Reset();
- // NOTE: We cannot dereference mHighlightMesh, due
- // to a bug in how the scene-graph MeshRenderer uses the Mesh data incorrectly.
-
- if ( hidePopup )
- {
- HidePopup();
- }
- }
-
- mSelectionHandleOnePosition = 0;
- mSelectionHandleTwoPosition = 0;
-}
-
-void TextInput::CreateHighlight()
-{
- if ( !mHighlightMeshActor )
- {
- mMeshData = MeshData( );
- mMeshData.SetHasNormals( true );
-
- mCustomMaterial = Material::New("CustomMaterial");
- mCustomMaterial.SetDiffuseColor( mMaterialColor );
-
- mMeshData.SetMaterial( mCustomMaterial );
-
- mHighlightMesh = Mesh::New( mMeshData );
-
- mHighlightMeshActor = MeshActor::New( mHighlightMesh );
- mHighlightMeshActor.SetName( "HighlightMeshActor" );
- mHighlightMeshActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
- mHighlightMeshActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
- mHighlightMeshActor.SetPosition( 0.0f, 0.0f, DISPLAYED_HIGHLIGHT_Z_OFFSET );
-
- Self().Add(mHighlightMeshActor);
- }
-}
-
-
-bool TextInput::CopySelectedTextToClipboard()
-{
- mCurrentCopySelecton.clear();
-
- mCurrentCopySelecton = GetSelectedText();
-
- std::string stringToStore;
-
- /* Create a StyledTextArray from the selected region so can use the MarkUpProcessor to produce
- * a marked up string.
- */
- MarkupProcessor::StyledTextArray selectedText(mCurrentCopySelecton.begin(),mCurrentCopySelecton.end());
- MarkupProcessor::GetPlainString( selectedText, stringToStore );
-
- bool success = mClipboard.SetItem( stringToStore );
- return success;
-}
-
-void TextInput::PasteText( const Text& text )
-{
- // Update Flag, indicates whether to update the text-input contents or not.
- // Any key stroke that results in a visual change of the text-input should
- // set this flag to true.
- bool update = false;
- if( mHighlightMeshActor )
- {
- /* if highlighted, delete entire text, and position cursor at start of deleted text. */
- mCursorPosition = std::min(mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
-
- ImfManager imfManager = ImfManager::Get();
- if ( imfManager )
- {
- imfManager.SetCursorPosition( mCursorPosition );
- imfManager.NotifyCursorPosition();
- }
- DeleteHighlightedText( true );
- update = true;
- }
-
- bool textExceedsMaximunNumberOfCharacters = false;
- bool textExceedsBoundary = false;
-
- std::size_t insertedStringLength = DoInsertAt( text, mCursorPosition, 0, textExceedsMaximunNumberOfCharacters, textExceedsBoundary );
-
- mCursorPosition += insertedStringLength;
- ImfManager imfManager = ImfManager::Get();
- if ( imfManager )
- {
- imfManager.SetCursorPosition ( mCursorPosition );
- imfManager.NotifyCursorPosition();
- }
-
- update = update || ( insertedStringLength > 0 );
- if( update )
- {
- CursorUpdate();
- EmitTextModified();
- }
-
- if( insertedStringLength < text.GetLength() )
- {
- EmitMaxInputCharactersReachedSignal();
- }
-
- if( textExceedsBoundary )
- {
- EmitInputTextExceedsBoundariesSignal();
- }
-}
-
-void TextInput::SetTextDirection()
-{
- // Put the cursor to the right if we are empty and an RTL language is being used.
- if ( mStyledText.empty() )
- {
- VirtualKeyboard::TextDirection direction( VirtualKeyboard::GetTextDirection() );
-
- // Get the current text alignment preserving the vertical alignment. Also preserve the horizontal center
- // alignment as we do not want to set the text direction if we've been asked to be in the center.
- //
- // TODO: Should split SetTextAlignment into two APIs to better handle this (sometimes apps just want to
- // set vertical alignment but are being forced to set the horizontal alignment as well with the
- // current API.
- int alignment( mDisplayedTextView.GetTextAlignment() &
- ( Toolkit::Alignment::VerticalTop |
- Toolkit::Alignment::VerticalCenter |
- Toolkit::Alignment::VerticalBottom |
- Toolkit::Alignment::HorizontalCenter ) );
- Toolkit::TextView::LineJustification justification( mDisplayedTextView.GetLineJustification() );
-
- // If our alignment is in the center, then do not change.
- if ( !( alignment & Toolkit::Alignment::HorizontalCenter ) )
- {
- alignment |= ( direction == VirtualKeyboard::LeftToRight ) ? Toolkit::Alignment::HorizontalLeft : Toolkit::Alignment::HorizontalRight;
- }
-
- // If our justification is in the center, then do not change.
- if ( justification != Toolkit::TextView::Center )
- {
- justification = ( direction == VirtualKeyboard::LeftToRight ) ? Toolkit::TextView::Left : Toolkit::TextView::Right;
- }
-
- mDisplayedTextView.SetTextAlignment( static_cast<Toolkit::Alignment::Type>(alignment) );
- mDisplayedTextView.SetLineJustification( justification );
- }
-}
-
-void TextInput::UpdateLineHeight()
-{
- Dali::Font font = Dali::Font::New( FontParameters( mInputStyle.GetFontName(), mInputStyle.GetFontStyle(), mInputStyle.GetFontPointSize() ) );
- mLineHeight = font.GetLineHeight();
-
- // If the height exceed policy is shrink or exceed the boundaries of the text-input is not allowed, then modify the line height is needed.
-
- const bool shrink = mDisplayedTextView && ( Toolkit::TextView::ShrinkToFit == mDisplayedTextView.GetHeightExceedPolicy() ) && mStyledText.empty();
-
- if( !mExceedEnabled || shrink )
- {
- mLineHeight = std::min( mLineHeight, GetControlSize().height );
- }
-}
-
-std::size_t TextInput::FindVisibleCharacter( FindVisibleCharacterDirection direction , std::size_t cursorPosition ) const
-{
- // VCC check if we need do this in the visual order ...
- std::size_t position = 0u;
-
- const std::size_t tableSize = mTextLayoutInfo.mCharacterLayoutInfoTable.size();
-
- switch( direction )
- {
- case Left:
- {
- position = FindVisibleCharacterLeft( cursorPosition, mTextLayoutInfo.mCharacterLayoutInfoTable );
-
- if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + ( tableSize == position ? position - 1u : position ) ) ).mIsVisible )
- {
- position = FindVisibleCharacterRight( cursorPosition, mTextLayoutInfo.mCharacterLayoutInfoTable );
- }
- break;
- }
- case Right:
- {
- position = FindVisibleCharacterRight( cursorPosition, mTextLayoutInfo.mCharacterLayoutInfoTable );
- if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + ( tableSize == position ? position - 1u : position ) ) ).mIsVisible )
- {
- position = FindVisibleCharacterLeft( cursorPosition, mTextLayoutInfo.mCharacterLayoutInfoTable );
- }
- break;
- }
- case ByEnd:
- {
- position = FindVisibleCharacterLeft( 0u, mTextLayoutInfo.mCharacterLayoutInfoTable );
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextInput::FindVisibleCharacter() Unknown direction." );
- }
- }
-
- return position;
-}
-
-void TextInput::SetSortModifier( float depthOffset )
-{
- if(mDisplayedTextView)
- {
- mDisplayedTextView.SetSortModifier(depthOffset);
- }
-}
-
-void TextInput::SetSnapshotModeEnabled( bool enable )
-{
- if(mDisplayedTextView)
- {
- mDisplayedTextView.SetSnapshotModeEnabled( enable );
- }
-}
-
-bool TextInput::IsSnapshotModeEnabled() const
-{
- bool snapshotEnabled = false;
-
- if(mDisplayedTextView)
- {
- snapshotEnabled = mDisplayedTextView.IsSnapshotModeEnabled();
- }
-
- return snapshotEnabled;
-}
-
-void TextInput::SetMarkupProcessingEnabled( bool enable )
-{
- mMarkUpEnabled = enable;
-}
-
-bool TextInput::IsMarkupProcessingEnabled() const
-{
- return mMarkUpEnabled;
-}
-
-void TextInput::SetScrollEnabled( bool enable )
-{
- if( mDisplayedTextView )
- {
- mDisplayedTextView.SetScrollEnabled( enable );
- }
-
- if( !enable )
- {
- // Don't set cursor's and handle's visibility to false if they are outside the
- // boundaries of the text-input.
- mIsCursorInScrollArea = true;
- mIsGrabHandleInScrollArea = true;
- if( mSelectionHandleOne && mSelectionHandleTwo )
- {
- mSelectionHandleOne.SetVisible( true );
- mSelectionHandleTwo.SetVisible( true );
-
- if( mHighlightMeshActor )
- {
- mHighlightMeshActor.SetVisible( true );
- }
- }
- }
-}
-
-bool TextInput::IsScrollEnabled() const
-{
- bool scrollEnabled = false;
-
- if( mDisplayedTextView )
- {
- scrollEnabled = mDisplayedTextView.IsScrollEnabled();
- }
-
- return scrollEnabled;
-}
-
-void TextInput::SetScrollPosition( const Vector2& position )
-{
- if( mDisplayedTextView )
- {
- mDisplayedTextView.SetScrollPosition( position );
- }
-}
-
-Vector2 TextInput::GetScrollPosition() const
-{
- Vector2 scrollPosition;
-
- if( mDisplayedTextView )
- {
- scrollPosition = mDisplayedTextView.GetScrollPosition();
- }
-
- return scrollPosition;
-}
-
-std::size_t TextInput::DoInsertAt( const Text& text, const std::size_t position, const std::size_t numberOfCharactersToReplace, bool& textExceedsMaximunNumberOfCharacters, bool& textExceedsBoundary )
-{
- // determine number of characters that we can write to style text buffer, this is the insertStringLength
- std::size_t insertedStringLength = std::min( text.GetLength(), mMaxStringLength - mStyledText.size() );
- textExceedsMaximunNumberOfCharacters = insertedStringLength < text.GetLength();
-
- // Add style to the new input text.
- MarkupProcessor::StyledTextArray textToInsert;
- for( std::size_t i = 0; i < insertedStringLength; ++i )
- {
- const MarkupProcessor::StyledText newStyledCharacter( text[i], mInputStyle );
- textToInsert.push_back( newStyledCharacter );
- }
-
- //Insert text to the TextView.
- const bool emptyTextView = mStyledText.empty();
- if( emptyTextView && mPlaceHolderSet )
- {
- // There is no text set so call to TextView::SetText() is needed in order to clear the placeholder text.
- mDisplayedTextView.SetText( textToInsert );
- }
- else
- {
- if( 0 == numberOfCharactersToReplace )
- {
- mDisplayedTextView.InsertTextAt( position, textToInsert );
- }
- else
- {
- mDisplayedTextView.ReplaceTextFromTo( position, numberOfCharactersToReplace, textToInsert );
- }
- }
- mPlaceHolderSet = false;
-
- if( textToInsert.empty() )
- {
- // If no text has been inserted, GetTextLayoutInfo() need to be called to check whether mStyledText has some text.
- GetTextLayoutInfo();
- }
- else
- {
- // GetTextLayoutInfo() can't be used here as mStyledText is not updated yet.
- mDisplayedTextView.GetTextLayoutInfo( mTextLayoutInfo );
- }
-
- textExceedsBoundary = false;
-
- if( !mExceedEnabled )
- {
- const Vector3& size = GetControlSize();
-
- if( ( mTextLayoutInfo.mTextSize.width > size.width ) || ( mTextLayoutInfo.mTextSize.height > size.height ) )
- {
- // If new text does not fit within TextView
- mDisplayedTextView.RemoveTextFrom( position, insertedStringLength );
- // previously inserted text has been removed. Call GetTextLayoutInfo() to check whether mStyledText has some text.
- GetTextLayoutInfo();
- textExceedsBoundary = true;
- insertedStringLength = 0;
- }
-
- if( textExceedsBoundary )
- {
- // Add the part of the text which fits on the text-input.
-
- // Split the text which doesn't fit in two halves.
- MarkupProcessor::StyledTextArray firstHalf;
- MarkupProcessor::StyledTextArray secondHalf;
- SplitText( textToInsert, firstHalf, secondHalf );
-
- // Clear text. This text will be filled with the text inserted.
- textToInsert.clear();
-
- // Where to insert the text.
- std::size_t positionToInsert = position;
-
- bool end = text.GetLength() <= 1;
- while( !end )
- {
- // Insert text and check ...
- const std::size_t textLength = firstHalf.size();
- mDisplayedTextView.InsertTextAt( positionToInsert, firstHalf );
- mDisplayedTextView.GetTextLayoutInfo( mTextLayoutInfo );
-
- if( ( mTextLayoutInfo.mTextSize.width > size.width ) || ( mTextLayoutInfo.mTextSize.height > size.height ) )
- {
- // Inserted text doesn't fit.
-
- // Remove inserted text
- mDisplayedTextView.RemoveTextFrom( positionToInsert, textLength );
- mDisplayedTextView.GetTextLayoutInfo( mTextLayoutInfo );
-
- // The iteration finishes when only one character doesn't fit.
- end = textLength <= 1;
-
- if( !end )
- {
- // Prepare next two halves for next iteration.
- MarkupProcessor::StyledTextArray copyText = firstHalf;
- SplitText( copyText, firstHalf, secondHalf );
- }
- }
- else
- {
- // Text fits.
-
- // store text to be inserted in mStyledText.
- textToInsert.insert( textToInsert.end(), firstHalf.begin(), firstHalf.end() );
-
- // Increase the inserted characters counter.
- insertedStringLength += textLength;
-
- // Prepare next two halves for next iteration.
- MarkupProcessor::StyledTextArray copyText = secondHalf;
- SplitText( copyText, firstHalf, secondHalf );
-
- // Update where next text has to be inserted
- positionToInsert += textLength;
- }
- }
- }
- }
-
- if( textToInsert.empty() && emptyTextView )
- {
- // No character has been added and the text-view was empty.
- // Show the placeholder text.
- ShowPlaceholderText( mStyledPlaceHolderText );
- }
- else
- {
- MarkupProcessor::StyledTextArray::iterator it = mStyledText.begin() + position;
- mStyledText.insert( it, textToInsert.begin(), textToInsert.end() );
- mPlaceHolderSet = false;
- }
-
- return insertedStringLength;
-}
-
-void TextInput::GetTextLayoutInfo()
-{
- if( mStyledText.empty() )
- {
- // The text-input has no text, clear the text-view's layout info.
- mTextLayoutInfo = Toolkit::TextView::TextLayoutInfo();
- }
- else
- {
- if( mDisplayedTextView )
- {
- mDisplayedTextView.GetTextLayoutInfo( mTextLayoutInfo );
- }
- else
- {
- // There is no text-view.
- mTextLayoutInfo = Toolkit::TextView::TextLayoutInfo();
- }
- }
-}
-
-void TextInput::SetOffsetFromText( const Vector4& offset )
-{
- mPopupOffsetFromText = offset;
-}
-
-const Vector4& TextInput::GetOffsetFromText() const
-{
- return mPopupOffsetFromText;
-}
-
-void TextInput::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
-{
- Toolkit::TextInput textInput = Toolkit::TextInput::DownCast( Dali::BaseHandle( object ) );
-
- if ( textInput )
- {
- TextInput& textInputImpl( GetImpl( textInput ) );
-
- switch ( propertyIndex )
- {
- case Toolkit::TextInput::HIGHLIGHT_COLOR_PROPERTY:
- {
- textInputImpl.SetMaterialDiffuseColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_COLOR_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupPressedColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupBorderColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupIconColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupIconPressedColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupTextColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupTextPressedColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCut, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCopy, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsPaste, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelect, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsClipboard, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY:
- {
- textInputImpl.SetOffsetFromText( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::CURSOR_COLOR_PROPERTY:
- {
- textInputImpl.mCursor.SetColor( value.Get< Vector4 >() );
- }
- }
- }
-}
-
-Property::Value TextInput::GetProperty( BaseObject* object, Property::Index propertyIndex )
-{
- Property::Value value;
-
- Toolkit::TextInput textInput = Toolkit::TextInput::DownCast( Dali::BaseHandle( object ) );
-
- if ( textInput )
- {
- TextInput& textInputImpl( GetImpl( textInput ) );
-
- switch ( propertyIndex )
- {
- case Toolkit::TextInput::HIGHLIGHT_COLOR_PROPERTY:
- {
- value = textInputImpl.GetMaterialDiffuseColor();
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_COLOR_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupColor();
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupPressedColor();
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY :
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupBorderColor();
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupIconColor();
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupIconPressedColor();
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupTextColor();
- break;
- }
- case Toolkit::TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupTextPressedColor();
- break;
- }
- case Toolkit::TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCut );
- break;
- }
- case Toolkit::TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCopy );
- break;
- }
- case Toolkit::TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsPaste );
- break;
- }
- case Toolkit::TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelect );
- break;
- }
- case Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll );
- break;
- }
- case Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsClipboard );
- break;
- }
- case Toolkit::TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY:
- {
- value = textInputImpl.GetOffsetFromText();
- break;
- }
- case Toolkit::TextInput::CURSOR_COLOR_PROPERTY:
- {
- value = textInputImpl.mCursor.GetCurrentColor();
- }
- }
- }
- return value;
-}
-
-void TextInput::EmitStyleChangedSignal()
-{
- // emit signal if input style changes.
- Toolkit::TextInput handle( GetOwner() );
- mStyleChangedSignal.Emit( handle, mInputStyle );
-}
-
-void TextInput::EmitTextModified()
-{
- // emit signal when text changes.
- Toolkit::TextInput handle( GetOwner() );
- mTextModifiedSignal.Emit( handle );
-}
-
-
-void TextInput::EmitMaxInputCharactersReachedSignal()
-{
- // emit signal if max characters is reached during text input.
- DALI_LOG_INFO(gLogFilter, Debug::General, "EmitMaxInputCharactersReachedSignal \n");
-
- Toolkit::TextInput handle( GetOwner() );
- mMaxInputCharactersReachedSignal.Emit( handle );
-}
-
-void TextInput::EmitInputTextExceedsBoundariesSignal()
-{
- // Emit a signal when the input text exceeds the boundaries of the text input.
-
- Toolkit::TextInput handle( GetOwner() );
- mInputTextExceedBoundariesSignal.Emit( handle );
-}
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/actors/mesh-actor.h>
-#include <dali/public-api/adaptor-framework/clipboard.h>
-#include <dali/public-api/adaptor-framework/clipboard-event-notifier.h>
-#include <dali/public-api/adaptor-framework/imf-manager.h>
-#include <dali/public-api/adaptor-framework/timer.h>
-#include <dali/public-api/common/dali-vector.h>
-#include <dali/public-api/geometry/mesh.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/control-impl.h>
-#include <dali-toolkit/public-api/controls/text-input/text-input.h>
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
-#include <dali-toolkit/public-api/controls/buttons/push-button.h>
-#include <dali-toolkit/internal/controls/text-input/text-input-popup-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-class TextInput;
-class TextView;
-
-typedef IntrusivePtr<TextInput> TextInputPtr;
-
-class TextInput : public Control
-{
-public:
-
- // Properties
- enum
- {
- TEXTINPUT_PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
- TEXTINPUT_PROPERTY_END_INDEX = TEXTINPUT_PROPERTY_START_INDEX + 512 ///< Reserving property indices
- };
-
- /**
- * Create a new TextInput
- * @return instrusive ptr to a TextInput
- */
- static Dali::Toolkit::TextInput New();
-
- /**
- * @copydoc Toolkit::TextInput::GetText
- */
- std::string GetText() const;
-
- /**
- * @copydoc Toolkit::TextInput::GetMarkupText()
- */
- std::string GetMarkupText() const;
-
- /**
- * @copydoc Toolkit::TextInput::SetPlaceholderText
- */
- void SetPlaceholderText( const std::string& placeHolderText );
-
- /**
- * @copydoc Toolkit::TextInput::SetPlaceholderText
- */
- std::string GetPlaceholderText();
-
- /**
- * @copydoc Toolkit::TextInput::SetInitialText
- */
- void SetInitialText(const std::string& initialText);
-
- /**
- * set the text to be displayed in text-input, will overwrite any existing text.
- * can be used to clear the text-input by passing an empty string.
- * @param [in] initialText text to be initially displayed
- */
- void SetText(const std::string& initialText);
-
- /**
- * @copydoc Toolkit::TextInput::SetMaxCharacterLength
- */
- void SetMaxCharacterLength(std::size_t maxChars);
-
- /**
- * @copydoc Toolkit::TextInput::SetNumberOfLinesLimit
- */
- void SetNumberOfLinesLimit(std::size_t maxLines);
-
- /**
- * @copydoc Toolkit::TextInput::GetNumberOfLinesLimit
- */
- std::size_t GetNumberOfLinesLimit() const;
-
- /**
- * @copydoc Toolkit::TextInput::GetFont
- */
- Font GetFont() const;
-
- /**
- * @copydoc Toolkit::TextInput::SetFont
- */
- void SetFont(Font font);
-
- /**
- * @copydoc Toolkit::TextInput::InputStartedSignal()
- */
- Toolkit::TextInput::InputSignalType& InputStartedSignal();
-
- /**
- * @copydoc Toolkit::TextInput::InputFinishedSignal()
- */
- Toolkit::TextInput::InputSignalType& InputFinishedSignal();
-
- /**
- * @copydoc Toolkit::TextInput::CutAndPasteToolBarDisplayedSignal()
- */
- Toolkit::TextInput::InputSignalType& CutAndPasteToolBarDisplayedSignal();
-
- /**
- * @copydoc Toolkit::TextInput::StyleChangedSignal()
- */
- Toolkit::TextInput::StyleChangedSignalType& StyleChangedSignal();
-
- /**
- * @copydoc Toolkit::TextInput::TextModifiedSignal()
- */
- Toolkit::TextInput::TextModifiedSignalType& TextModifiedSignal();
-
- /**
- * @copydoc Toolkit::TextInput::MaxInputCharactersReachedSignal()
- */
- Toolkit::TextInput::MaxInputCharactersReachedSignalType& MaxInputCharactersReachedSignal();
-
- /**
- * @copydoc Toolkit::TextInput::InputTextExceedBoundariesSignal()
- */
- Toolkit::TextInput::InputTextExceedBoundariesSignalType& InputTextExceedBoundariesSignal();
-
- /**
- * Connects a callback function with the object's signals.
- * @param[in] object The object providing the signal.
- * @param[in] tracker Used to disconnect the signal.
- * @param[in] signalName The signal to connect to.
- * @param[in] functor A newly allocated FunctorDelegate.
- * @return True if the signal was connected.
- * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
- */
- static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
-
- /**
- * @see Toolkit::TextInput::SetEditMode(bool editMode)
- * @see Toolkit::TextInput::SetEditMode(bool editMode, const Vector2& touchPoint)
- *
- * @param[in] editMode true or false to indicate editMode on or off.
- * @param[in] setCursorOnTouchPoint Whether to use the touch point to set the cursor position.
- * @param[in] touchPoint A position in actor coordinates within the text-input.
- */
- void SetEditable(bool editMode, bool setCursorOnTouchPoint, const Vector2& touchPoint = Vector2::ZERO);
-
- /**
- * @copydoc Toolkit::TextInput::GetEditMode
- */
- bool IsEditable() const;
-
- /**
- * @copydoc Toolkit::TextInput::SetTextSelectable
- */
- void SetTextSelectable(bool textSelectable = true);
-
- /**
- * @copydoc Toolkit::TextInput::IsTextSelectable
- */
- bool IsTextSelectable() const;
-
- /**
- * @copydoc Toolkit::TextInput::IsTextSelected
- */
- bool IsTextSelected() const;
-
- /**
- * @copydoc Toolkit::TextInput::DeSelectText
- */
- void DeSelectText();
-
- /**
- * @copydoc Toolkit::TextInput::SetEditOnTouch
- */
- void SetEditOnTouch(bool editOnTouch);
-
- /**
- * @copydoc Toolkit::TextInput::IsEditOnTouch
- */
- bool IsEditOnTouch() const;
-
- /**
- * @copydoc Toolkit::TextInput::SetGrabHandleImage
- */
- void SetGrabHandleImage(Dali::Image image);
-
- /**
- * @copydoc Toolkit::TextInput::SetCursorImage
- */
- void SetCursorImage(Dali::Image image, const Vector4& border );
-
- /**
- * @copydoc Toolkit::TextInput::GetSelectionHandleSize
- */
- Vector3 GetSelectionHandleSize();
-
- /**
- * @copydoc Toolkit::TextInput::SetRTLCursorImage
- */
- void SetRTLCursorImage(Dali::Image image, const Vector4& border );
-
- /**
- * @copydoc Toolkit::TextInput::EnableGrabHandle
- */
- void EnableGrabHandle(bool toggle);
-
- /**
- * @copydoc Toolkit::TextInput::IsGrabHandleEnabled
- */
- bool IsGrabHandleEnabled();
-
- /**
- * @copydoc Toolkit::TextInput::EnableSelectionHandleFlip
- */
- void EnableSelectionHandleFlip( bool toggle );
-
- /**
- * @copydoc Toolkit::TextInput::IsSelectionHandleFlipEnabled
- */
- bool IsSelectionHandleFlipEnabled();
-
- /**
- * @copydoc Toolkit::TextInput::SetSelectionHandleFlipMargin
- */
- void SetSelectionHandleFlipMargin( const Vector4& margin );
-
- /**
- * @copydoc Toolkit::TextInput::SetBoundingRectangle
- */
- void SetBoundingRectangle( const Rect<float>& boundingRectangle );
-
- /**
- * @copydoc Toolkit::TextInput::GetBoundingRectangle
- */
- const Rect<float> GetBoundingRectangle() const;
-
- /**
- * @copydoc Toolkit::TextInput::GetSelectionHandleFlipMargin
- */
- const Vector4& GetSelectionHandleFlipMargin();
-
- /**
- * @copydoc Toolkit::TextInput::SetTextColor
- */
- void SetTextColor( const Vector4& color );
-
- /**
- * @copydoc Toolkit::TextInput::SetActiveStyle
- */
- void SetActiveStyle( const TextStyle& style, const TextStyle::Mask mask );
-
- /**
- * @copydoc Toolkit::TextInput::ApplyStyle
- */
- void ApplyStyle( const TextStyle& style, const TextStyle::Mask mask );
-
- /**
- * @copydoc Toolkit::TextInput::ApplyStyleToAll
- */
- void ApplyStyleToAll( const TextStyle& style, const TextStyle::Mask mask );
-
- /**
- * @copydoc Toolkit::TextInput::GetStyleAtCursor
- */
- TextStyle GetStyleAtCursor() const;
-
- /**
- * Retrieves the character style for the given position.
- * @param[in] position The character position which style is required.
- * @return The style for the given position.
- */
- TextStyle GetStyleAt( std::size_t position ) const;
-
- /**
- * @copydoc Toolkit::TextInput::SetTextAlignment()
- */
- void SetTextAlignment( Toolkit::Alignment::Type align );
-
- /**
- * @copydoc Toolkit::TextInput::SetTextLineJustification()
- */
- void SetTextLineJustification( Toolkit::TextView::LineJustification justification );
-
- /**
- * @copydoc Toolkit::TextInput::SetFadeBoundary()
- */
- void SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary );
-
- /**
- * @copydoc Toolkit::TextInput::GetFadeBoundary()
- */
- const Toolkit::TextView::FadeBoundary& GetFadeBoundary() const;
-
- /**
- * @copydoc Toolkit::TextInput::GetTextAlignment()
- */
- Toolkit::Alignment::Type GetTextAlignment() const;
-
- /**
- * @copydoc Toolkit::TextInput::SetMultilinePolicy()
- */
- void SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy );
-
- /**
- * @copydoc Toolkit::TextInput::GetMultilinePolicy()
- */
- Toolkit::TextView::MultilinePolicy GetMultilinePolicy() const;
-
- /**
- * @copydoc Toolkit::TextInput::SetWidthExceedPolicy()
- */
- void SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy );
-
- /**
- * @copydoc Toolkit::TextInput::GetWidthExceedPolicy()
- */
- Toolkit::TextView::ExceedPolicy GetWidthExceedPolicy() const;
-
- /**
- * @copydoc Toolkit::TextInput::SetHeightExceedPolicy()
- */
- void SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy );
-
- /**
- * @copydoc Toolkit::TextInput::GetHeightExceedPolicy()
- */
- Toolkit::TextView::ExceedPolicy GetHeightExceedPolicy() const;
-
- /**
- * @copydoc Toolkit::TextInput::SetExceedEnabled()
- */
- void SetExceedEnabled( bool enable );
-
- /**
- * @copydoc Toolkit::TextInput::GetExceedEnabled()
- */
- bool GetExceedEnabled() const;
-
- /**
- * @copydoc Toolkit::TextInput::SetBackground
- */
- void SetBackground(Dali::Image image );
-
- /**
- * @copydoc Toolkit::TextInput::SetNumberOfLines
- */
- void SetNumberOfLines(std::size_t lines);
-
- /**
- * @copydoc Toolkit::TextInput::GetNumberOfLines
- */
- std::size_t GetNumberOfLines();
-
- /**
- * @copydoc Toolkit::TextInput::GetNumberOfCharacters
- */
- std::size_t GetNumberOfCharacters() const;
-
- /**
- * Styling
- */
-
- /**
- * Set the diffuse color for the highlight
- * @param[in] color color to use
- */
- void SetMaterialDiffuseColor( const Vector4& color );
-
- /**
- * Get the diffuse color used by the highlight
- * @return color
- */
- const Vector4& GetMaterialDiffuseColor() const;
-
-private:
-
- /**
- * structure to hold each highlight box needed for text selection
- */
- struct HighlightBox
- {
- Vector3 size; ///< size of the highlight box
- Vector3 position; ///< position of highlight box
- ImageActor highlightBoxActor; ///< as actor that is the highlight box
- };
-
- /**
- * structure to hold each character in displayed string and its position from the left
- */
- struct CharPositions
- {
- char character; ///< todo change to UTF to aid multi-language support
- Vector3 position;
- Vector2 size;
- };
-
- /**
- * structure to hold coordinates of each quad, which will make up the mesh.
- */
- struct QuadCoordinates
- {
- /**
- * Default constructor
- */
- QuadCoordinates()
- {
- }
-
- /**
- * Constructor
- * @param[in] x1 left co-ordinate
- * @param[in] y1 top co-ordinate
- * @param[in] x2 right co-ordinate
- * @param[in] y2 bottom co-ordinate
- */
- QuadCoordinates(float x1, float y1, float x2, float y2)
- : min(x1, y1),
- max(x2, y2)
- {
- }
-
- Vector2 min; ///< top-left (minimum) position of quad
- Vector2 max; ///< bottom-right (maximum) position of quad
- };
-
- typedef std::vector<QuadCoordinates> QuadContainer;
-
- /**
- * structure for information required to build the highlight mesh
- */
- struct HighlightInfo
- {
- /**
- * Adds a Quad (2D rectangular sub-selection)
- * @param[in] x1 left co-ordinate
- * @param[in] y1 top co-ordinate
- * @param[in] x2 right co-ordinate
- * @param[in] y2 bottom co-ordinate
- */
- void AddQuad( float x1, float y1, float x2, float y2 );
-
- /**
- * Clamps all quads to fit within a min -> max 2D boundary.
- */
- void Clamp2D(const Vector2& min, const Vector2& max);
-
- QuadContainer mQuadList; ///< List of quads (sub-selections that form to create complete selection)
- };
-
- /**
- * Holds requested selection start and end points for highlighted text.
- */
- struct SelectionParameters
- {
- SelectionParameters( size_t start, size_t end )
- : mStartOfSelection( start ), mEndOfSelection( end )
- {
-
- }
-
- size_t mStartOfSelection;
- size_t mEndOfSelection;
- };
-
- enum State
- {
- StateEdit,
- StateDraggingHandle
- };
-
- enum SelectionHandleId
- {
- HandleOne, ///< Selection handle one which is on the left
- HandleTwo ///< Selection handle two which is on the right
- };
-
- /**
- * Two different behaviours are needed to convert a touch point into a character index.
- * When a tap is received and the touch point doesn't hit any character, the final character selected might
- * be different than the one selected if the event is a pan.
- * i.e. If a tap is received and the touch point doesn't hit any character the expected position of the cursor
- * would be the end or the beginning of a line. However, this behaviour would be weird while panning.
- */
- enum TouchToIndex
- {
- TapMode, ///< Touch point to character index conversion mode used for Tap events.
- DragMode ///< Touch point to character index conversion mode used for Pan events.
- };
-
- /**
- * Used to set the direction when find the next visible character.
- */
- enum FindVisibleCharacterDirection
- {
- Left, ///< Find visible characters on the left.
- Right, ///< Find visible characters on the right.
- ByEnd ///< Start finding visible characters by the end.
- };
-
- /**
- *
- */
- virtual bool OnTouchEvent(const TouchEvent& event);
-
- /**
- * From CustomActorImpl; called after the Text Input actor is touched
- * @param[in] event The KeyEvent event.
- * @return True if the event should be consumed.
- */
- virtual bool OnKeyEvent(const KeyEvent& event);
-
- /**
- * From CustomActorImpl; called when this actor gains keyboard focus.
- */
- virtual void OnKeyInputFocusGained();
-
- /**
- * From CustomActorImpl; called when this actor loses keyboard focus.
- */
- virtual void OnKeyInputFocusLost();
-
- /**
- * From Control; called whenever the control is added to the stage.
- */
- virtual void OnControlStageConnection();
-
-private: // From Control
-
- /**
- * Creation of the layer that is used by top level active parts of the TextInput like handles
- */
- void CreateActiveLayer();
-
- /**
- * @copydoc Control::OnInitialize()
- */
- virtual void OnInitialize();
-
- /**
- * @copydoc Control::OnControlSizeSet()
- */
- virtual void OnControlSizeSet(const Vector3& targetSize);
-
- /**
- * @copydoc Control::OnRelayout()
- */
- virtual void OnRelayout( const Vector2& size, ActorSizeContainer& container );
-
- /**
- * Retrieves the text-input's natural size by calling TextView::GetNaturalSize().
- *
- * @return The natural size.
- */
- virtual Vector3 GetNaturalSize();
-
- /**
- * Retrieves the text-input's \e height for a given \e width by calling TextView::GetHeightForWidth().
- *
- * @param[in] width The given \e width.
- *
- * @return The \e height for the given \e width.
- */
- virtual float GetHeightForWidth( float width );
-
-protected:
-
- /**
- * Construct a new TextInput.
- */
- TextInput();
-
- /**
- * A reference counted object may only be deleted by calling Unreference()
- */
- virtual ~TextInput();
-
-private:
-
- // Undefined
- TextInput(const TextInput&);
-
- // Undefined
- TextInput& operator=(const TextInput& rhs);
-
- /**
- * Callback when a handle is panned/moved, either selection handles or grab handle
- * @param actor Handle of the selection or grab handle.
- * @param gesture Data structure with the parameters of the gesture.
- */
- void OnHandlePan(Actor actor, const PanGesture& gesture);
-
- /**
- * Callback for touch down on Grab handle
- * @param[in] actor touched
- * @param[in] touch touch event
- */
- bool OnPressDown(Dali::Actor actor, const TouchEvent& touch);
-
- /**
- * Callback for touch down on Selection handle one
- * @param[in] actor touched
- * @param[in] touch touch event, used to determine if down or up event
- */
- bool OnHandleOneTouched(Dali::Actor actor, const TouchEvent& touch);
-
- /**
- * Callback for touch down on Selection handle two
- * @param[in] actor touched
- * @param[in] touch touch event, used to determine if down or up event
- */
- bool OnHandleTwoTouched(Dali::Actor actor, const TouchEvent& touch);
-
- /**
- * Callback for tap on TextInput
- * @param[in] actor
- * @param[in] tap touch event
- */
- void OnTextTap(Dali::Actor actor, const Dali::TapGesture& tap);
-
- /**
- * Callback for double tap on TextInput
- * @param[in] actor
- * @param[in] tap touch event
- */
- void OnDoubleTap(Dali::Actor actor, const Dali::TapGesture& tap);
-
- /**
- * Callback for long press on TextInput
- * @param[in] actor
- * @param[in] longPress long press event
- */
- void OnLongPress(Dali::Actor actor, const Dali::LongPressGesture& longPress);
-
- /**
- * Callback for the ClipboardEventNotifier when text is selected in the clipboard window.
- * @param[in] notifier The Clipboard Event Notifier.
- */
- void OnClipboardTextSelected( ClipboardEventNotifier& notifier );
-
- /**
- * Callback for when a button is pressed in popup panel
- * @param[in] button handle to the button pressed.
- */
- bool OnPopupButtonPressed( Toolkit::Button button );
-
- /**
- * Callback when handle timer ticks.
- *
- * Cursor should become visible/invisible to simulate blinking.
- *
- * @return True if the timer should be keep running.
- */
- bool OnCursorBlinkTimerTick();
-
- /**
- * Invoked upon popup Hide animation completing.
- * @note Only called for animating hide, not called for instantaneous (animate = false)
- * @param[in] popup The popup which was hidden.
- */
- void OnPopupHideFinished(TextInputPopup& popup);
-
- /**
- * Called in OnKeyEvent to handle key down events.
- * @param[in] event The KeyEvent event.
- * @return True if the event should be consumed.
- */
- bool OnKeyDownEvent(const KeyEvent& event);
-
- /**
- * Called in OnKeyEvent to handle key up events.
- * @param[in] event The KeyEvent event.
- * @return True if the event should be consumed.
- */
- bool OnKeyUpEvent(const KeyEvent& event);
-
- /**
- * Chooses from all handle position and alternative handle positions where to set the position of the two selection handles.
- *
- * @param[in] cursorPositionOne The initial position of the first selection handle.
- * @param[in] cursorPositionTwo The initial position of the second selection handle.
- * @param[in] altPositionValidOne Whether there is an alternative position for the first selection handle.
- * @param[in] altPositionValidTwo Whether there is an alternative position for the second selection handle.
- * @param[in] altPositionOne The alternative position of the first selection handle.
- * @param[in] altPositionTwo The alternative position of the second selection handle.
- */
- void ChooseRtlSelectionHandlePosition( const Vector3& cursorPositionOne,
- const Vector3& cursorPositionTwo,
- bool altPositionValidOne,
- bool altPositionValidTwo,
- const Vector3& altPositionOne,
- const Vector3& altPositionTwo );
- /**
- * Callback called when the text-view is scrolled.
- *
- * Updates the selection and grab handles, and the highlighted text.
- *
- * @param[in] textView Handle of the text-view.
- * @param[in] scrollPosition The difference with the previous scroll position.
- */
- void OnTextViewScrolled( Toolkit::TextView textView, Vector2 scrollPosition );
-
- /**
- * Scrolls the text-view to make the cursor visible.
- *
- * @param[in] cursorPosition The actual cursor position in actor coordinates.
- */
- void ScrollTextViewToMakeCursorVisible( const Vector3& cursorPosition );
-
- /**
- * Creates and starts a timer to scroll the text when handles are close to the edges of the text-input.
- *
- * It only starts the timer if it's already created.
- */
- void StartScrollTimer();
-
- /**
- * Stops the timer used to scroll the text.
- */
- void StopScrollTimer();
-
- /**
- * Callback called by the timer used to scroll the text.
- *
- * It calculates and sets a new scroll position.
- */
- bool OnScrollTimerTick();
-
-public: // Public to allow internal testing.
-
- /**
- * Register for touch events
- */
- void SetUpTouchEvents();
-
- /**
- * Sets up TextView Actor
- */
- void CreateTextViewActor();
-
- /**
- * Set Styled Text for text input.
- * @param[in] styleText The new styled text for the text input.
- */
- void SetText( const MarkupProcessor::StyledTextArray& styleText );
-
- /**
- * Start a timer to signal cursor to blink.
- */
- void StartCursorBlinkTimer();
-
- /**
- * Stop the timer signalling the cursor to blink.
- */
- void StopCursorBlinkTimer();
-
- /**
- * Starts input, setting focus and showing keyboard..
- */
- void StartEditMode();
-
- /**
- * Called when End of input and focus no longer required, keyboard is hidden.
- */
- void EndEditMode();
-
- /**
- * Applies a style to the current pre-edit / predicted word to show it is being edited.
- * @param[in] preEditStartPosition position in text array that the predicted word starts at
- * @param[in] preEditStringLength used to calculate how many characters need their style changed.
- */
- void ApplyPreEditStyle( std::size_t preEditStartPosition, std::size_t preEditStringLength );
-
- /**
- * Restores style to value before applying Pre-Edit style.
- */
- void RemovePreEditStyle();
-
- /**
- * Event received from IMF manager
- * @return ImfCallbackData data struture undicating if update is needed, cursor position and current text
- */
- ImfManager::ImfCallbackData ImfEventReceived( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& test );
-
- /**
- * Called when the OnKey event is a Pre-edit string
- * @param[in] keyString String received in Pre-edit
- * @param[in] cursorOffset the cursor offset from where the pre-edit word starts
- * @return bool true if preedit reset is required.
- */
- bool PreEditReceived( const std::string& keyString, std::size_t cursorOffset );
-
- /**
- * Called when the OnKey event is a Commit string
- * @param[in] keyString String received in Comment
- * @return update flag to trigger cursor update of TextInput only when needed.
- */
- bool CommitReceived( const std::string& keyString );
-
- /**
- * Deletes Pre-edit string
- * By default it doesn't update the character's size and position table, which is a costly
- * operation. As in many cases deletion and insertion (InsertAt) of text
- * occurs in the same action i.e. preedit/commit. It makes sense to
- * delete without updating, and then insert with updating.
- *
- * @return The number of characters to be deleted.
- */
- std::size_t DeletePreEdit();
-
- /**
- * Reset all pre-edit flag and signal IMF keyboard that the current pre-edit word has been comitted.
- * This may be due to the cursor being moved by user or reached the max character limit.
- * @param[in] preserveCursorPosition Set true to keep cursor in current position, eg. touch event caused cursor to move.
- */
- void PreEditReset( bool preserveCursorPosition );
-
- /**
- * Called after cursor position needs updating.
- * Redraws cursor and notifies VirtualKeyboard
- */
- void CursorUpdate();
-
- /**
- * Delete highlighted characters
- * @param[in] inheritStyle Whether style from previous character in the string should be inherited.
- */
- void DeleteHighlightedText( bool inheritStyle );
-
- /*
- * Delete range of characters
- * @param[in] start position of characters to delete
- * @param[in] ncharacters number of characters to delete
- */
- void DeleteRange(std::size_t start, std::size_t ncharacters);
-
- /**
- * Delete character at current cursor position and redisplay
- * @param[in] positionToDelete position of character to delete
- */
- void DeleteCharacter( std::size_t positionToDelete );
-
- /**
- * Add or replaces characters to currently displayed string at cursor position
- * By default it doesn't update the character's size and position table, which is a costly
- * operation. As in many cases deletion and insertion (InsertAt) of text
- * occurs in the same action i.e. preedit/commit. It makes sense to
- * delete without updating, and then insert with updating.
- * @param[in] newText string to add to TextInput display string.
- * @param[in] insertionPosition position to insert at.
- * @param[in] numberOfCharactersToReplace The number of characters to replace.
- * @return number of characters to offset the cursor by.
- */
- std::size_t InsertAt( const Text& newText, const std::size_t insertionPosition, const std::size_t numberOfCharactersToReplace );
-
- /**
- * Creates a cursor.
- * @param[in] color the cursor color.
- * @return the image actor to be used as the cursor.
- */
- ImageActor CreateCursor( const Vector4 &color );
-
- /**
- * Moves cursor to the right
- * param[in] reverse if true then cursor moves in the reverse direction (to the left)
- * param[in] places number of character cursor should move.
- */
- void AdvanceCursor(bool reverse = false, std::size_t places = 1);
-
- /**
- * Draw a cursor / caret at position where new text should appear
- */
- void DrawCursor();
-
- /**
- * Sets cursor visibility
- * This sets visibility of the cursor. Which is comprised of 2
- * cursors. The conventional cursor, and the alternate (RTL) cursor,
- * which only appears when the cursor is at a character that can have
- * a character appended to different visual positions depending on whether that
- * character to be appended is RTL or LTR.
- * @param[in] visible true - enable visibility for cursor, false - disable visiblity for cursor
- */
- void SetCursorVisibility( bool visible );
-
- /**
- * Sets alternate cursor enable state
- * @see SetCursorVisibility
- * alternate cursor will only be visible if both SetCursorVisiblity
- * and cursor enabled have been set to true.
- */
- void SetAltCursorEnabled( bool enabled );
-
- /**
- * Create the grab handle that positions the cursor
- * @param[in] image to be used for grab handle
- *
- */
- void CreateGrabHandle(Image image=Image());
-
- /**
- * Create Grab area to be used by Grab Handle
- */
- void CreateGrabArea( Actor& parent);
-
- /**
- * Move grab handle to the required character position
- *
- * @param[in] displacement Displacement of the grab handle in actor coordinates.
- *
- * @return The new actual position the handle has been set to.
- */
- Vector3 MoveGrabHandle( const Vector2& displacement );
-
- /**
- * Show or hide the grab handle without baking the visibility flag.
- * Used when the Grab handle needs to be invisible due to text-view scrolling making it out of view
- *
- * @param[in] visible bool flag to set as true is grab handle should be shown, else false to hide.
- */
- void ShowGrabHandle( bool visible );
-
- /**
- * Show or hide the grab handle and bake the visibility flag.
- * Used when the state of text-input changes to a state which the grabhandle is not required. E.g. Selection mode starts or edit mode ends.
- * Calls ShowGrabHandle.
- *
- * @param[in] visible bool flag to set as true is grab handle should be shown, else false to hide.
- */
- void ShowGrabHandleAndSetVisibility( bool visible );
-
- /* Boundary Property Notifications when handle exceed bounding box*/
-
- /**
- * PropertyNotification Callback when left boundary exceeded so handle can be flipped.
- * @param[in] source PropertyNotification
- */
- void OnLeftBoundaryExceeded( PropertyNotification& source );
- /**
- * PropertyNotification Callback when within left boundary so handle can be flipped back.
- * @param[in] source PropertyNotification
- */
- void OnReturnToLeftBoundary( PropertyNotification& source );
- /**
- * PropertyNotification Callback when right boundary exceeded so handle can be flipped.
- * @param[in] source PropertyNotification
- */
- void OnRightBoundaryExceeded( PropertyNotification& source );
- /**
- * * PropertyNotification Callback when within right boundary so handle can be flipped back.
- * @param[in] source PropertyNotification
- */
- void OnReturnToRightBoundary( PropertyNotification& source );
-
- /**
- * PropertyNotification Callbacks for hiding handle one when it exceeds boundary.
- * @param[in] source PropertyNotification
- */
- void OnHandleOneLeavesBoundary( PropertyNotification& source );
- /**
- * PropertyNotification Callbacks for showing hidden handle one when returns within boundary
- * @param[in] source PropertyNotification
- */
- void OnHandleOneWithinBoundary( PropertyNotification& source );
- /**
- * PropertyNotification Callbacks for hiding handle two it when exceeds boundary.
- * @param[in] source PropertyNotification
- */
- void OnHandleTwoLeavesBoundary( PropertyNotification& source );
- /**
- * PropertyNotification Callbacks for showing hidden handle two when returns within boundary
- * * @param[in] source PropertyNotification
- */
- void OnHandleTwoWithinBoundary( PropertyNotification& source );
-
- /**
- * Set up property notifications on the position of the handles to facilitate flipping and hiding when at screen boundary.
- */
- void SetUpHandlePropertyNotifications();
-
- /**
- * Create the selection handles that bound text to be selected for copy/cut.
- * @param[in] start initial position of start selection handle.
- * @param[in] end initial position of end selection handle.
- * @param[in] handleOneImage (optional) to be used for selection handle
- * @param[in] handleTwoImage (optional) to be used for selection handle
- */
- void CreateSelectionHandles( std::size_t start = 0, std::size_t end = std::numeric_limits<std::size_t>::max(), Dali::Image handleOneImage = Dali::Image(), Dali::Image handleTwoImage = Dali::Image() );
-
- /**
- * Move the selection handles to required positions in text.
- *
- * @param[in] handleId the handle to position
- * @param[in] displacement Displacement of the selection handle in actor coordinates.
- *
- * @return The new actual position the handle has been set to.
- */
- Vector3 MoveSelectionHandle(SelectionHandleId handleId, const Vector2& displacement);
-
- /**
- * Calculate and position the specified selection handle the given index position
- *
- * @param[in] handleId the handle to position
- */
- void SetSelectionHandlePosition(SelectionHandleId handleId);
-
- /**
- * Gets a table of the visual text positions which has a flag
- * for each Character. The flag is either true (character selected)
- * or false (character deselected)
- * @note startSelection can be greater or less than endSelection
- *
- * @param[in,out] selectedVisualText The vector to be resized and populated with the selected flags
- * @param[in] startSelection The start selection point for the text
- * @param[in] endSelection The end selection point for the text
- */
- void GetVisualTextSelection(std::vector<bool>& selectedVisualText, std::size_t startSelection, std::size_t endSelection);
-
- /**
- * Iterates between selection handles and computes the info required to build the highlight mesh
- */
- HighlightInfo CalculateHighlightInfo();
-
- /**
- * This method was added to fix a PLM. it creates one quad per character so the mesh can show different selection boxes when a mix of right to left and left to right text is selected.
- */
- HighlightInfo CalculateHighlightInfoRtl();
-
- /**
- * Calculates new Mesh data so highlight moves with selection handles.
- */
- void UpdateHighlight();
-
- /**
- * Removes popup, and its options.
- */
- void ClearPopup();
-
- /**
- * Adds Popup options which have been enabled.
- */
- void AddPopupOptions();
-
- /**
- * Sets popup position
- * @param[in] position The actual position for this popup.
- * @param[in] alternativePosition Alternative popup position if no space in upper area.
- */
- void SetPopupPosition(const Vector3& position, const Vector2& alternativePosition );
-
- /**
- * Hides the popup
- * @param[in] animate (optional) whether to animate popup to hide state over time (i.e. tween).
- * @param[in] signalFinished (optional) whether to perform an animation finish operation after the hide animation completes. Requires animate to be true.
- */
- void HidePopup( bool animate = true, bool signalFinished = true );
-
- /**
- * Shows the popup
- * @param[in] animate (optional) whether to animate popup to show state over time (i.e. tween).
- */
- void ShowPopup(bool animate = true);
-
- /**
- * Shows the cut-copy-paste popup
- */
- void ShowPopupCutCopyPaste();
-
- /**
- * Setup the selection popup and clipboard if relevant so the correct options are shown when ShowPopup is called.
- * @param[in] showCutButton Flag to show or hide cut button, in some cases like whitespace we do not want to cut just select.
- * default is true.
- */
- void SetUpPopupSelection( bool showCutButton = true );
-
- /**
- * Return the logical index containing the character position closest to the source.
- * Used for positioning the grab handle at characters when dragged along.
- * Two different behaviours are needed in case the source point doesn't actually touch a
- * character. @see TouchToIndex.
- * @param[in] source float to match against
- * @param[out] closestIndex index to the vector of character's size and position.
- * @return \e true if the source point is actually inside the geometry provided by TextView.
- */
- bool ReturnClosestIndex(const Vector2& source, std::size_t& closestIndex );
-
- /**
- * Returns the X-position of the current line justification
- * (relative to left of text-view container)
- * @return X position for line justification
- */
- float GetLineJustificationPosition() const;
-
- /**
- * Currently the cursor is positioned at the previous characters position plus it's width.
- * If the previous character is on a different line then this function returns the correct position.
- * @param[in] characterPosition the character position index that the cursor should be at
- * @return position of cursor/handle
- */
- Vector3 PositionCursorAfterWordWrap( std::size_t characterPosition ) const;
-
-
- /**
- * Return a vector which is the actual position for the given character position
- * The character position is where a cursor would be position for that character.
- * @param[in] characterPosition the logical (input) position in the 'string' of characters.
- *
- * @return Vector3 the actual x,y,z position
- */
- Vector3 GetActualPositionFromCharacterPosition(std::size_t characterPosition ) const;
-
- /**
- * Return a vector which is the actual position for the given character position
- * The character position is where a cursor would be positioned for that character to be inserted.
- * An additional alternatePosition is also set in circumstances where the possible writing
- * of characters would be in the opposite direction.
- * e.g. "HelloشقشلاهؤEnglish"
- * | |
- * * +
- * [*] - Primary actual position for cursor i.e. continuing writing LTR (English)
- * [+] - Alternate actual position for cursor i.e. writing RTL (Arabic)
- *
- * @param[in] characterPosition the logical (input) position in the 'string' of characters.
- * @param[out] directionRTL Whether the actual x,y,z position is after LTR (false) or RTL (true) text.
- * @param[out] alternatePosition the actual x,y,z position of the cursor if user types
- * in alternate direction to current flow of text.
- * @param[out] alternatePositionValid whether this alternate position is valid.
- * @return Vector3 the actual x,y,z position
- */
- Vector3 GetActualPositionFromCharacterPosition(std::size_t characterPosition, bool& directionRTL, Vector3& alternatePosition, bool& alternatePositionValid ) const;
-
- /**
- * Retrieve the character position of the first character on the row of text
- * that this character resides on.
- * @param[in] logicalPosition the position in the 'string' of characters.
- * @return logical character position of start of row.
- */
- std::size_t GetRowStartFromCharacterPosition(std::size_t logicalPosition) const;
-
- /**
- * Retrieves the first character of a group of characters with the same direction.
- *
- * @param[in] logicalPosition Index to a character.
- *
- * @return Index to the character.
- */
- std::size_t GetFirstCharacterWithSameDirection( std::size_t logicalPosition ) const;
-
- /**
- * Retrieve the dimensions of this row of text that the character resides on.
- * @param[in] characterPosition the position in the 'string' of characters.
- * @return The size of the rectangle representing this row
- */
- Size GetRowRectFromCharacterPosition(std::size_t characterPosition) const;
-
- /**
- * Retrieve the dimensions (and min-max) of this row of text that the character resides on.
- * @param[in] characterPosition the position in the 'string' of characters.
- * @param[out] min the top-left position of the rectangle representing this row
- * @param[out] max the bottom-right position of the rectangle representing this row
- * @return The size of the rectangle representing this row (max - min)
- */
- Size GetRowRectFromCharacterPosition(std::size_t characterPosition, Vector2& min, Vector2& max) const;
-
- /**
- * Checks if the provided touchedActor was this text-input
- * @param[in] touchedActor the touched actor that will be checked against this text-input
- * @return true if the touchActor was the text-input or one of its children
- */
- bool WasTouchedCheck( const Actor& touchedActor ) const;
-
- /**
- * Connect to the stage touch event
- */
- void StartMonitoringStageForTouch();
-
- /**
- * Disconnect from the stage touch event
- */
- void EndMonitoringStageForTouch();
-
- /**
- * Callback for when the screen is touched, this will be connected when selection starts and disconnected when it ends.
- * @param[in] event The touch event
- */
- void OnStageTouched(const TouchEvent& event);
-
-
- /**
- * Select the text between the given values
- * @param[in] start position within array to start selection
- * @param[in] end position within array to end selection
- */
- void SelectText(std::size_t start, std::size_t end);
-
- /**
- * Gets selected text and returns it as a StyleText vector
- * @return StyledText vector that is selected.
- */
- MarkupProcessor::StyledTextArray GetSelectedText();
-
- /**
- * Applies the given style to all text, selected or not selected.
- * By default all style settings are applied but a bit mask could be used to modify only certain style settings.
- */
- void ApplyStyleToRange(const TextStyle& style, const TextStyle::Mask mask, const std::size_t begin, const std::size_t end);
-
- /**
- * Callback for when the keyboard status changes
- * @param[in] keyboardShown Whether the keyboard has just been shown or not.
- */
- void KeyboardStatusChanged(bool keyboardShown);
-
- /**
- * Hide highlight shown between selection handles.
- * @param[in] hidePopup flag to hide the popup too, default is to hide popup.
- */
- void RemoveHighlight( bool hidePopup = true );
-
- /**
- * Highlights text that has been selected
- */
- void CreateHighlight();
-
- /**
- * Copies selected text to clipboard
- * @return bool true if copy was successful.
- */
- bool CopySelectedTextToClipboard();
-
- /**
- * Pastes the given text to currently displayed string at the current cursor position
- * @param[in] text Text to be pasted
- */
- void PasteText( const Text& text );
-
- /**
- * Sets the direction of the text if it is empty.
- */
- void SetTextDirection();
-
- /**
- * Updates the line height accordingly with the current text input style.
- */
- void UpdateLineHeight();
-
- /**
- * Finds a visible character.
- *
- * The \e direction parameters specifies from where to start to look for a visible character. \e Left means start by characters in lower
- * positions than \e cursorPosition, \e Right means start by characters in greater positions than \e cursorPosition and \e ByEnd starts
- * by the last characters.
- *
- * If \e Left or \e Right is provided and any character is found, then looks in the other direction.
- *
- * @param[in] direction Direction used to find a visible character.
- * @param[in] cursorPosition Starting position.
- *
- * @return The found visible character.
- */
- std::size_t FindVisibleCharacter( const FindVisibleCharacterDirection direction , const std::size_t cursorPosition ) const;
-
- /**
- * @copydoc SetSortModifier()
- */
- void SetSortModifier( float depthOffset );
-
- /**
- * @copydoc SetSnapshotModeEnabled()
- */
- void SetSnapshotModeEnabled( bool enable );
-
- /**
- * @copydoc IsSnapshotModeEnabled()
- */
- bool IsSnapshotModeEnabled() const;
-
- /**
- * @copydoc SetScrollEnabled()
- */
- void SetScrollEnabled( bool enable );
-
- /**
- * @copydoc IsScrollEnabled()
- */
- bool IsScrollEnabled() const;
-
- /**
- * @copydoc SetScrollPosition()
- */
- void SetScrollPosition( const Vector2& position );
-
- /**
- * @copydoc GetScrollPosition()
- */
- Vector2 GetScrollPosition() const;
-
- /**
- * @brief Sets whether markup processing should be carried out.
- *
- * @param[in] enable whether markup processing is carried out or not.
- */
- void SetMarkupProcessingEnabled( bool enable );
-
- /**
- * @brief Returns whether markup processing is enabled or not
- *
- * @return true is markup processing is enabled
- */
- bool IsMarkupProcessingEnabled() const;
-
- /**
- * Insert or replaces the given text in the given position. It checks if the text exceeds the maximum allowed number of characters
- * and if it fits in the text-input's boundaries.
- *
- * @param[in] text Text to be inserted.
- * @param[in] position Position where the text is inserted.
- * @param[in] numberOfCharactersToReplace The number of characters to replace.
- * @param[out] textExceedsMaximunNumberOfCharacters The number of characters that have been inserted.
- * @param[out] textExceedsBoundary Whether the inserted text has exceeded the boundaries of the text-input.
- *
- * @return The number of characters that have been inserted.
- */
- std::size_t DoInsertAt( const Text& text, std::size_t position, std::size_t numberOfCharactersToReplace, bool& textExceedsMaximunNumberOfCharacters, bool& textExceedsBoundary );
-
- /**
- * Retrieve Text-view's layout info.
- */
- void GetTextLayoutInfo();
-
- /**
- * Set the offset for positioning Popup from the TextInput
- * @param[in] offset in the order, left, top, right, bottom
- */
- void SetOffsetFromText( const Vector4& offset );
-
- /**
- * Get the offset of the Popup from the TextInput
- * @return Vector4 with the offset in the order, left, top, right, bottom
- */
- const Vector4& GetOffsetFromText() const;
-
- /**
- * Show the Placeholder text with an already created StyleTextArray
- * @param[in] stylePlaceHolderText Required placeholder text to be used
- */
- void ShowPlaceholderText( const MarkupProcessor::StyledTextArray& stylePlaceHolderText );
-
- // Properties
-
- /**
- * Called when a property of an object of this type is set.
- * @param[in] object The object whose property is set.
- * @param[in] index The property index.
- * @param[in] value The new property value.
- */
- static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
-
- /**
- * Called to retrieve a property of an object of this type.
- * @param[in] object The object whose property is to be retrieved.
- * @param[in] index The property index.
- * @return The current value of the property.
- */
- static Property::Value GetProperty( BaseObject* object, Property::Index propertyIndex );
-
- /**
- * Emits the style changed signal.
- */
- void EmitStyleChangedSignal();
-
- /**
- * Emit signal when text is modified.
- */
- void EmitTextModified();
-
- /**
- * Emits max input characters reached signal.
- */
- void EmitMaxInputCharactersReachedSignal();
-
- /**
- * Emits a signal when the input text exceeds the boundaries of the text-input.
- */
- void EmitInputTextExceedsBoundariesSignal();
-
-private:
-
- State mState; ///< Current State of Text input.
- MarkupProcessor::StyledTextArray mStyledText; ///< String currently displayed by TextView with style info.
- TextStyle mInputStyle; ///< Stores the current input style.
- float mLineHeight; ///< Stores the current line height accordingly with the input style.
- Toolkit::TextView mDisplayedTextView; ///< Actor which actually display text
-
- MarkupProcessor::StyledTextArray mStyledPlaceHolderText; ///< Text used as place holder with style info.
-
- std::size_t mMaxStringLength; ///< Max number of characters for string
- std::size_t mNumberOflinesLimit; ///< Limit on the number of lines this TextInput will display.
-
- ImageActor mCursor; ///< Cursor overlayed on Text to show where new text will be inserted
- ImageActor mCursorRTL; ///< Right To Left Cursor overlayed on Text (where new RTL text would be inserted)
- Animation mCursorAnimation; ///< animator for cursor blinking.
- std::size_t mCursorPosition; ///< position along string cursor is at.
- Timer mCursorBlinkTimer; ///< Timer to signal cursor to blink
-
- Layer mActiveLayer; ///< Layer for active handles and alike that ensures they are above all else.
-
- Image mGrabHandleImage; ///< image to be used for grab handle
- ImageActor mGrabHandle; ///< Handle used to move cursor for editing
-
- Actor mGrabArea; ///< invisible actor that receives pans events for the grab handle.
- PanGestureDetector mPanGestureDetector; ///< Pan gesture for handles
- TapGestureDetector mTapDetector; ///< used to start editing
- TapGestureDetector mDoubleTapDetector; ///< double tap detector
-
- Vector3 mActualGrabHandlePosition; ///< actual position of grab handle, this might not be snapped to a character
-
- LongPressGestureDetector mLongPressDetector; ///< Gesture to start selection
-
- /*Selection handles*/
- Image mSelectionHandleOneImage; ///< image used for selection handle one
- Image mSelectionHandleOneImagePressed; ///< image used for selection handle one pressed state
- Image mSelectionHandleTwoImage; ///< image used for selection handle two
- Image mSelectionHandleTwoImagePressed; ///< image used for selection handle two pressed state
-
- bool mIsSelectionHandleOneFlipped:1; ///< Flag to know whether the handle one is flipped or not.
- bool mIsSelectionHandleTwoFlipped:1; ///< Flag to know whether the handle two is flipped or not.
- Vector3 mSelectionHandleOneOffset; ///< Handle One's Offset
- Vector3 mSelectionHandleTwoOffset; ///< Handle Two's Offset
- Vector3 mSelectionHandleOneActualPosition; ///< Actual x y position of handle
- Vector3 mSelectionHandleTwoActualPosition; ///< Actual x y position of handle
- std::size_t mSelectionHandleOnePosition; ///< Position of handle along the string of text
- std::size_t mSelectionHandleTwoPosition; ///< Position of handle along the string of text
- ImageActor mSelectionHandleOne; ///< First selection handle used for selecting text to cut&paste
- ImageActor mSelectionHandleTwo; ///< Second selection handle used for selecting text to cut&paste
- Actor mHandleOneGrabArea; ///< invisible actor that receives pans events for the selection handle.
- Actor mHandleTwoGrabArea; ///< invisible actor that receives pans events for the selection handle.
-
- Mesh mHighlightMesh; ///< Mesh Data for highlight
- MeshActor mHighlightMeshActor; ///< Mesh Actor to display highlight
- MeshData mMeshData; ///< Container to hold meshData for highlight
- Material mCustomMaterial; ///< Custom material used for highlight
- HighlightInfo mNewHighlightInfo; ///< Geometry info to create highlight.
-
- Text mPreEditString; ///< Holds current input string prior to it being committed.
- std::size_t mPreEditStartPosition; ///< Cursor position for start of pre-edit string
- std::size_t mPreEditLength; ///< Cursor position for length of current pre-edit string after purging characters that do not fit.
- std::size_t mNumberOfSurroundingCharactersDeleted; ///< Stores the number of surrounding characters deleted.
- unsigned long mTouchStartTime; ///< Touch Start time (time in ms when down press began)
-
- Toolkit::TextView::TextLayoutInfo mTextLayoutInfo; ///< It contains a table layout info per character sorted by the character's visual index (retrieved from TextView),
- ///< a reorder map that stores each character's visual (output) index according to its logical (input) index,
- ///< a reorder map that stores each character's logical (input) index according to its visual (output) index,
- ///< the text size after layout and the scroll offset.
-
- MarkupProcessor::StyledTextArray mCurrentCopySelecton; ///< Array to store copied text.
- TextInputPopup mPopupPanel; ///< Panel to house cut and paste, select all buttons.
-
- Timer mScrollTimer;
- Vector2 mScrollDisplacement;
- Vector3 mCurrentHandlePosition;
- SelectionHandleId mCurrentSelectionId;
- Vector3 mCurrentSelectionHandlePosition;
- SelectionParameters mRequestedSelection;
- Vector4 mSelectionHandleFlipMargin;
- Vector4 mBoundingRectangleWorldCoordinates;
-
- Clipboard mClipboard; ///< Handle to clipboard
-
- // Styling
- Vector4 mMaterialColor; // Color of the highlight
- Vector4 mPopupOffsetFromText; // Offset of Popup from the TextInput.
-
- bool mOverrideAutomaticAlignment:1; ///< Whether to override the alignment automatically set by the text content (e.g. european LTR or arabic RTL)
- bool mCursorRTLEnabled:1; ///< Enable state of Alternate RTL Cursor (need to keep track of this as it's not always enabled)
- bool mClosestCursorPositionEOL:1; ///< closest cursor position is end of line.
- bool mCursorBlinkStatus:1; ///< \e true shows the cursor, \e false hiddes it.
-
- bool mCursorVisibility:1; ///< Visibility status of Cursor
- bool mGrabHandleVisibility:1; ///< Visibility status of the grab handle.
-
- bool mIsCursorInScrollArea:1; ///< Whether the cursor is inside the boundaries of the text-input.
- bool mIsGrabHandleInScrollArea:1; ///< Whether the grab handle is inside the boundaries of the text-input.
-
- bool mEditModeActive:1; ///< true to indicate TextInput is in edit mode.
- bool mEditOnTouch:1; ///< true indicates edit mode starts by touching/tapping the TextInput
- bool mTextSelection:1; ///< true indicates text selection is enabled.
- bool mExceedEnabled:1; ///< Whether text-input editing text beyond its boundary is enabled or not. By default is enabled.
- bool mGrabHandleEnabled:1; ///< Flag to enable the grab handle instead of the default magnifier.
- bool mIsSelectionHandleFlipEnabled:1; ///< Flag to enable the selection handle flip
-
- bool mPreEditFlag:1; ///< Flag to indicate if key string received is still in pre-edit mode (Ecore IMF keyboard)
- bool mIgnoreCommitFlag:1; ///< Flag to indicate if the commit string should be ignored, maybe due to a keyboard reset.
- bool mIgnoreFirstCommitFlag:1; ///< Whether to ignore the first commit.
- bool mSelectingText:1; ///< Ignore surrounding text as selecting text
-
- bool mPreserveCursorPosition:1; ///< Indicates that the commit message is from a reset and does not require the cursor to be moved
-
- bool mSelectTextOnCommit:1;
-
- bool mUnderlinedPriorToPreEdit:1; ///< As predictive text adds underline style this flag enables us to revert back or keep underline.
-
- bool mCommitByKeyInput:1; ///< Set if a commit is done by key input rather than automatically (usually when a space bar or enter is pressed).
-
- bool mPlaceHolderSet:1; ///< Whether the place holder text is set.
- bool mMarkUpEnabled:1; ///< enable to scan for mark-up
-
- Toolkit::TextInput::InputSignalType mInputStartedSignal; ///< Signal emitted when input starts
- Toolkit::TextInput::InputSignalType mInputFinishedSignal; ///< Signal emitted when input ends
- Toolkit::TextInput::StyleChangedSignalType mStyleChangedSignal; ///< Signal emitted when style changes.
- Toolkit::TextInput::TextModifiedSignalType mTextModifiedSignal; ///< Signal emitted when text modified.
- Toolkit::TextInput::MaxInputCharactersReachedSignalType mMaxInputCharactersReachedSignal; ///< Signal emitted when max input characters is reached.
- Toolkit::TextInput::InputSignalType mCutAndPasteToolBarDisplayed; ///< Signal emitted when toolbar displayed
- Toolkit::TextInput::InputTextExceedBoundariesSignalType mInputTextExceedBoundariesSignal; ///< Signal emitted when input text exceeds the boundaries of the text-input.
-};
-
-} // namespace Internal
-
-// Helpers for public-api forwarding methods
-
-inline Toolkit::Internal::TextInput& GetImpl(Toolkit::TextInput& textInput)
-{
- DALI_ASSERT_ALWAYS(textInput);
-
- Dali::RefObject& handle = textInput.GetImplementation();
-
- return static_cast<Toolkit::Internal::TextInput&>(handle);
-}
-
-inline const Toolkit::Internal::TextInput& GetImpl(const Toolkit::TextInput& textInput)
-{
- DALI_ASSERT_ALWAYS(textInput);
-
- const Dali::RefObject& handle = textInput.GetImplementation();
-
- return static_cast<const Toolkit::Internal::TextInput&>(handle);
-}
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <libintl.h>
-#include <dali/public-api/animation/constraints.h>
-#include <dali/public-api/images/resource-image.h>
-#include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-input/text-input-popup-impl.h>
-#include <dali-toolkit/public-api/controls/buttons/push-button.h>
-#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
-
-using namespace Dali;
-
-#define GET_LOCALE_TEXT(string) dgettext("sys_string", string)
-
-namespace
-{
-const Vector2 DEFAULT_POPUP_INDICATOR_OFFSET(0.0f, 60.0f);
-
-// 1. For selection: should be above top of highlighted selection, or below bottom of highlighted selection + end handle.
-// 2. For cursor: should be above top of cursor, or below bottom of cursor + grab handle.
-
-/**
- * Image resource paths
- */
-const std::string POPUP_BACKGROUND( DALI_IMAGE_DIR "popup_bubble_bg.#.png" );
-const std::string POPUP_BACKGROUND_EFFECT( DALI_IMAGE_DIR "popup_bubble_bg_ef.#.png" );
-const std::string POPUP_BACKGROUND_LINE( DALI_IMAGE_DIR "popup_bubble_bg_line.#.png" );
-
-const std::string POPUP_TAIL_BOTTOM( DALI_IMAGE_DIR "popup_bubble_tail_bottom.png" );
-const std::string POPUP_TAIL_BOTTOM_EFFECT( DALI_IMAGE_DIR "popup_bubble_tail_bottom_ef.png" );
-const std::string POPUP_TAIL_BOTTOM_LINE( DALI_IMAGE_DIR "popup_bubble_tail_bottom_line.png" );
-const std::string POPUP_TAIL_TOP( DALI_IMAGE_DIR "popup_bubble_tail_top.png" );
-const std::string POPUP_TAIL_TOP_EFFECT( DALI_IMAGE_DIR "popup_bubble_tail_top_ef.png" );
-const std::string POPUP_TAIL_TOP_LINE( DALI_IMAGE_DIR "popup_bubble_tail_top_line.png" );
-
-const std::string OPTION_ICON_CLIPBOARD( DALI_IMAGE_DIR "copy_paste_icon_clipboard.png" );
-const std::string OPTION_ICON_COPY( DALI_IMAGE_DIR "copy_paste_icon_copy.png" );
-const std::string OPTION_ICON_CUT( DALI_IMAGE_DIR "copy_paste_icon_cut.png" );
-const std::string OPTION_ICON_PASTE( DALI_IMAGE_DIR "copy_paste_icon_paste.png" );
-const std::string OPTION_ICON_SELECT( DALI_IMAGE_DIR "copy_paste_icon_select.png" );
-const std::string OPTION_ICON_SELECT_ALL( DALI_IMAGE_DIR "copy_paste_icon_select_all.png" );
-
-/**
- * Constant values for building the GUI
- */
-const Vector4 POPUP_MARGIN( 14.0f, 14.0f, 14.0f, 14.0f ); ///< Margin around the popup visible background Image.
-const Vector4 POPUP_BORDER( 2.0f, 2.0f, 2.0f, 2.0f ); ///< The Border of the popup.
-const Vector2 POPUP_MIN_SIZE( 0.0f, 126.0f ); ///< The minimum size of the popup.
-const Vector2 POPUP_MAX_SIZE( 720.0f, 126.0f ); ///< The maximum size of the popup.
-const float POPUP_TAIL_Y_OFFSET( -2.25f ); ///< The y offset of the tail.
-const Vector2 POPUP_TAIL_SIZE( 36.0f, 36.0f ); ///< The size of the tail.
-const Vector2 POPUP_DIVIDER_SIZE( 1.0f, 126.0f ); ///< The size of the divider.
-
-const Vector4 OPTION_PADDING( 16.0f, 16.0f, 24.0f, 19.0f ); ///< The padding within the option to position icon and text away from the border. The order is left, right, top and bottom
-const Vector2 OPTION_MAX_SIZE( 220.0f, 126.0f ); ///< The maximum size of the option.
-const Vector2 OPTION_MIN_SIZE( 128.0f, 126.0f ); ///< The minimum size of the option.
-const Vector2 OPTION_ICON_SIZE( 45.0f, 45.0f ); ///< The size of the icon.
-const Vector2 OPTION_TEXT_MIN_SIZE( 128.0f, 30.0f ); ///< The minimum size of the text.
-const float OPTION_GAP_ICON_TEXT( 8.0f ); ///< The gap between the icon and the text
-
-const float HIDE_POPUP_ANIMATION_DURATION( 0.2f ); ///< Duration of popup hide animation in seconds.
-const float SHOW_POPUP_ANIMATION_DURATION( 0.2f ); ///< Duration of popup show animation in seconds.
-
-/**
- * Default Colors
- */
-const Vector4 DEFAULT_POPUP_BACKGROUND( Vector4( .20f, 0.29f, 0.44f, 1.0f ) );
-const Vector4 DEFAULT_POPUP_BACKGROUND_PRESSED( Vector4( 0.07f, 0.10f, 0.17f, 1.0f ) );
-const Vector4 DEFAULT_POPUP_LINE_COLOR( Vector4( 0.36f, 0.45f, 0.59f, 1.0f ) );
-const Vector4 DEFAULT_OPTION_ICON( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
-const Vector4 DEFAULT_OPTION_ICON_PRESSED( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
-const Vector4 DEFAULT_OPTION_TEXT( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
-const Vector4 DEFAULT_OPTION_TEXT_PRESSED( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
-
-} // unnamed namespace
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace
-{
-
-// Signals
-
-const char* const SIGNAL_PRESSED = "pressed";
-const char* const SIGNAL_HIDE_FINISHED = "hide-finished";
-const char* const SIGNAL_SHOW_FINISHED = "show-finished";
-
-}
-
-const char* const TextInputPopup::OPTION_SELECT_WORD = "option-select_word"; // "Select Word" popup option.
-const char* const TextInputPopup::OPTION_SELECT_ALL("option-select_all"); // "Select All" popup option.
-const char* const TextInputPopup::OPTION_CUT("option-cut"); // "Cut" popup option.
-const char* const TextInputPopup::OPTION_COPY("option-copy"); // "Copy" popup option.
-const char* const TextInputPopup::OPTION_PASTE("option-paste"); // "Paste" popup option.
-const char* const TextInputPopup::OPTION_CLIPBOARD("option-clipboard"); // "Clipboard" popup option.
-
-TextInputPopup::TextInputPopup()
-: mState(StateHidden),
- mRoot( Layer::New() ),
- mButtons(),
- mVisiblePopUpSize(),
- mPopupTailXPosition( 0.0f ),
- mContentSize(),
- mBackgroundColor( DEFAULT_POPUP_BACKGROUND ),
- mBackgroundPressedColor( DEFAULT_POPUP_BACKGROUND_PRESSED ),
- mLineColor( DEFAULT_POPUP_LINE_COLOR ),
- mIconColor( DEFAULT_OPTION_ICON ),
- mIconPressedColor( DEFAULT_OPTION_ICON_PRESSED ),
- mTextColor( DEFAULT_OPTION_TEXT ),
- mTextPressedColor( DEFAULT_OPTION_TEXT_PRESSED ),
- mSelectOptionPriority(1),
- mSelectAllOptionPriority(2),
- mCutOptionPriority(3),
- mCopyOptionPriority(4),
- mPasteOptionPriority(5),
- mClipboardOptionPriority(6),
- mPressedSignal(),
- mHideFinishedSignal(),
- mShowFinishedSignal()
-{
- mRoot.SetParentOrigin( ParentOrigin::TOP_LEFT );
- mRoot.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
-}
-
-void TextInputPopup::AddToParent( Actor parent )
-{
- Actor existingParent = mRoot.GetParent();
-
- if ( !existingParent )
- {
- parent.Add( mRoot );
- }
-}
-
-void TextInputPopup::RemoveFromParent()
-{
- Actor parent = mRoot.GetParent();
-
- if ( parent )
- {
- parent.Remove( mRoot );
- }
-}
-
-void TextInputPopup::CreateLayer( const Vector2& size )
-{
- mLayer = Layer::New();
- mLayer.SetParentOrigin(ParentOrigin::CENTER);
- mLayer.SetAnchorPoint(AnchorPoint::CENTER);
- mLayer.SetSize( size ); // matches stencil size
- mLayer.SetName("popup-mLayer");
-}
-
-void TextInputPopup::CreateStencil( const Vector2& size )
-{
- mStencil = CreateSolidColorActor( Color::BLUE );
- mStencil.SetParentOrigin( ParentOrigin::CENTER );
- mStencil.SetAnchorPoint( AnchorPoint::CENTER );
- mStencil.SetDrawMode( DrawMode::STENCIL );
- mStencil.SetVisible( true );
- mStencil.SetName( "popup-stencil" );
- mStencil.SetSize( size );
-}
-
-void TextInputPopup::OnScrollStarted( const Vector3& position )
-{
- mButtons.SetSensitive( false );
-}
-
-void TextInputPopup::OnScrollCompleted( const Vector3& position )
-{
- mButtons.SetSensitive( true );
-}
-
-void TextInputPopup::CreateScrollView()
-{
- mScrollView = Toolkit::ScrollView::New();
- mScrollView.SetName("popup-scroll-view");
- mScrollView.SetAnchorPoint( AnchorPoint::CENTER );
- mScrollView.SetParentOrigin( ParentOrigin::CENTER );
- mScrollView.SetScrollingDirection( PanGestureDetector::DIRECTION_HORIZONTAL, Degree( 40.0f ) );
- mScrollView.SetAxisAutoLock( true );
- mScrollView.ScrollStartedSignal().Connect( this, &TextInputPopup::OnScrollStarted );
- mScrollView.ScrollCompletedSignal().Connect( this, &TextInputPopup::OnScrollCompleted );
-}
-
-void TextInputPopup::UpdateScrollViewRulerAndSize( const Vector2& visibleSize )
-{
- mScrollView.SetSize( visibleSize.x, visibleSize.y );
-
- RulerPtr rulerX = new DefaultRuler(); // IntrusivePtr which is unreferenced when ScrollView is destroyed.
- RulerPtr rulerY = new DefaultRuler(); // IntrusivePtr which is unreferenced when ScrollView is destroyed.
- rulerY->Disable();
- rulerX->SetDomain( RulerDomain( 0, mContentSize.width, true ) );
- mScrollView.SetRulerX(rulerX);
- mScrollView.SetRulerY(rulerY);
-}
-
-
-void TextInputPopup::Clear()
-{
- if ( mBackground )
- {
- UnparentAndReset( mTail );
- UnparentAndReset( mStencil );
- UnparentAndReset( mBackground );
- UnparentAndReset( mButtons );
- UnparentAndReset( mScrollView );
- mDividerContainer.clear();
- RemoveFromParent();
- mState = StateHidden;
- }
-}
-
-ImageActor TextInputPopup::CreateOptionIcon( Image iconImage, const Vector4& color )
-{
- ImageActor icon = ImageActor::New( iconImage );
- icon.SetSize( OPTION_ICON_SIZE );
- icon.SetParentOrigin( ParentOrigin::TOP_CENTER );
- icon.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- icon.SetColor( color );
- icon.SetY( OPTION_PADDING.z - POPUP_BORDER.y );
- return icon;
-}
-
-Toolkit::TextView TextInputPopup::CreateOptionCaption( const std::string& caption, const Vector4& color )
-{
- TextStyle style;
- style.SetTextColor( color );
-
- PointSize pointSize( Font::PixelsToPoints( OPTION_TEXT_MIN_SIZE.y ) );
- style.SetFontPointSize( pointSize );
-
- MarkupProcessor::StyledTextArray styledCaption;
- styledCaption.push_back( MarkupProcessor::StyledText( Text( caption ), style ) );
-
- Toolkit::TextView textView = Toolkit::TextView::New( styledCaption );
- textView.SetSizePolicy( Toolkit::Control::Fixed, Toolkit::Control::Fixed );
- textView.SetWidthExceedPolicy( Toolkit::TextView::EllipsizeEnd );
- textView.SetHeightExceedPolicy( Toolkit::TextView::EllipsizeEnd );
- textView.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
- textView.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
- textView.SetY( -OPTION_PADDING.w + POPUP_BORDER.w );
-
- MarkupProcessor::StyledTextArray styledCaptionEllipsize;
- MarkupProcessor::SetTextStyle( Text("..."), styledCaptionEllipsize, style );
- textView.SetEllipsizeText( styledCaptionEllipsize );
-
- const float textWidth = textView.GetWidthForHeight( OPTION_TEXT_MIN_SIZE.y );
- textView.SetSize( textWidth, OPTION_TEXT_MIN_SIZE.y );
-
- return textView;
-}
-
-void TextInputPopup::CreateBackground()
-{
- // Create background-panel if not already created (required if we have at least one option)
- if ( !mBackground )
- {
- Image bgImg = ResourceImage::New( POPUP_BACKGROUND );
- mBackground = ImageActor::New( bgImg );
- mBackground.SetAnchorPoint( AnchorPoint::CENTER );
- mBackground.SetParentOrigin( ParentOrigin::CENTER );
- mBackground.SetName( "text-input-popup-background" );
- mBackground.SetColor( mBackgroundColor );
-
- Image bgEffectImg = ResourceImage::New( POPUP_BACKGROUND_EFFECT );
- mBackgroundEffect = ImageActor::New( bgEffectImg );
- mBackgroundEffect.SetAnchorPoint( AnchorPoint::CENTER );
- mBackgroundEffect.SetParentOrigin( ParentOrigin::CENTER );
- mBackgroundEffect.SetName( "text-input-popup-background-effect" );
- mBackgroundEffect.SetSizeMode( SIZE_EQUAL_TO_PARENT );
- mBackgroundEffect.SetZ( 1.0f );
- mBackground.Add( mBackgroundEffect );
-
- Image bgLine = ResourceImage::New( POPUP_BACKGROUND_LINE );
- mBackgroundLine = ImageActor::New( bgLine );
- mBackgroundLine.SetAnchorPoint( AnchorPoint::CENTER);
- mBackgroundLine.SetParentOrigin( ParentOrigin::CENTER );
- mBackgroundLine.SetName( "text-input-popup-background-effect" );
- mBackgroundLine.SetSizeMode( SIZE_EQUAL_TO_PARENT );
- mBackgroundLine.SetColor( mLineColor );
- mBackgroundLine.SetZ( 0.1f );
- mBackgroundEffect.Add( mBackgroundLine );
-
- Hide(false);
- }
-}
-
-void TextInputPopup::CreateTail()
-{
- if ( !mTail )
- {
- Image tail = ResourceImage::New( POPUP_TAIL_BOTTOM );
- mTail = ImageActor::New( tail );
- mTail.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
- mTail.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- mTail.SetName( "text-input-popup-tail" );
- mTail.SetPosition( 0.0f, POPUP_TAIL_Y_OFFSET - POPUP_BORDER.w, 1.2f );
- mTail.SetColor( mBackgroundColor );
-
- Image tailEffect = ResourceImage::New( POPUP_TAIL_BOTTOM_EFFECT );
- mTailEffect = ImageActor::New( tailEffect );
- mTailEffect.SetParentOrigin( ParentOrigin::CENTER );
- mTailEffect.SetAnchorPoint( AnchorPoint::CENTER );
- mTailEffect.SetName( "text-input-popup-tail-effect" );
- mTailEffect.SetSizeMode( SIZE_EQUAL_TO_PARENT );
- mTailEffect.SetZ( 0.1f );
- mTail.Add( mTailEffect );
-
- Image tailLine = ResourceImage::New( POPUP_TAIL_BOTTOM_LINE );
- mTailLine = ImageActor::New( tailLine );
- mTailLine.SetParentOrigin( ParentOrigin::CENTER );
- mTailLine.SetAnchorPoint( AnchorPoint::CENTER );
- mTailLine.SetSizeMode( SIZE_EQUAL_TO_PARENT );
- mTailLine.SetName( "text-input-popup-tail-line" );
- mTailLine.SetColor( mLineColor );
- mTailLine.SetZ( 0.1f );
- mTailEffect.Add( mTailLine );
- }
-}
-
-ImageActor TextInputPopup::CreateDivider()
-{
- ImageActor divider = Toolkit::CreateSolidColorActor( mLineColor );
- divider.SetParentOrigin( ParentOrigin::TOP_LEFT );
- divider.SetAnchorPoint( AnchorPoint::TOP_LEFT );
- divider.SetSize( POPUP_DIVIDER_SIZE.width , mContentSize.height );
- divider.SetPosition( mContentSize.width - POPUP_DIVIDER_SIZE.width, 0.0f );
-
- // Keep track of all the dividers. As their height's need to be updated to the max of all
- // buttons currently added.
- mDividerContainer.push_back( divider );
-
- return divider;
-}
-
-ImageActor TextInputPopup::CreatePressedBackground( const Vector2& requiredSize )
-{
- ImageActor pressedBg = Toolkit::CreateSolidColorActor( mBackgroundPressedColor );
- pressedBg.SetDrawMode( DrawMode::OVERLAY );
- pressedBg.SetParentOrigin( ParentOrigin::CENTER );
- pressedBg.SetAnchorPoint( AnchorPoint::CENTER );
- pressedBg.SetSize( requiredSize );
- return pressedBg;
-}
-
-TextInputPopup::ButtonRequirement TextInputPopup::CreateRequiredButton( TextInputPopup::Buttons buttonId, std::size_t orderOfPriority,
- const std::string& name, const std::string& caption, Image iconImage, bool enabled )
-{
- TextInputPopup::ButtonRequirement currentButton;
- currentButton.buttonId = buttonId;
- currentButton.orderOfPriority = orderOfPriority;
- currentButton.name = name;
- currentButton.caption = caption;
- currentButton.iconImage = iconImage;
- currentButton.enabled = enabled;
-
- return currentButton;
-}
-
-void TextInputPopup::CreateOrderedListOfOptions()
-{
- mOrderListOfButtons.clear();
-
- for ( std::size_t index= 0; index < ButtonsEnumEnd; index++ )
- {
- TextInputPopup::ButtonRequirement currentButton;
-
- // Create button for each possible option using Option priority
- switch ( index )
- {
- case ButtonsCut:
- {
- Image cutIcon = ResourceImage::New( OPTION_ICON_CUT );
- currentButton = CreateRequiredButton( ButtonsCut, mCutOptionPriority, OPTION_CUT, GET_LOCALE_TEXT("IDS_COM_BODY_CUT"), cutIcon, false );
- break;
- }
- case ButtonsCopy:
- {
- Image copyIcon = ResourceImage::New( OPTION_ICON_COPY );
- currentButton = CreateRequiredButton( ButtonsCopy, mCopyOptionPriority, OPTION_COPY, GET_LOCALE_TEXT("IDS_COM_BODY_COPY"), copyIcon, false );
- break;
- }
- case ButtonsPaste:
- {
- Image pasteIcon = ResourceImage::New( OPTION_ICON_PASTE );
- currentButton = CreateRequiredButton( ButtonsPaste, mPasteOptionPriority, OPTION_PASTE, GET_LOCALE_TEXT("IDS_COM_BODY_PASTE"), pasteIcon, false );
- break;
- }
- case ButtonsSelect:
- {
- Image selectIcon = ResourceImage::New( OPTION_ICON_SELECT );
- currentButton = CreateRequiredButton( ButtonsSelect, mSelectOptionPriority, OPTION_SELECT_WORD, GET_LOCALE_TEXT("IDS_COM_SK_SELECT"), selectIcon, false );
- break;
- }
- case ButtonsSelectAll:
- {
- Image selectAllIcon = ResourceImage::New( OPTION_ICON_SELECT_ALL );
- currentButton = CreateRequiredButton( ButtonsSelectAll, mSelectAllOptionPriority, OPTION_SELECT_ALL, GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL"), selectAllIcon, false );
- break;
- }
- case ButtonsClipboard:
- {
- Image clipboardIcon = ResourceImage::New( OPTION_ICON_CLIPBOARD );
- currentButton = CreateRequiredButton( ButtonsClipboard, mClipboardOptionPriority, OPTION_CLIPBOARD, GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD"), clipboardIcon, false );
- break;
- }
- }
-
- bool match = false;
-
- // Insert button in list of buttons in order of priority setting.
- for( std::vector<ButtonRequirement>::iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt && !match ); ++it )
- {
- const ButtonRequirement& button( *it );
- if ( currentButton.orderOfPriority < button.orderOfPriority )
- {
- if ( currentButton.orderOfPriority != 0 ) // If order priority 0 then do not add button as not required.
- {
- mOrderListOfButtons.insert( it, currentButton );
- }
- match = true;
- }
- }
-
- if ( !match )
- {
- mOrderListOfButtons.push_back( currentButton );
- }
- }
-}
-
-Vector2 TextInputPopup::GetConstrainedTextSize( const Vector2& textSize )
-{
- return Vector2( std::min( textSize.width, OPTION_MAX_SIZE.width - OPTION_PADDING.x - OPTION_PADDING.y ), textSize.height );
-}
-
-void TextInputPopup::AddOption(const std::string& name, const std::string& caption, const Image iconImage, bool finalOption)
-{
- // 1. Create container for text and icon when not pressed.
- Actor optionContainer = Actor::New();
- optionContainer.SetParentOrigin( ParentOrigin::TOP_LEFT );
- optionContainer.SetAnchorPoint( AnchorPoint::TOP_LEFT );
-
- // 2. Add text.
- Toolkit::TextView captionTextView = CreateOptionCaption( caption, mTextColor );
- optionContainer.Add( captionTextView );
-
- // 3. Add icon.
- ImageActor icon = CreateOptionIcon( iconImage, mIconColor );
- optionContainer.Add( icon );
-
- // 4. Calculate the size of option.
- const Vector2 textSize = Vector2( captionTextView.GetNaturalSize() );
- captionTextView.SetSize( GetConstrainedTextSize( textSize ) );
-
-
- const Vector2 optionSize( std::max( textSize.x, OPTION_ICON_SIZE.x ) + OPTION_PADDING.x + OPTION_PADDING.z,
- OPTION_PADDING.z + OPTION_ICON_SIZE.y + OPTION_GAP_ICON_TEXT + textSize.y + OPTION_MAX_SIZE.y );
-
-
- Vector2 constrainedOptionSize = Min( Max( optionSize, OPTION_MIN_SIZE ), OPTION_MAX_SIZE );
-
- constrainedOptionSize.height = constrainedOptionSize.height - POPUP_BORDER.y - POPUP_BORDER.z;
-
- // 5. Create a option.
- Toolkit::PushButton option = Toolkit::PushButton::New();
- option.SetSizePolicy( Toolkit::Control::Fixed, Toolkit::Control::Fixed );
- option.SetParentOrigin( ParentOrigin::TOP_LEFT );
- option.SetAnchorPoint( AnchorPoint::TOP_LEFT );
- option.SetSize( constrainedOptionSize );
- option.SetX( mContentSize.x );
- option.SetName( name );
- option.SetAnimationTime( 0.0f );
- option.ClickedSignal().Connect( this, &TextInputPopup::OnButtonPressed );
- mButtons.Add( option );
-
- // 6. Set the normal option image.
- option.SetButtonImage( optionContainer );
-
- // 7. Update the content size.
- mContentSize.x += constrainedOptionSize.x;
- mContentSize.y = std::max ( constrainedOptionSize.y, mContentSize.y );
-
- // 8. Create the pressed container.
- Actor optionPressedContainer = Actor::New();
-
- // 9. Add option pressed background.
- Vector2 optionPressedBackgroundSize( constrainedOptionSize.x - POPUP_BORDER.x, mContentSize.y - POPUP_BORDER.y - POPUP_BORDER.w );
- ImageActor optionPressedBackground = CreatePressedBackground( optionPressedBackgroundSize );
- optionPressedContainer.Add( optionPressedBackground );
-
- // 10. Add pressed text
- Toolkit::TextView pressedCaptionTextView = CreateOptionCaption( caption, mTextPressedColor );
- pressedCaptionTextView.SetSize( GetConstrainedTextSize( Vector2( pressedCaptionTextView.GetNaturalSize() ) ) );
- optionPressedBackground.Add( pressedCaptionTextView );
-
- // 11. Add pressed icon
- ImageActor pressedIcon = CreateOptionIcon( iconImage, mIconPressedColor );
- optionPressedBackground.Add( pressedIcon );
-
- // 12. Set the pressed option image
- option.SetSelectedImage( optionPressedContainer );
-
- // 13. Add the divider
- if ( !finalOption )
- {
- ImageActor divider = CreateDivider();
- mButtons.Add( divider );
- }
-}
-
-void TextInputPopup::Hide(bool animate)
-{
- if( mRoot )
- {
- if(mAnimation)
- {
- mAnimation.Clear();
- mAnimation.Reset();
- }
-
- if(animate)
- {
- mAnimation = Animation::New( HIDE_POPUP_ANIMATION_DURATION );
- mAnimation.AnimateTo( Property(mRoot, Actor::Property::Scale), Vector3::ZERO, AlphaFunctions::EaseOut );
- mAnimation.AnimateTo( Property(mRoot, Actor::Property::ColorAlpha), 0.0f, AlphaFunctions::EaseOut );
- mAnimation.Play();
-
- mAnimation.FinishedSignal().Connect( this, &TextInputPopup::OnHideFinished );
- mState = StateHiding;
- }
- else
- {
- mRoot.SetProperty(Actor::Property::Scale, Vector3::ZERO);
- mRoot.SetProperty(Actor::Property::ColorAlpha, 0.0f);
- mState = StateHidden;
- }
- }
-}
-
-void TextInputPopup::Show( Actor target, bool animate )
-{
- if( mRoot )
- {
- mRoot.SetSensitive( true );
-
- if(mAnimation)
- {
- mAnimation.Clear();
- mAnimation.Reset();
- }
-
- if ( target )
- {
- AddToParent( target );
- }
-
- if(animate)
- {
- mAnimation = Animation::New( SHOW_POPUP_ANIMATION_DURATION );
- mAnimation.AnimateTo( Property(mRoot, Actor::Property::Scale), Vector3::ONE, AlphaFunctions::EaseOut );
- mAnimation.AnimateTo( Property(mRoot, Actor::Property::ColorAlpha), 1.0f, AlphaFunctions::EaseOut );
- mAnimation.Play();
-
- mAnimation.FinishedSignal().Connect( this, &TextInputPopup::OnShowFinished );
- mState = StateShowing;
- }
- else
- {
- mRoot.SetProperty(Actor::Property::Scale, Vector3::ONE);
- mRoot.SetProperty(Actor::Property::ColorAlpha, 1.0f);
- mState = StateShown;
- }
- }
-}
-
-TextInputPopup::State TextInputPopup::GetState(void) const
-{
- return mState;
-}
-
-Actor TextInputPopup::GetRootActor() const
-{
- return mRoot;
-}
-
-// Styling
-
-void TextInputPopup::SetCutPastePopupColor( const Vector4& color )
-{
- mBackgroundColor = color;
-}
-
-const Vector4& TextInputPopup::GetCutPastePopupColor() const
-{
- return mBackgroundColor;
-}
-
-void TextInputPopup::SetCutPastePopupPressedColor( const Vector4& color )
-{
- mBackgroundPressedColor = color;
-}
-
-const Vector4& TextInputPopup::GetCutPastePopupPressedColor() const
-{
- return mBackgroundPressedColor;
-}
-
-void TextInputPopup::SetCutPastePopupBorderColor( const Vector4& color )
-{
- mLineColor = color;
-}
-
-const Vector4& TextInputPopup::GetCutPastePopupBorderColor() const
-{
- return mLineColor;
-}
-
-void TextInputPopup::SetCutPastePopupIconColor( const Vector4& color )
-{
- mIconColor = color;
-}
-
-const Vector4& TextInputPopup::GetCutPastePopupIconColor() const
-{
- return mIconColor;
-}
-
-void TextInputPopup::SetCutPastePopupIconPressedColor( const Vector4& color )
-{
- mIconPressedColor = color;
-}
-
-const Vector4& TextInputPopup::GetCutPastePopupIconPressedColor()
-{
- return mIconPressedColor;
-}
-
-void TextInputPopup::SetCutPastePopupTextColor( const Vector4& color )
-{
- mTextColor = color;
-}
-
-const Vector4& TextInputPopup::GetCutPastePopupTextColor()
-{
- return mTextColor;
-}
-
-void TextInputPopup::SetCutPastePopupTextPressedColor( const Vector4& color )
-{
- mTextPressedColor = color;
-}
-
-const Vector4& TextInputPopup::GetCutPastePopupTextPressedColor()
-{
- return mTextPressedColor;
-}
-
-void TextInputPopup::TogglePopupButtonOnOff( TextInputPopup::Buttons requiredButton, bool enable )
-{
- bool match ( false );
- for( std::vector<ButtonRequirement>::iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt && !match ); ++it )
- {
- ButtonRequirement& button( *it );
- if ( requiredButton == button.buttonId )
- {
- button.enabled = enable;
- match = true;
- }
- }
-}
-
-void TextInputPopup::SetButtonPriorityPosition( TextInputPopup::Buttons button, unsigned int priority )
-{
- switch ( button )
- {
- case ButtonsCut:
- {
- mCutOptionPriority = priority;
- break;
- }
- case ButtonsCopy:
- {
- mCopyOptionPriority = priority;
- break;
- }
- case ButtonsPaste:
- {
- mPasteOptionPriority = priority;
- break;
- }
- case ButtonsSelect:
- {
- mSelectOptionPriority = priority;
- break;
- }
- case ButtonsSelectAll:
- {
- mSelectAllOptionPriority = priority;
- break;
- }
- case ButtonsClipboard:
- {
- mClipboardOptionPriority = priority;
- break;
- }
- case ButtonsEnumEnd:
- {
- DALI_ASSERT_DEBUG( "ButtonsEnumEnd used but an invalid choice");
- break;
- }
- }
- CreateOrderedListOfOptions(); // Update list of options as priority changed.
-}
-
-unsigned int TextInputPopup::GetButtonPriorityPosition( TextInputPopup::Buttons button ) const
-{
- unsigned int priority = 0;
-
- switch ( button )
- {
- case ButtonsCut:
- {
- priority = mCutOptionPriority;
- break;
- }
- case ButtonsCopy:
- {
- priority = mCopyOptionPriority;
- break;
- }
- case ButtonsPaste:
- {
- priority = mPasteOptionPriority;
- break;
- }
- case ButtonsSelect:
- {
- priority = mSelectOptionPriority;
- break;
- }
- case ButtonsSelectAll:
- {
- priority = mSelectAllOptionPriority;
- break;
- }
- case ButtonsClipboard:
- {
- priority = mClipboardOptionPriority;
- break;
- }
- case ButtonsEnumEnd:
- {
- DALI_ASSERT_DEBUG( "ButtonsEnumEnd used but an invalid choice");
- break;
- }
- }
-
- return priority;
-}
-
-void TextInputPopup::AddPopupOptions()
-{
- mContentSize = Vector2( POPUP_MIN_SIZE.width, ( POPUP_BORDER.y + POPUP_BORDER.z ) );
-
- // 1. Create the background.
- CreateBackground();
-
- // 2. Create the tail.
- CreateTail();
-
- // 3. Create the scroll view and Actor to hold buttons.
- CreateScrollView();
-
- // Clear previous buttons
- if ( mButtons )
- {
- UnparentAndReset( mButtons );
- }
-
- mButtons = Actor::New();
- mButtons.SetParentOrigin( ParentOrigin::CENTER );
- mButtons.SetAnchorPoint( AnchorPoint::CENTER );
-
- // 4. Create the options and add into the scroll view.
- for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
- {
- const ButtonRequirement& button( *it );
- if ( button.enabled )
- {
- AddOption( button.name, button.caption, button.iconImage, it != ( endIt - 1 ) ? false : true );
- }
- }
-
- // 5. Calculate size of content and of popup including borders
- const Vector2 popupSize = Vector2( std::min ( ( POPUP_BORDER.x + mContentSize.width + POPUP_BORDER.z ), POPUP_MAX_SIZE.width ) , POPUP_BORDER.y + mContentSize.height + POPUP_BORDER.w );
-
- mVisiblePopUpSize = Vector3( popupSize.width - POPUP_BORDER.x - POPUP_BORDER.z , mContentSize.height, 1.0f);
-
- mBackground.SetSize( popupSize.x + 28 - POPUP_BORDER.x - POPUP_BORDER.z, popupSize.y + 28 - POPUP_BORDER.y - POPUP_BORDER.w );
- mButtons.SetSize( mVisiblePopUpSize.GetVectorXY() );
-
- // 6. Set the scroll view ruler.
- UpdateScrollViewRulerAndSize( mVisiblePopUpSize.GetVectorXY() );
-
- // 7. Create stencil
- const Vector2 stencilSize = Vector2( mVisiblePopUpSize.GetVectorXY() );
-
- CreateLayer( stencilSize );
- CreateStencil( stencilSize );
-
- mScrollView.Add ( mButtons );
- mLayer.Add( mScrollView);
- mLayer.Add( mStencil);
- mRoot.Add( mTail );
- mRoot.Add( mBackground );
- mRoot.Add( mLayer );
-
- // 8. Set the root size.
- mRoot.SetSize( popupSize ); // Make Root Actor reflect the size of its content
-}
-
-const Vector3& TextInputPopup::GetVisibileSize() const
-{
- return mVisiblePopUpSize;
-}
-
-void TextInputPopup::SetTailPosition( const Vector3& position, bool yAxisFlip )
-{
- mPopupTailXPosition = std::max( position.x, POPUP_TAIL_SIZE.width*0.5f - mVisiblePopUpSize.width*0.5f + POPUP_BORDER.x );
-
- std::min( mPopupTailXPosition, mVisiblePopUpSize.width*0.5f - POPUP_BORDER.x - POPUP_TAIL_SIZE.width*0.5f );
-
- mTail.SetX( mPopupTailXPosition );
-
- if ( yAxisFlip )
- {
- Image tail = ResourceImage::New( POPUP_TAIL_TOP );
- Image tailEffect = ResourceImage::New( POPUP_TAIL_TOP_EFFECT );
- Image tailLine = ResourceImage::New( POPUP_TAIL_TOP_LINE );
-
- mTail.SetImage( tail );
- mTailEffect.SetImage( tailEffect );
- mTailLine.SetImage( tailLine );
-
- mTail.SetParentOrigin( ParentOrigin::TOP_CENTER );
- mTail.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
- mTail.SetY( POPUP_BORDER.y - POPUP_TAIL_Y_OFFSET );
- }
-}
-
-bool TextInputPopup::OnButtonPressed( Toolkit::Button button )
-{
- mPressedSignal.Emit( button );
- return false;
-}
-
-void TextInputPopup::OnHideFinished(Animation& source)
-{
- source.FinishedSignal().Disconnect( this, &TextInputPopup::OnHideFinished );
- Clear();
- mState = StateHidden;
- mHideFinishedSignal.Emit( *this );
-}
-
-void TextInputPopup::OnShowFinished(Animation& source)
-{
- source.FinishedSignal().Disconnect( this, &TextInputPopup::OnShowFinished );
- mState = StateShown;
- mShowFinishedSignal.Emit( *this );
-}
-
-TextInputPopup::PressedSignalType& TextInputPopup::PressedSignal()
-{
- return mPressedSignal;
-}
-
-TextInputPopup::VisibilityChangeFinishedSignalType& TextInputPopup::HideFinishedSignal()
-{
- return mHideFinishedSignal;
-}
-
-TextInputPopup::VisibilityChangeFinishedSignalType& TextInputPopup::ShowFinishedSignal()
-{
- return mShowFinishedSignal;
-}
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_POPUP_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_POPUP_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/actors/image-actor.h>
-#include <dali/public-api/actors/layer.h>
-#include <dali/public-api/animation/animation.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
-#include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-class Button;
-
-namespace Internal
-{
-
-class TextInputPopup : public ConnectionTracker
-{
-
-public:
-
- enum State
- {
- StateHidden,
- StateHiding,
- StateShowing,
- StateShown
- };
-
- enum Buttons
- {
- ButtonsCut,
- ButtonsCopy,
- ButtonsPaste,
- ButtonsSelect,
- ButtonsSelectAll,
- ButtonsClipboard,
- ButtonsEnumEnd
- };
-
- struct ButtonRequirement
- {
- TextInputPopup::Buttons buttonId;
- std::size_t orderOfPriority;
- std::string name;
- std::string caption;
- Image iconImage;
- bool enabled;
- };
-
- static const char* const OPTION_SELECT_WORD;
- static const char* const OPTION_SELECT_ALL;
- static const char* const OPTION_CUT;
- static const char* const OPTION_COPY;
- static const char* const OPTION_PASTE;
- static const char* const OPTION_CLIPBOARD;
-
- // Popup Button Pressed
- typedef Signal< bool( Toolkit::Button ) > PressedSignalType;
-
- // Popup Hide / Show Finished
- typedef Signal< void( TextInputPopup& ) > VisibilityChangeFinishedSignalType;
-
- /**
- * Signal emitted when the button is touched.
- */
- PressedSignalType& PressedSignal();
-
- /**
- * Signal emitted when popup is completely hidden
- * @note Only occurs after a Show() call with animation enabled.
- */
- VisibilityChangeFinishedSignalType& HideFinishedSignal();
-
- /**
- * Signal emitted when popup is completely shown
- * @note Only occurs after a Hide() call with animation enabled.
- */
- VisibilityChangeFinishedSignalType& ShowFinishedSignal();
-
-public:
-
- /**
- * Default constructor
- * Creates an empty popup base actor (no content i.e. invisible)
- */
- TextInputPopup();
-
- /**
- * Clears popup options (popup no longer exists)
- */
- void Clear();
-
- /**
- * Create the label
- * @return the newly created Image actor to be used as the icon
- */
- ImageActor CreateOptionIcon( Image iconImage, const Vector4& color );
-
- /**
- * Create the caption
- * @param[in] styledCaption The text to be displayed
- * @return the newly created label
- */
- Toolkit::TextView CreateOptionCaption( const std::string& caption, const Vector4& color );
-
- /**
- * Creates and sets up the background
- */
- void CreateBackground();
-
- /**
- * Create and set up the tail
- */
- void CreateTail();
-
- /**
- * Create divider if multiple options
- * @return Return a divider image actor
- */
- ImageActor CreateDivider();
-
- /**
- * Create a background to be used when option pressed
- * @param[in] requiredSize size Image actor should be
- * @return Returns an Image Actor to be used a pressed background
- */
- ImageActor CreatePressedBackground( const Vector2& requiredSize );
-
- /**
- * Creates a ordered vector of button options
- */
- void CreateOrderedListOfOptions();
-
- /**
- * Get the TextSize after constrained by the Popup margins.
- * @param[in] textSize Natural size of text
- * @return Vector2 constrained text size.
- *
- */
- Vector2 GetConstrainedTextSize( const Vector2& textSize );
-
- /**
- * Adds a popup option.
- * @note Creates popup frame if not already created.
- * @param[in] name The unique name for this option.
- * @param[in] caption The caption (label) for this option
- * @param[in] iconImage Image to displayed with text.
- * @param[in] finalOption Flag to indicate that this is the final option.
- * (set to true on the last option you add)
- */
- void AddOption(const std::string& name, const std::string& caption, const Image iconImage, bool finalOption);
-
- /**
- * Hides the popup
- * @param[in] animate (optional) whether to animate popup to hide state over time (i.e. tween).
- */
- void Hide(bool animate = true);
-
- /**
- * Shows the popup
- * @param[in] animate (optional) whether to animate popup to show state over time (i.e. tween).
- * @param[in] target Actor to parent popup.
- */
- void Show( Actor target, bool animate = true );
-
- /**
- * Returns the current state of the popup.
- * @return The state of the popup see enum State
- */
- State GetState(void) const;
-
- /**
- * Get the root actor which the buttons are added to.
- * @return the root actor
- */
- Actor GetRootActor() const;
-
- /**
- * Set the Cut and Paste buttons color when in normal state
- * @param[in] color color to use
- */
- void SetCutPastePopupColor( const Vector4& color );
-
- /**
- * Get the set color of the Copy and Paste Popup buttons
- * @return color
- */
- const Vector4& GetCutPastePopupColor() const;
-
- /**
- * Set the Cut and Paste button color when pressed.
- * @param[in] color color to use
- */
- void SetCutPastePopupPressedColor( const Vector4& color );
-
- /**
- * Get the Cut and Paste pressed button color.
- * @return color
- */
- const Vector4& GetCutPastePopupPressedColor() const;
-
- /**
- * Set the border color of the popup
- * @param[in] color required color
- */
- void SetCutPastePopupBorderColor( const Vector4& color );
-
- /**
- * Get the border color
- * @return Vector4 the color of the border
- */
- const Vector4& GetCutPastePopupBorderColor() const;
-
- /**
- * Toggle if a popup button should be enabled (shown) or not
- * @param[in] requiredButton Button Id to enable or disable
- * @param[in] enable toggle to enable (true) or disable (false)
- */
- void TogglePopupButtonOnOff( TextInputPopup::Buttons requiredButton, bool enable );
-
- /**
- * Set the Button Priority Position
- * @param[in] button Button id for priority to be set on
- * @param[in] priority Priority level, 1 is highest so will appear first. 0 priority will not show the button.
- */
- void SetButtonPriorityPosition( TextInputPopup::Buttons button, unsigned int priority );
-
- /**
- * Set the icon color of the popup
- * @param[in] color required color
- */
- void SetCutPastePopupIconColor( const Vector4& color );
-
- /**
- * Get the popup icon color
- * @return Vector4 the color of the popup icon
- */
- const Vector4& GetCutPastePopupIconColor() const;
-
- /**
- * Set the pressed icon color of the popup
- * @param[in] color required color
- */
- void SetCutPastePopupIconPressedColor( const Vector4& color );
-
- /**
- * Get the popup pressed icon color
- * @return Vector4 the color of the popup pressed icon
- */
- const Vector4& GetCutPastePopupIconPressedColor();
-
- /**
- * Set the text color of the popup
- * @param[in] color required color
- */
- void SetCutPastePopupTextColor( const Vector4& color );
-
- /**
- * Get the popup text color
- * @return Vector4 the color of the popup text
- */
- const Vector4& GetCutPastePopupTextColor();
-
- /**
- * Set the pressed text color of the popup
- * @param[in] color required color
- */
- void SetCutPastePopupTextPressedColor( const Vector4& color );
-
- /**
- * Get the popup pressed text color
- * @return Vector4 the color of the popup pressed text
- */
- const Vector4& GetCutPastePopupTextPressedColor();
-
- /**
- * Get the Button Priority Position
- * @param[in] button Button id to get priority of
- * @return the button priority, 1 is highest, 0 is not shown.
- */
- unsigned int GetButtonPriorityPosition( TextInputPopup::Buttons button ) const;
-
- /**
- * Adds Popup options which have been enabled.
- */
- void AddPopupOptions();
-
- /**
- * Get Visible size of the Popup, excludes content that needs scrolling
- * @return Vector3 size of Popup
- */
- const Vector3& GetVisibileSize() const;
-
- /**
- * Sets the positon of the PopUp tail relative to TextInput
- * @param[in] position Position to set
- * @param[in] yAxisFlip If tail should be flipped in y axis
- */
- void SetTailPosition( const Vector3& position, const bool yAxisFlip );
-
-private:
-
- /**
- * Creates a Button with the required parameters.
- * @param[in] buttonId enum representing the button
- * @param[in] orderOfPriority Position in toolbar button should be position, 1 is first from left to right.
- * @param[in] name Given name for Button actor
- * @param[in] caption Text to display in button
- * @param[in] iconImage Icon to display in button
- * @param[in] enabled Toggle if button should be used or not, this is decided by the current state/conditions.
- */
- TextInputPopup::ButtonRequirement CreateRequiredButton( TextInputPopup::Buttons buttonId, std::size_t orderOfPriority,
- const std::string& name, const std::string& caption, Image iconImage, bool enabled );
-
- /**
- * @brief Adds popup to the given parent
- * @paran[in] parent target to add Popup to
- */
- void AddToParent( Actor parent );
-
- /**
- * @brief Removes Popup from Parent
- */
- void RemoveFromParent();
-
- /**
- * Applies constraint to keep Popup in view within the desired area.
- */
- void ApplyConfinementConstraint();
-
- /**
- * Applies constraint to keep the Tail attached to Popup
- */
- void ApplyTailConstraint();
-
- /**
- * Create Layer to be used with stencil to allow scrolling of buttons which do not fit in visible popup
- * @param[in] size of the layer.
- */
- void CreateLayer( const Vector2& size );
-
- /**
- * Create a stencil to clip the scroll view content
- * @param[in] size of the stencil.
- */
- void CreateStencil( const Vector2& size );
-
- /**
- * Popup has started to scroll
- * @param[in] position current scroll view position
- */
- void OnScrollStarted( const Vector3& position );
-
- /**
- * Popup has stopped scrolling
- * @param[in] position current scroll view position
- */
- void OnScrollCompleted( const Vector3& position );
-
- /**
- * Create a scroll view to hold the popup buttons and allow scrolling if too many buttons to fit within the visible boundary
- */
- void CreateScrollView();
-
- /**
- * Set the scroll view size and ruler.
- * @param[in] visibleSize size of the visible scroll view
- */
- void UpdateScrollViewRulerAndSize( const Vector2& visibleSize );
-
- /**
- * Called when a button is pressed in the Popup
- * @param[in] button The button pressed.
- */
- bool OnButtonPressed( Toolkit::Button button );
-
- /**
- * Invoked upon popup Hide animation completing.
- * @note Only called for animating hide, not called for instantaneous (animate = false)
- * @param[in] source The animation which completed.
- */
- void OnHideFinished(Animation& source);
-
- /**
- * Invoked upon popup Show animation completing.
- * @note Only called for animating show, not called for instantaneous (animate = false)
- * @param[in] source The animation which completed.
- */
- void OnShowFinished(Animation& source);
-
-private:
-
- State mState; ///< Popup State.
- Layer mRoot; ///< The actor which all popup content is added to (i.e. panel and buttons)
- Actor mButtons; ///< Actor which holds all the buttons, sensitivity can be set on all buttons via this actor
- ImageActor mBackground; ///< The background popup panel
- ImageActor mBackgroundEffect; ///< The background effect
- ImageActor mBackgroundLine; ///< The background line
- ImageActor mTail; ///< The tail for the popup
- ImageActor mTailEffect; ///< the tail effect
- ImageActor mTailLine; ///< The border/outline around the tail
-
- Vector3 mVisiblePopUpSize; ///< Visible Size of Popup excluding content that needs scrolling.
- float mPopupTailXPosition; ///< X position of PopUp tail.
-
- Vector2 mContentSize; ///< Size of Content (i.e. Buttons)
- ActorContainer mDividerContainer; ///< List of dividers added to popup.
- Animation mAnimation; ///< Popup Hide/Show animation.
-
- Layer mLayer; ///< Layer to be used with Stencil
- Actor mStencil; ///< Stencil to clip scrollview
- Toolkit::ScrollView mScrollView; ///< Scrollview to house the popup
-
- std::vector<ButtonRequirement> mOrderListOfButtons; // List of buttons in the order to be displayed and a flag to indicate if needed.
-
- Vector4 mBackgroundColor; // Color of the background of the text input popup
- Vector4 mBackgroundPressedColor; // Color of the option background.
- Vector4 mLineColor; // Color of the line around the text input popup
- Vector4 mIconColor; // Color of the popup icon.
- Vector4 mIconPressedColor; // Color of the popup icon when pressed.
- Vector4 mTextColor; // Color of the popup text.
- Vector4 mTextPressedColor; // Color of the popup text when pressed.
-
- // Priority of Options/Buttons in the Cut and Paste pop-up, higher priority buttons are displayed first, left to right.
- std::size_t mSelectOptionPriority; // Position of Select Button
- std::size_t mSelectAllOptionPriority; // Position of Select All button
- std::size_t mCutOptionPriority; // Position of Cut button
- std::size_t mCopyOptionPriority; // Position of Copy button
- std::size_t mPasteOptionPriority; // Position of Paste button
- std::size_t mClipboardOptionPriority; // Position of Clipboard button
-
- PressedSignalType mPressedSignal; ///< Signal emitted when a button within the popup is pressed.
- VisibilityChangeFinishedSignalType mHideFinishedSignal; ///< Signal emitted when popup is completely hidden
- VisibilityChangeFinishedSignalType mShowFinishedSignal; ///< Signal emitted when popup is completely shown
-
-};
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_ITEM_VIEW_H__
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_POPUP_NEW_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_POPUP_NEW_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
-#include <dali-toolkit/public-api/controls/buttons/button.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-/**
- * @brief Class to create and Popup bar made up of buttons.
- * It provides signals when a button is pressed.
- * The Popup must be positioned by it's owner.
- * The future plan is to reuse the Toolkit Popup control to house the buttons.
- */
-
-class TextInputPopupNew : public ConnectionTracker
-{
-
-public:
-
- enum State
- {
- StateHidden,
- StateHiding,
- StateShowing,
- StateShown
- };
-
- // Popup Button Pressed
- typedef Signal< bool( Toolkit::Button ) > PopUpPressedSignal;
-
- // Popup Hide Finished
- typedef Signal< void( TextInputPopupNew& ) > PopUpVisibilityChangeFinishedSignal;
-
- /**
- * Signal emitted when the button is touched.
- */
- PopUpPressedSignal& PressedSignal() { return mPressedSignal; }
-
- /**
- * Signal emitted when popup is completely hidden
- * @note Only occurs after a Show() call with animation enabled.
- */
- PopUpVisibilityChangeFinishedSignal& HideFinishedSignal() { return mHideFinishedSignal; }
-
- /**
- * Signal emitted when popup is completely shown
- * @note Only occurs after a Hide() call with animation enabled.
- */
- PopUpVisibilityChangeFinishedSignal& ShowFinishedSignal() { return mShowFinishedSignal; }
-
-public:
-
- /**
- * Default constructor
- * Creates an empty popup base actor (no content i.e. invisible)
- */
- TextInputPopupNew()
- : mState(StateHidden)
- { };
-
- /**
- * Destructor
- */
- ~TextInputPopupNew(){};
-
- /**
- * @return The root actor of for this popup is returned.
- */
- Actor Self() { return mRootActor; };
-
- /**
- * Clears popup options (popup no longer exists)
- */
- void Clear(){};
-
- /**
- * Create the label
- * @param[in] styledCaption The text to be displayed
- * @return the newly created label
- */
- Toolkit::TextView CreateLabel( const MarkupProcessor::StyledTextArray& styledCaption ){return Toolkit::TextView();};
-
- /**
- * Create the label
- * @param[in] iconImage the image to be used
- * @return the newly created Image actor to be used as the icon
- */
- ImageActor CreateIcon( Image iconImage ) {return ImageActor();};
-
- /**
- * Creates and sets up the popup background
- */
- void CreatePopUpBackground(){};
-
- /**
- * Create divider if multiple options
- */
- void CreateDivider(){};
-
- /**
- * Create a background to be used when button pressed
- * @param[in] requiredSize size Image actor should be
- * @param[in] finalFlag flag to be set if option is the final one.
- * @return Returns an Image Actor to be used a pressed background
- */
- ImageActor CreatePressedBackground( const Vector3 requiredSize, const bool finalFlag ){ return ImageActor(); };
-
- /**
- * Adds a popup option button.
- * @note Creates popup frame if not already created.
- * @param[in] name The unique name for this option.
- * @param[in] caption The caption (label) for this option
- * @param[in] iconImage Image to displayed with text.
- * @param[in] finalOption Flag to indicate that this is the final option.
- * (set to true on the last option you add)
- */
- void AddButton(const std::string& name, const std::string& caption, const Image iconImage, bool finalOption ){};
-
- /**
- * Hides the popup
- * @param[in] animate (optional) whether to animate popup to hide state over time (i.e. tween).
- */
- void Hide(bool animate = true){};
-
- /**
- * Shows the popup
- * @param[in] animate (optional) whether to animate popup to show state over time (i.e. tween).
- * @param[in] target Actor to parent popup.
- */
- void Show( Actor target, bool animate = true ){};
-
- /**
- * @brief Get the calculated size of the PopUp
- * This can not be set directly as is calculated depending on the content added.
- *
- * @return Vector3 size of PopUp.
- */
- Vector3 GetSize() const { return Vector3::ZERO;};
-
- /**
- * Returns the current state of the popup.
- * @return The state of the popup see enum State
- */
- State GetState(void) const{ return StateHidden;};
-
- /**
- * Get the root actor which the buttons are added to.
- * @return the root actor
- */
- Actor GetRootActor() const { return Actor(); };
-
- /**
- * @brief Creates the PopUp with the required buttons for the provided states.
- * @param[in] isAllTextSelectedAlready Is all the text already selected
- * @param[in] isTextEmpty Contains some text
- * @param[in] hasClipboardGotContent Something to paste from clipboard
- * @param[in] isSubsetOfTextAlreadySelected Some but not all text is selected
- */
- void CreateCutCopyPastePopUp( bool isAllTextSelectedAlready, bool isTextEmpty, bool hasClipboardGotContent, bool isSubsetOfTextAlreadySelected ){};
-
- /**
- * @brief Applies constraint to keep Popup in view within the desired area.
- * @param[in] bounding box in which the PopUp must remain.
- *
- */
- void ApplyConfinementConstraint( Vector4 boundingBox ){};
-
-private:
-
- /**
- * @brief Adds popup to the given parent
- * @paran[in] parent target to add Popup to
- */
- void AddToParent( Actor parent ){};
-
- /**
- * Removes popup from Parent.
- */
- void RemoveFromStage(){};
-
- /**
- * Called when a button is pressed in the popup
- * @param[in] button The button pressed.
- */
- bool OnButtonPressed( Toolkit::Button button ){return false;};
-
- /**
- * Invoked upon popup Hide animation completing.
- * @note Only called for animating hide, not called for instantaneous (animate = false)
- * @param[in] source The animation which completed.
- */
- void OnHideFinished(Animation& source){};
-
- /**
- * Invoked upon popup Show animation completing.
- * @note Only called for animating show, not called for instantaneous (animate = false)
- * @param[in] source The animation which completed.
- */
- void OnShowFinished(Animation& source);
-
-private:
-
- /**
- * @brief Copy Constructor
- * @param[in] popup
- * Undefined/Hidden.
- */
- TextInputPopupNew(const TextInputPopupNew& popup );
-
- /**
- * @Assignment Constructor
- * @param[in] rhs
- * Undefined/Hidden.
- */
- TextInputPopupNew& operator=(const TextInputPopupNew& rhs);
-
-private:
-
- State mState; // Popup State.
- Actor mRootActor; // The actor which all popup content is added to (i.e. panel and buttons)
- Vector3 mPopupSize; // Size of the PopUp determined by it's content and max/min size constraints.
- ImageActor mBackground; // The background popup panel
- ImageActor mTail; // The tail for the popup
- Vector3 mContentSize; // Size of Content (i.e. Buttons)
- ActorContainer mButtonContainer; // List of buttons added to popup.
- ActorContainer mDividerContainer; // List of dividers added to popup.
- Animation mAnimation; // Popup Hide/Show animation.
-
- PopUpPressedSignal mPressedSignal; // Signal emitted when a button within the popup is pressed.
- PopUpVisibilityChangeFinishedSignal mHideFinishedSignal; // Signal emitted when popup is completely hidden
- PopUpVisibilityChangeFinishedSignal mShowFinishedSignal; // Signal emitted when popup is completely shown
-
-};
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_POPUP_NEW_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali-toolkit/internal/controls/text-input/text-input-text-highlight-impl.h>
-
-// EXTERNAL INCLUDES
-#include <math.h>
-#include <sstream>
-#include <algorithm>
-#include <libintl.h>
-#include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
-
-using namespace Dali;
-
-namespace
-{
- /**
- * Selection state enumeration (FSM)
- */
- enum SelectionState
- {
- SelectionNone, ///< Currently not encountered selected section.
- SelectionStarted, ///< Encountered selected section
- SelectionFinished ///< Finished selected section
- };
-
- const Vector4 LIGHTBLUE( 10.0f/255.0f, 140.0f/255.0f, 210.0f/255.0f, 1.0f ); // todo make this a setting
-
- const float CHARACTER_THRESHOLD( 2.5f ); // todo check if unified method to do this in Text
-}
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-// Default constructor
-TextHighlight::TextHighlight( TextViewCharacterPositioning& textViewCharacterPositioning ) :
- mTextViewCharacterPositioning( textViewCharacterPositioning )
-{
-}
-
-TextHighlight::~TextHighlight()
-{
-}
-
-void TextHighlight::GetVisualTextSelection(std::vector<bool>& selectedVisualText, std::size_t startSelection, std::size_t endSelection,
- Toolkit::TextView::TextLayoutInfo& textLayoutInfo )
-{
- std::vector<int>::iterator it = textLayoutInfo.mCharacterLogicalToVisualMap.begin();
- std::vector<int>::iterator startSelectionIt = textLayoutInfo.mCharacterLogicalToVisualMap.begin() + std::min(startSelection, endSelection);
- std::vector<int>::iterator endSelectionIt = textLayoutInfo.mCharacterLogicalToVisualMap.begin() + std::max(startSelection, endSelection);
- std::vector<int>::iterator end = textLayoutInfo.mCharacterLogicalToVisualMap.end();
-
- selectedVisualText.resize( mTextViewCharacterPositioning.GetNumberOfCharactersInText() );
-
- // Deselect text prior to startSelectionIt
- for(;it!=startSelectionIt;++it)
- {
- selectedVisualText[*it] = false;
- }
-
- // Select text from startSelectionIt -> endSelectionIt
- for(;it!=endSelectionIt;++it)
- {
- selectedVisualText[*it] = true;
- }
-
- // Deselect text after endSelection
- for(;it!=end;++it)
- {
- selectedVisualText[*it] = false;
- }
-
- selectedVisualText.resize( mTextViewCharacterPositioning.GetNumberOfCharactersInText(), false );
-}
-
-// Calculate the dimensions of the quads they will make the highlight mesh
-TextHighlight::HighlightInfo TextHighlight::CalculateHighlightInfo( std::size_t handlePositionStart, std::size_t handlePositionEnd, Toolkit::TextView::TextLayoutInfo& textLayoutInfo )
-{
- // At the moment there is no public API to modify the block alignment option.
-
- TextHighlight::HighlightInfo newHighlightInfo;
- //newHighlightInfo.mQuadList.clear(); // clear last quad information.
-
- if ( !mTextViewCharacterPositioning.IsTextEmpty() && !textLayoutInfo.mCharacterLogicalToVisualMap.empty() )
- {
- // Get vector of flags representing characters that are selected (true) vs unselected (false).
- std::vector<bool> selectedVisualText;
- GetVisualTextSelection(selectedVisualText, handlePositionStart, handlePositionEnd, textLayoutInfo );
- std::vector<bool>::iterator selectedIt(selectedVisualText.begin());
- std::vector<bool>::iterator selectedEndIt(selectedVisualText.end());
-
- SelectionState selectionState = SelectionNone; ///< Current selection status of cursor over entire text.
- float rowLeft = 0.0f;
- float rowRight = 0.0f;
- // Keep track of the TextView's min/max extents. Should be able to query this from TextView.
- float maxRowLeft = std::numeric_limits<float>::max();
- float maxRowRight = 0.0f;
-
- Toolkit::TextView::CharacterLayoutInfoContainer::iterator it = textLayoutInfo.mCharacterLayoutInfoTable.begin();
- Toolkit::TextView::CharacterLayoutInfoContainer::iterator end = textLayoutInfo.mCharacterLayoutInfoTable.end();
-
- Toolkit::TextView::CharacterLayoutInfoContainer::iterator lastIt = it;
-
- // Scan through entire text.
- while(it != end)
- {
- // selectionState: None when not in selection, Started when in selection, and Ended when reached end of selection.
-
- Toolkit::TextView::CharacterLayoutInfo& charInfo(*it);
- bool charSelected( false );
- if( selectedIt != selectedEndIt )
- {
- charSelected = *selectedIt++;
- }
-
- if(selectionState == SelectionNone)
- {
- if(charSelected)
- {
- selectionState = SelectionStarted;
- rowLeft = charInfo.mPosition.x - textLayoutInfo.mScrollOffset.x;
- rowRight = rowLeft + charInfo.mSize.width;
- }
- }
- else if(selectionState == SelectionStarted)
- {
- // break selection on:
- // 1. new line causing selection break. (\n or wordwrap)
- // 2. character not selected.
- if(charInfo.mPosition.y - lastIt->mPosition.y > CHARACTER_THRESHOLD ||
- !charSelected)
- {
- // finished selection.
- // TODO: TextView should have a table of visual rows, and each character a reference to the row
- // that it resides on. That way this enumeration is not necessary.
- Vector2 min, max;
- if(lastIt->mIsNewParagraphChar)
- {
- // If the last character is a new line, then to get the row rect, we need to scan from the character before the new line.
- lastIt = std::max( textLayoutInfo.mCharacterLayoutInfoTable.begin(), lastIt - 1 );
- }
- const Size rowSize( mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( lastIt - textLayoutInfo.mCharacterLayoutInfoTable.begin(), min, max ) );
- maxRowLeft = std::min(maxRowLeft, min.x);
- maxRowRight = std::max(maxRowRight, max.x);
- float rowBottom = lastIt->mPosition.y - textLayoutInfo.mScrollOffset.y;
- float rowTop = rowBottom - rowSize.height;
-
- // Still selected, and block-align mode then set rowRight to max, so it can be clamped afterwards
- if(charSelected)
- {
- rowRight = std::numeric_limits<float>::max();
- }
- newHighlightInfo.AddQuad( rowLeft, rowTop, rowRight, rowBottom );
-
- selectionState = SelectionNone;
-
- // Still selected? start a new selection
- if( charSelected )
- {
- // if block-align mode then set rowLeft to min, so it can be clamped afterwards
- rowLeft = 0.0f;
- rowRight = ( charInfo.mPosition.x - textLayoutInfo.mScrollOffset.x ) + charInfo.mSize.width;
- selectionState = SelectionStarted;
- }
- }
- else
- {
- // build up highlight(s) with this selection data.
- rowLeft = std::min( charInfo.mPosition.x - textLayoutInfo.mScrollOffset.x, rowLeft );
- rowRight = std::max( ( charInfo.mPosition.x - textLayoutInfo.mScrollOffset.x ) + charInfo.mSize.width, rowRight );
- }
- }
-
- lastIt = it++;
- }
-
- // If reached end, and still on selection, then close selection.
- if(it == end)
- {
- if(selectionState == SelectionStarted)
- {
- // finished selection.
- Vector2 min, max;
- if(lastIt != end && lastIt->mIsNewParagraphChar)
- {
- lastIt = std::max( textLayoutInfo.mCharacterLayoutInfoTable.begin(), lastIt - 1 );
- }
- if( lastIt != end )
- {
- const Size rowSize( mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( lastIt - textLayoutInfo.mCharacterLayoutInfoTable.begin(), min, max ) );
- maxRowLeft = std::min(maxRowLeft, min.x);
- maxRowRight = std::max(maxRowRight, max.x);
- float rowBottom = lastIt->mPosition.y - textLayoutInfo.mScrollOffset.y;
- float rowTop = rowBottom - rowSize.height;
- newHighlightInfo.AddQuad( rowLeft, rowTop, rowRight, rowBottom );
- }
- }
- }
-
- // Get the top left and bottom right corners.
- const Toolkit::TextView::CharacterLayoutInfo& firstCharacter( *textLayoutInfo.mCharacterLayoutInfoTable.begin() );
- const Vector2 topLeft( maxRowLeft, firstCharacter.mPosition.y - firstCharacter.mSize.height );
- const Vector2 bottomRight( topLeft.x + textLayoutInfo.mTextSize.width, topLeft.y + textLayoutInfo.mTextSize.height );
-
- // Clamp quads so they appear to clip to borders of the whole text.
- newHighlightInfo.Clamp2D( topLeft, bottomRight );
-
- // For block-align align Further Clamp quads to max left and right extents
- // BlockAlign: Will adjust highlight to block:
- // i.e.
- // H[ello] (top row right = max of all rows right)
- // [--this-] (middle rows' left = min of all rows left, middle rows' right = max of all rows right)
- // [is some] (middle rows' left = min of all rows left, middle rows' right = max of all rows right)
- // [text] (bottom row left = min of all rows left)
- // (common in SMS messaging selection)
- //
- // As opposed to the default which is tight text highlighting.
- // H[ello]
- // [this]
- // [is some]
- // [text]
- // (common in regular text editors/web browser selection)
- newHighlightInfo.Clamp2D( Vector2(maxRowLeft, topLeft.y), Vector2(maxRowRight, bottomRight.y ) );
-
- }
-
- return newHighlightInfo;
-}
-
-void TextHighlight::UpdateHighlight( TextHighlight::HighlightInfo& newHighlightInfo )
-{
-// Construct a Mesh with a texture to be used as the highlight 'box' for selected text
-//
-// Example scenarios where mesh is made from 3, 1, 2, 2 ,3 or 3 quads.
-//
-// [ TOP ] [ TOP ] [TOP ] [ TOP ] [ TOP ] [ TOP ]
-// [ MIDDLE ] [BOTTOM] [BOTTOM] [ MIDDLE ] [ MIDDLE ]
-// [ BOTTOM] [ MIDDLE ] [ MIDDLE ]
-// [BOTTOM] [ MIDDLE ]
-// [BOTTOM]
-//
-// Each quad is created as 2 triangles.
-// Middle is just 1 quad regardless of its size.
-//
-// (0,0) (0,0)
-// 0* *2 0* *2
-// TOP TOP
-// 3* *1 3* *1
-// 4* *1 4* *6
-// MIDDLE BOTTOM
-// 6* *5 7* *5
-// 6* *8
-// BOTTOM
-// 9* *7
-//
-
- // vertex and triangle buffers should always be present if MeshActor is alive.
- //HighlightInfo newHighlightInfo = CalculateHighlightInfo( handlePositionStart, handlePositionEnd );
- MeshData::VertexContainer vertices;
- Dali::MeshData::FaceIndices faceIndices;
-
- if( !newHighlightInfo.mQuadList.empty() )
- {
- std::vector<QuadCoordinates>::iterator iter = newHighlightInfo.mQuadList.begin();
- std::vector<QuadCoordinates>::iterator endIter = newHighlightInfo.mQuadList.end();
-
- // vertex position defaults to (0 0 0)
- MeshData::Vertex vertex;
- // set normal for all vertices as (0 0 1) pointing outward from TextInput Actor.
- vertex.nZ = 1.0f;
-
- for(std::size_t v = 0; iter != endIter; ++iter,v+=4 )
- {
- // Add each quad geometry (a sub-selection) to the mesh data.
-
- // 0-----1
- // |\ |
- // | \ A |
- // | \ |
- // | B \ |
- // | \|
- // 2-----3
-
- QuadCoordinates& quad = *iter;
- // top-left (v+0)
- vertex.x = quad.min.x;
- vertex.y = quad.min.y;
- vertices.push_back( vertex );
-
- // top-right (v+1)
- vertex.x = quad.max.x;
- vertex.y = quad.min.y;
- vertices.push_back( vertex );
-
- // bottom-left (v+2)
- vertex.x = quad.min.x;
- vertex.y = quad.max.y;
- vertices.push_back( vertex );
-
- // bottom-right (v+3)
- vertex.x = quad.max.x;
- vertex.y = quad.max.y;
- vertices.push_back( vertex );
-
- // triangle A (3, 1, 0)
- faceIndices.push_back( v + 3 );
- faceIndices.push_back( v + 1 );
- faceIndices.push_back( v );
-
- // triangle B (0, 2, 3)
- faceIndices.push_back( v );
- faceIndices.push_back( v + 2 );
- faceIndices.push_back( v + 3 );
- }
-
- mMeshData.SetVertices( vertices );
- mMeshData.SetFaceIndices( faceIndices );
-
- mHighlightMesh.UpdateMeshData(mMeshData);
- }
-}
-
-Mesh TextHighlight::CreateHighLightMesh()
-{
- mMeshData = MeshData( );
- mMeshData.SetHasNormals( true );
-
- mCustomMaterial = Material::New("CustomMaterial");
- mCustomMaterial.SetDiffuseColor( LIGHTBLUE );
-
- mMeshData.SetMaterial( mCustomMaterial );
-
- mHighlightMesh = Mesh::New( mMeshData );
-
- return mHighlightMesh;
-}
-
-void TextHighlight::HighlightInfo::AddQuad( float x1, float y1, float x2, float y2 )
-{
- QuadCoordinates quad(x1, y1, x2, y2);
- mQuadList.push_back( quad );
-}
-
-void TextHighlight::HighlightInfo::Clamp2D(const Vector2& min, const Vector2& max)
-{
- for(std::size_t i = 0;i < mQuadList.size(); i++)
- {
- QuadCoordinates& quad = mQuadList[i];
-
- quad.min.Clamp(min, max);
- quad.max.Clamp(min, max);
- }
-}
-
-} // Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_HIGHLIGHT_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_HIGHLIGHT_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/geometry/mesh.h>
-#include <dali/public-api/modeling/material.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-input/textview-character-positions-impl.h>
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-/**
- * @brief TextHighlight is a decoration which highlights selected text.
- *
- * The class creates a highlight mesh used to show selected text between handles.
- * Not responsible for positioning.
- */
-class TextHighlight
-{
- /**
- * structure to hold coordinates of each quad, which will make up the mesh.
- */
- struct QuadCoordinates
- {
- /**
- * Default constructor
- */
- QuadCoordinates()
- {
- }
-
- /**
- * Constructor
- * @param[in] x1 left co-ordinate
- * @param[in] y1 top co-ordinate
- * @param[in] x2 right co-ordinate
- * @param[in] y2 bottom co-ordinate
- */
- QuadCoordinates(float x1, float y1, float x2, float y2)
- : min(x1, y1),
- max(x2, y2)
- {
- }
-
- Vector2 min; ///< top-left (minimum) position of quad
- Vector2 max; ///< bottom-right (maximum) position of quad
- };
-
- typedef std::vector<QuadCoordinates> QuadContainer;
-
-public:
-
- /**
- * structure for information required to build the highlight mesh
- */
- struct HighlightInfo
- {
- /**
- * Adds a Quad (2D rectangular sub-selection)
- * @param[in] x1 left co-ordinate
- * @param[in] y1 top co-ordinate
- * @param[in] x2 right co-ordinate
- * @param[in] y2 bottom co-ordinate
- */
- void AddQuad( float x1, float y1, float x2, float y2 );
-
- /**
- * Clamps all quads to fit within a min -> max 2D boundary.
- */
- void Clamp2D(const Vector2& min, const Vector2& max);
-
- QuadContainer mQuadList; ///< List of quads (sub-selections that form to create complete selection)
- };
-
- /**
- * Constructor
- * @param[in] textViewCharacterPositioning TextViewCharacterPositioning to be used for positioning information.
- */
- TextHighlight( TextViewCharacterPositioning& textViewCharacterPositioning );
-
- /**
- * Destructor
- */
- ~TextHighlight();
-
- /**
- * Gets the table of the visual text positions which has a flag
- * for each Character. The flag is either true (character selected)
- * or false (character de-selected)
- * @note startSelection can be greater or less than endSelection
- *
- * @param[in,out] selectedVisualText The vector to be resized and populated with the selected flags
- * @param[in] startSelection The start selection point for the text
- * @param[in] endSelection The end selection point for the text
- * @param[in] endSelection The end selection point for the text
- * @param[in] textLayoutInfo TextView character layout information
- */
- void GetVisualTextSelection(std::vector<bool>& selectedVisualText, std::size_t startSelection, std::size_t endSelection,
- Toolkit::TextView::TextLayoutInfo& textLayoutInfo);
-
- /**
- * Iterates between selection handles and computes the info required to build the highlight mesh
- * @param[in] handlePositionStart starting handle position
- * @param[in] handlePositionEnd ending handle position
- * @return textHighlight target TextHighlight
- */
- TextHighlight::HighlightInfo CalculateHighlightInfo( std::size_t handlePositionStart, std::size_t handlePositionEnd, Toolkit::TextView::TextLayoutInfo& textLayoutInfo );
-
- /**
- * Calculates new Mesh data so highlight moves with selection handles.
- * @param[in] newHighlightInfo HighlightInfo calculated by CalculateHighlightInfo
- */
- void UpdateHighlight( TextHighlight::HighlightInfo& newHighlightInfo );
-
- /**
- * Creates the Mesh data needed by the Mesh Actor
- */
- Mesh CreateHighLightMesh();
-
-private:
-
- /**
- * @brief Copy Constructor
- * @param[in] textHight
- * Undefined/Hidden.
- */
- TextHighlight(const TextHighlight& textHight );
-
- /**
- * @Assignment Constructor
- * @param[in] rhs
- * Undefined/Hidden.
- */
- TextHighlight& operator=(const TextHighlight& rhs);
-
-private:
-
- TextViewCharacterPositioning& mTextViewCharacterPositioning;
-
- Mesh mHighlightMesh; ///< Mesh Data for highlight
- MeshData mMeshData; ///< Container to hold meshData for highlight
- Material mCustomMaterial; ///< Custom material used for highlight
- HighlightInfo mNewHighlightInfo; ///< Geometry info to create highlight.
-
-};
-
-
-} // namespace Internal
-
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_HIGHLIGHT_H__
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXT_STYLE_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXT_STYLE_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/signals/dali-signal.h>
-#include <dali/public-api/text/text-style.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-input/textview-character-positions-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-class TextInputTextStyle;
-
-typedef IntrusivePtr<TextInputTextStyle> TextInputTextStylePtr;
-
-/**
- * Stores the Input Text Style and provides functions to retrieve and manipulate it.
- */
-
-class TextInputTextStyle : ConnectionTracker
-{
-
-public:
-
- /**
- * @brief Constructor
- */
- TextInputTextStyle(){};
-
- /**
- * @brief Destructor
- */
- ~TextInputTextStyle(){};
-
- /**
- * @brief Returns the current Input Style, this is the style that newly inputed text will inherit.
- * @return TextStyle object representing new style.
- */
- TextStyle GetInputStyle() const{return mInputStyle;};
-
- /**
- * @brief Sets the Input style so newly inputed text will inherit this.
- * @param[in] newStyle the style to now use for Input
- * @return returns true if style changed. False if new style is the same as current setting.
- */
- bool SetInputStyle( const TextStyle newStyle, const TextStyle::Mask mask = TextStyle::ALL ){return false;};
-
- /**
- * @brief Gets the Current Font used for newly inputed text
- * @return the Font currently set for new text
- */
- Dali::Font GetInputFont() const{return Dali::Font();};
-
- /**
- * Signals
- */
-
- /* Input style changed signal.*/
- typedef Signal< void( const TextStyle& style ) > StyleChangedSignalType;
-
- /**
- * @brief Signal emitted when style changes.
- * @return The signal to connect to
- */
- StyleChangedSignalType& StyleChangedSignal();
-
-private:
-
- /**
- * @brief Copy Constructor
- * @param[in] textStyle
- * Undefined/Hidden.
- */
- TextInputTextStyle(const TextInputTextStyle& textStyle );
-
- /**
- * @Assignment Constructor
- * @param[in] rhs
- * Undefined/Hidden.
- */
- TextInputTextStyle& operator=(const TextInputTextStyle& rhs);
-
-private:
-
- TextStyle mInputStyle; // Stores the current input style.
- StyleChangedSignalType mStyleChangedSignal; // Signal emitted when style changes.
-};
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXT_STYLE_H__
-
-
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXTVIEW_CHARACTER_POSITIONS_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXTVIEW_CHARACTER_POSITIONS_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-input/text-input-text-style-impl.h>
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-class TextInputTextStyle;
-
-/**
- * Class which contains functions related to the TextView.
- * Functions which are needed by various parts of the TextInput to determine the position of characters.
- * Functions to Set the TextView so text justification, alignment and wrapping behaviour in the desired manner for text input.
- * The functionality of this class may be divided in future.
- */
-class TextViewCharacterPositioning
-{
-
-public:
-
- /**
- * @brief Constructor
- *
- * @param[in] displayedTextView TextView to be used with this class.
- * @param[in] textStyle TextInputTextStyle to be used
- */
- TextViewCharacterPositioning( Toolkit::TextView displayedTextView, TextInputTextStyle& textStyle ):mTextStyle( textStyle ){};
-
- /**
- * Destructor
- */
- ~TextViewCharacterPositioning(){};
-
- /**
- * @brief Creates the TextView to be used within this class.
- */
- void CreateTextView(){};
-
- /*
- * @brief Get a handle to the current text view object
- * If one does not exist then it's create.
- * @return TextView
- */
- Toolkit::TextView GetTextView() const{return Toolkit::TextView();};
-
- /**
- * @brief Get the TextLayoutInfo from the TextView so know the updated positions of characters.
- */
- void UpdateTextLayoutInfo(){};
-
-
- /**
- * @brief Get the TextLayoutInfo structure for the TextView
- * @return the TextLayoutInfo structure
- */
- const Toolkit::TextView::TextLayoutInfo& GetLayoutInfo() const{return mTextLayoutInfo;};
-
-
- /**
- * @brief Get the number of characters visually represented in the text
- * @return the number of characters
- */
- std::size_t GetNumberOfCharactersInText() const{return 0;};
-
- /**
- * @brief Check if any text exists in TextView's character layout table
- * @return bool true if empty
- */
- bool IsTextEmpty() const{return false;};
-
- /**
- * @brief Get the height of the line at the given cursor position
- * @param[in] position
- * @return float the height of the line
- */
- float GetLineHeight( std::size_t position ) const{return 0.0f;};
-
- /**
- * @brief Sets if the inputed text can exceed the text-input boundary.
- * By default is enabled.
- * @param[in] enable Whether the inputed text can exceed its boundary.
- */
- void SetTextExceedEnabled( bool enable ) {};
-
- /**
- * @brief Retrieves whether inputed text can exceed the text-input boundary.
- * @return \e true if text inputed can exceed the boundary, otherwise \e false.
- */
- bool IsTextExceedEnabled() const{ return false;};
-
- /**
- * @brief From the given x and y vector the closest character position is returned
- * @param[in] source the x and y position
- * @return the position in the string of the character closest to the source.
- */
- std::size_t ReturnClosestIndex( const Vector2& source ){return 0;};
-
- /**
- * @brief If no text exists then this function uses the text alignment to position cursor.
- * @param[in] cursorPosition
- */
- void GetActualPositionFromCharacterPositionWhenNoText( Vector3& cursorPosition ) const{};
-
- /**
- * @brief Function to position cursor when a word is wrapped to another line
- * @param[in] characterPosition that actual position is required for
- * @return the actual position of the cursor.
- */
- Vector3 PositionCursorAfterWordWrap( std::size_t characterPosition ) const{return Vector3::ZERO;};
-
- /**
- * @brief Returns the x-position of the current line justification
- * (relative to left of text-view container)
- * @return x position for line justification
- */
- float GetLineJustificationPosition() const{return 0.0f;};
-
- /**
- * @brief Retrieve the dimensions (and min-max) of this row of text that the character resides on.
- * @param[in] characterPosition the position in the 'string' of characters.
- * @param[out] min the top-left position of the rectangle representing this row
- * @param[out] max the bottom-right position of the rectangle representing this row
- * @return The size of the rectangle representing this row (max - min)
- */
- Size GetRowRectFromCharacterPosition(std::size_t characterPosition, Vector2& min, Vector2& max) const{return Vector2::ZERO;};
-
- /**
- * @brief Retrieve the character position of the first character on the row of text
- * that this character resides on.
- * @param[in] logicalPosition the position in the 'string' of characters.
- * @return logical character position of start of row.
- */
- std::size_t GetRowStartFromCharacterPosition(std::size_t logicalPosition) const{return 0;};
-
- /**
- * @brief Gets the visual position of a logical position.
- * @note This is preferred over directly accessing the Map, as it resolves visual
- * positions outside of the character map range.
- * @param[in] logicalPosition The logical position
- * @return Visual position is returned.
- */
- std::size_t GetVisualPosition(std::size_t logicalPosition) const{return 0;};
-
- /**
- * @brief Return a vector which is the actual position for the given character position
- * The character position is where a cursor would be position for that character.
- * @param[in] characterPosition the logical (input) position in the 'string' of characters.
- *
- * @return Vector3 the actual x,y,z position
- */
- Vector3 GetActualPositionFromCharacterPosition(std::size_t characterPosition ) const{return Vector3::ZERO;};
-
- /**
- * @brief Return a vector which is the actual position for the given character position
- * The character position is where a cursor would be positioned for that character to be inserted.
- * An additional alternatePosition is also set in circumstances where the possible writing
- * of characters would be in the opposite direction.
- * e.g. "HelloشقشلاهؤEnglish"
- * | |
- * * +
- * [*] - Primary actual position for cursor i.e. continuing writing LTR (English)
- * [+] - Alternate actual position for cursor i.e. writing RTL (Arabic)
- *
- * @param[in] characterPosition the logical (input) position in the 'string' of characters.
- * @param[out] directionRTL Whether the actual x,y,z position is after LTR (false) or RTL (true) text.
- * @param[out] alternatePosition the actual x,y,z position of the cursor if user types
- * in alternate direction to current flow of text.
- * @param[out] alternatePositionValid whether this alternate position is valid.
- * @return Vector3 the actual x,y,z position
- */
- Vector3 GetActualPositionFromCharacterPosition(std::size_t characterPosition, bool& directionRTL, Vector3& alternatePosition, bool& alternatePositionValid ) const{return Vector3::ZERO;};
-
- /**
- * @brief Get the currently displayed text.
- * @return The currently displayed text.
- */
- std::string GetText() const{return std::string();};
-
- /**
- * @brief Get the text currently being displayed together with mark-up tags.
- * @return string, the currently displayed string with mark-up.
- */
- std::string GetMarkupText() const{return std::string();};
-
- /**
- * @brief Sets whether markup processing should be carried out.
- *
- * @param[in] enable whether markup processing is carried out or not.
- */
- void SetMarkupProcessingEnabled( bool enable ){};
-
- /**
- * @brief Returns whether markup processing is enabled or not
- *
- * @return true is markup processing is enabled
- */
- bool IsMarkupProcessingEnabled() const{ return false;};
-
- // Styled Text
-
- /**
- * @brief Check if styled text is empty
- * @return bool returns true if styled text is empty
- */
- bool IsStyledTextEmpty() const{ return false;};
-
- /**
- * @brief The size of the style text
- * @return std::size_t returns number of characters in styled text
- */
- std::size_t StyledTextSize() const{return 0;};
-
- /**
- * @brief Get the styled text array
- * @return reference to MarkupProcessor::StyledTextArray
- */
- MarkupProcessor::StyledTextArray& GetStyledTextArray(){return mStyledText;};
-
- /**
- * @brief Get the style for the character at the given position
- * @param[in] position of character style is required for
- * @return a copy of the style structure for the character at the given position
- */
- TextStyle GetStyleAt( std::size_t position ) const{return TextStyle();};
-
-/**
- * @briefApplies the given style to all text, selected or not selected.
- * By default all style settings are applied but a bit mask could be used to modify only certain style settings.
- * @param[in] style style to apply
- * @param[in] mask mask style should be applied to
- * @param[in] begin start position of range to apply style
- * @param[in] end end position of range to apply style
- */
- void ApplyStyleToRange( const TextStyle& style, const TextStyle::Mask mask, const std::size_t begin, const std::size_t end ){};
-
- // Snapshot
- /**
- * @copydoc TextView::SetSnapshotModeEnabled()
- */
- void SetSnapshotModeEnabled( bool enable ){};
-
- /**
- * @copydoc TextView::IsSnapshotModeEnabled()
- */
- bool IsSnapshotModeEnabled() const{ return false;};
-
- // Scrolling
- /**
- * @copydoc TextView::SetScrollEnabled()
- */
- void SetScrollEnabled( bool enable ){};
-
- /**
- * @copydoc TextView::SetScrollPosition()
- */
- void SetScrollPosition( const Vector2& position ){};
-
- /**
- * @copydoc TextView::IsScrollEnabled()
- */
- bool IsScrollEnabled() const{ return false;};
-
- /**
- * @copydoc TextView::GetScrollPosition()
- */
- Vector2 GetScrollPosition() const{return Vector2::ZERO;};
-
- /**
- * @copydoc TextView::GetScrollPosition()
- */
- bool IsScrollPositionTrimmed() const{ return false;};
-
-private:
-
- /**
- * @brief Copy Constructor
- * @param[in] characterPositioning
- * Undefined.
- */
- TextViewCharacterPositioning(const TextViewCharacterPositioning& characterPositioning );
-
- /**
- * @Assignment Constructor
- * @param[in] rhs
- * Undefined.
- */
- TextViewCharacterPositioning& operator=(const TextViewCharacterPositioning& rhs);
-
-private:
-
- Toolkit::TextView mDisplayedTextView; // A text view object used to display the text.
- TextInputTextStyle& mTextStyle; // Holds the style object related to input style
-
- MarkupProcessor::StyledTextArray mStyledText; // String currently displayed by TextView with style info.
-
- Toolkit::TextView::TextLayoutInfo mTextLayoutInfo; // It contains a table layout info per character sorted by the character's visual index (retrieved from TextView),
- // a reorder map that stores each character's visual (output) index according to its logical (input) index,
- // a reorder map that stores each character's logical (input) index according to its visual (output) index
-
- bool mExceedEnabled:1; // flag set by user to determine if text can exceed the control's size
- bool mMarkUpEnabled:1; // If Markup is being passed with the text
-};
-
-
-} // namespace Internal
-
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXTVIEW_CHARACTER_POSITIONS_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/license/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
-
-// EXTERNAL INCLUDES
-#include <cmath>
-#include <dali/public-api/text/text-actor-parameters.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-helper-functions.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-dbg.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewRelayout
-{
-
-const float MINIMUM_FADE_BOUNDARY = 0.05f; // When the fade boundary is the same as the text-view boundary, this constant reduces it in order to avoid a zero division.
-
-RelayoutParameters::RelayoutParameters()
-: mPositionOffset(),
- mParagraphSize(),
- mWordSize(),
- mCharacterSize(),
- mIndices(),
- mCharacterGlobalIndex( 0u ),
- mIsFirstCharacter( false ),
- mIsFirstCharacterOfWord( false ),
- mIsNewLine( false ),
- mIsNewParagraphCharacter( false ),
- mIsWhiteSpace( false ),
- mIsVisible( false )
-{
-}
-
-RelayoutParameters::~RelayoutParameters()
-{
-}
-
-FadeParameters::FadeParameters()
-: mRightFadeBoundary( 0.f ),
- mRightFadeThreshold( 0.f ),
- mRightFadeBoundaryOffset( 0.f ),
- mRightFadeThresholdOffset( 0.f ),
- mRightAlphaCoeficients(),
- mLeftFadeBoundary( 0.f ),
- mLeftFadeThreshold( 0.f ),
- mLeftFadeBoundaryOffset( 0.f ),
- mLeftFadeThresholdOffset( 0.f ),
- mLeftAlphaCoeficients(),
- mTopFadeBoundary( 0.f ),
- mTopFadeThreshold( 0.f ),
- mTopFadeBoundaryOffset( 0.f ),
- mTopFadeThresholdOffset( 0.f ),
- mTopAlphaCoeficients(),
- mBottomFadeBoundary( 0.f ),
- mBottomFadeThreshold( 0.f ),
- mBottomFadeBoundaryOffset( 0.f ),
- mBottomFadeThresholdOffset( 0.f ),
- mBottomAlphaCoeficients(),
- mIsPartiallyVisible( false )
-{
-}
-
-FadeParameters::~FadeParameters()
-{
-}
-
-EllipsizeParameters::EllipsizeParameters()
-: mPosition(),
- mLineDescender( 0.f ),
- mLineWidth( 0.f ),
- mEllipsizeBoundary(),
- mFirstIndex( 0u ),
- mLastIndex( 0u ),
- mEllipsizeLine( false ),
- mIsLineWidthFullyVisible( false ),
- mIsLineHeightFullyVisible( false ),
- mIsNextLineFullyVisibleHeight( false ),
- mCreateEllipsizedTextActors( false ),
- mLineFits( false ),
- mWordFits( false )
-{
-}
-
-EllipsizeParameters::~EllipsizeParameters()
-{
-}
-
-UnderlineInfo::UnderlineInfo()
-: mMaxHeight( 0.f ),
- mMaxThickness( 0.f ),
- mPosition( 0.f )
-{
-}
-
-UnderlineInfo::~UnderlineInfo()
-{
-}
-
-TextUnderlineStatus::TextUnderlineStatus()
-: mUnderlineInfo(),
- mCharacterGlobalIndex( 0u ),
- mLineGlobalIndex( 0u ),
- mCurrentUnderlineStatus( false )
-{
-}
-
-TextUnderlineStatus::~TextUnderlineStatus()
-{
-}
-
-LineLayoutInfo::LineLayoutInfo()
-: mLineLength( 0.f ),
- mMaxCharHeight( 0.f ),
- mMaxAscender( 0.f )
-{
-}
-
-LineLayoutInfo::~LineLayoutInfo()
-{
-}
-
-/**
- * Whether the given text-actor exceeds the left or the right boundary of the text-view.
- *
- * @param[in] position The position of the text-actor.
- * @param[in] size The size of the text-actor.
- * @param[in] parantSize The size of the text-view.
- *
- * @return \e true if the text-actor exceeds the left or the right boundary of the text-view.
- */
-bool IsExceedingWidth( const Vector3& position, const Size& size, const Size& parentSize )
-{
- return ( ( position.x < 0.f ) ||
- ( position.x + size.width > parentSize.width ) );
-}
-
-/**
- * Whether the given text-actor exceeds the top or the bottom boundary of the text-view.
- *
- * @param[in] position The position of the text-actor.
- * @param[in] size The size of the text-actor.
- * @param[in] parantSize The size of the text-view.
- *
- * @return \e true if the text-actor exceeds the top or the bottom boundary of the text-view.
- */
-bool IsExceedingHeight( const Vector3& position, const Size& size, const Size& parentSize )
-{
- return ( ( position.y > parentSize.height ) ||
- ( position.y < size.height ) );
-}
-
-/**
- * Calculates the line length adding the new word or character width.
- *
- * It also returns the length of white spaces if they are at the end of the line.
- *
- * @param[in] isWhiteSpace Whether the word is a white space.
- * @param[in] width The width of the character or word.
- * @param[in] parentWidth The parent width.
- * @param[out] found Whether the sum of the new character or word is exceding the parent's width.
- * @param[out] lineLength The length of the portion of line which doesn't exceed the parant's width
- * @param[out] endWhiteSpaceLength The length of white spaces which are at the end of the line.
- */
-void CalculateLineLength( bool isWhiteSpace, float width, float parentWidth, bool& found, float& lineLength, float& endWhiteSpaceLength )
-{
- if( lineLength + width > parentWidth )
- {
- found = true;
- lineLength -= endWhiteSpaceLength;
- }
- else
- {
- lineLength += width;
-
- if( isWhiteSpace )
- {
- endWhiteSpaceLength += width;
- }
- else
- {
- endWhiteSpaceLength = 0.f;
- }
- }
-}
-
-struct CurrentTextActorInfo
-{
- TextActor textActor;
- Text text;
- Vector3 position;
- Size size;
- Vector4 color;
- TextViewProcessor::CharacterLayoutInfo* characterLayout;
-};
-
-void SetVisualParameters( CurrentTextActorInfo& currentTextActorInfo,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData,
- const float lineHeight )
-{
- currentTextActorInfo.textActor.SetTextColor( currentTextActorInfo.color );
- if( ( NULL != currentTextActorInfo.characterLayout ) &&
- ( NULL != currentTextActorInfo.characterLayout->mGradientInfo ) )
- {
- currentTextActorInfo.textActor.SetGradientColor( currentTextActorInfo.characterLayout->mGradientInfo->mGradientColor );
- currentTextActorInfo.textActor.SetGradientStartPoint( currentTextActorInfo.characterLayout->mGradientInfo->mStartPoint );
- currentTextActorInfo.textActor.SetGradientEndPoint( currentTextActorInfo.characterLayout->mGradientInfo->mEndPoint );
- }
-
- // The italics offset is used in the offscreen rendering. When text is in italics, it may exceed the text-view's boundary
- // due to the trick used to implement it.
- const Radian& italicsAngle = currentTextActorInfo.textActor.GetItalicsAngle();
- const float italicsOffset = lineHeight * std::tan( italicsAngle );
- relayoutData.mTextLayoutInfo.mMaxItalicsOffset = std::max( relayoutData.mTextLayoutInfo.mMaxItalicsOffset, italicsOffset );
-
- // Sets the sort modifier value.
- currentTextActorInfo.textActor.SetSortModifier( visualParameters.mSortModifier );
-
- // Enables or disables the blending.
- currentTextActorInfo.textActor.SetBlendMode( !visualParameters.mSnapshotModeEnabled ? BlendingMode::ON : BlendingMode::OFF );
-}
-
-void CalculateLineLayout( float parentWidth,
- const TextViewProcessor::TextInfoIndices& indices,
- const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo,
- HorizontalWrapType splitPolicy,
- float shrinkFactor,
- LineLayoutInfo& subLineInfo )
-{
- subLineInfo.mLineLength = 0.f;
- subLineInfo.mMaxCharHeight = 0.f;
- subLineInfo.mMaxAscender = 0.f;
-
- float endWhiteSpaceLength = 0.f;
-
- std::size_t characterIndex = indices.mCharacterIndex;
- float lineOffset = 0.f;
- bool found = false;
- bool isFirstCharacter = true;
- for( TextViewProcessor::WordLayoutInfoContainer::const_iterator wordIt = paragraphLayoutInfo.mWordsLayoutInfo.begin() + indices.mWordIndex,
- wordEndIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
- ( wordIt != wordEndIt ) && !found;
- ++wordIt )
- {
- const TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordIt );
-
- const float shrunkWordWidth = wordLayoutInfo.mSize.width * shrinkFactor;
- const bool isWhiteSpace = TextViewProcessor::WordSeparator == wordLayoutInfo.mType;
-
- bool splitByCharacter = false;
-
- switch( splitPolicy )
- {
- case WrapByCharacter:
- {
- splitByCharacter = true;
- break;
- }
- case WrapByWord:
- case WrapByParagraphCharacter: // Fall through
- {
- splitByCharacter = false;
- break;
- }
- case WrapByWordAndSplit:
- {
- splitByCharacter = ( shrunkWordWidth > parentWidth );
- break;
- }
- case WrapByParagraphCharacterAndSplit:
- {
- if( ( 0u != characterIndex ) ||
- ( ( 0u == characterIndex ) && ( lineOffset + shrunkWordWidth > parentWidth ) ) )
- {
- splitByCharacter = true;
- }
- else
- {
- lineOffset += shrunkWordWidth;
- splitByCharacter = false;
- }
- }
- }
-
- if( splitByCharacter )
- {
- for( TextViewProcessor::CharacterLayoutInfoContainer::const_iterator charIt = wordLayoutInfo.mCharactersLayoutInfo.begin() + characterIndex,
- charEndIt = wordLayoutInfo.mCharactersLayoutInfo.end();
- ( charIt != charEndIt ) && !found;
- ++charIt )
- {
- const TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *charIt );
- CalculateLineLength( isWhiteSpace, characterLayoutInfo.mSize.width * shrinkFactor, parentWidth, found, subLineInfo.mLineLength, endWhiteSpaceLength );
- if( !found || isFirstCharacter )
- {
- subLineInfo.mMaxCharHeight = std::max( subLineInfo.mMaxCharHeight, characterLayoutInfo.mSize.height );
- subLineInfo.mMaxAscender = std::max( subLineInfo.mMaxAscender, characterLayoutInfo.mAscender );
- }
-
- // All characters for word 'wordIndex' have been processed.
- // Next word need to process all characters, so the characterIndex is reset to 0.
- characterIndex = 0u;
- isFirstCharacter = false;
- }
-
- lineOffset += subLineInfo.mLineLength;
- }
- else
- {
- CalculateLineLength( isWhiteSpace, shrunkWordWidth, parentWidth, found, subLineInfo.mLineLength, endWhiteSpaceLength );
- if( !found || isFirstCharacter )
- {
- subLineInfo.mMaxCharHeight = std::max( subLineInfo.mMaxCharHeight, wordLayoutInfo.mSize.height );
- subLineInfo.mMaxAscender = std::max( subLineInfo.mMaxAscender, wordLayoutInfo.mAscender );
- }
- isFirstCharacter = false;
- }
- }
-
- subLineInfo.mMaxCharHeight *= shrinkFactor;
- subLineInfo.mMaxAscender *= shrinkFactor;
-}
-
-
-/**
- * Sets a character of a line of a bidirectional paragraph in the new position.
- *
- * @param[in] wordsLayoutInfo Layout info of all the words of the paragraph.
- * @param[in] index Index within the paragraph to the character to be set in the new position.
- * @param[in,out] character Reference to the character in the new position.
- */
-void SetCharacter( const TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo,
- std::size_t index,
- TextViewProcessor::CharacterLayoutInfo& character )
-{
- // Traverse all the characters of the paragraph till the one pointed by index is found.
- std::size_t traversedCharacters = 0u;
- for( TextViewProcessor::WordLayoutInfoContainer::const_iterator wordIt = wordsLayoutInfo.begin(),
- wordEndIt = wordsLayoutInfo.end();
- wordIt != wordEndIt;
- ++wordIt )
- {
- const TextViewProcessor::WordLayoutInfo& word( *wordIt );
-
- const std::size_t numberOfCharacters = word.mCharactersLayoutInfo.size();
- if( index < traversedCharacters + numberOfCharacters )
- {
- character = *( word.mCharactersLayoutInfo.begin() + ( index - traversedCharacters ) );
- return;
- }
- traversedCharacters += numberOfCharacters;
- }
-}
-
-/**
- * Reorders the layout info of each line of the paragraph.
- *
- * Uses the visual to logical conversion table to order the text, styles and character's layout (metrics).
- *
- * @param[in] characterGlobalIndex Index within the whole text of the first character of the paragraph.
- * @param[in,out] rtlParagraph Layout info for the paragraph with rtl text.
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void ReorderLayout( std::size_t characterGlobalIndex,
- TextViewProcessor::ParagraphLayoutInfo& paragraph,
- TextView::RelayoutData& relayoutData )
-{
- // Clear any previous right to left layout.
- if( NULL != paragraph.mRightToLeftLayout )
- {
- paragraph.mRightToLeftLayout->Clear();
- paragraph.mRightToLeftLayout->mPreviousLayoutCleared = true;
- }
- else
- {
- // Create a new right to left layout if there isn't any.
- paragraph.mRightToLeftLayout = new TextViewProcessor::RightToLeftParagraphLayout();
- }
-
- // Reorder Text and Styles.
-
- // Reserve space for the styles.
- paragraph.mRightToLeftLayout->mTextStyles.Reserve( paragraph.mTextStyles.Count() );
-
- // Traverses all the bidirectional info per line.
- for( Vector<TextProcessor::BidirectionalLineInfo*>::ConstIterator it = paragraph.mBidirectionalLinesInfo.Begin(), endIt = paragraph.mBidirectionalLinesInfo.End(); it != endIt; ++it )
- {
- TextProcessor::BidirectionalLineInfo* info( *it );
-
- const std::size_t characterParagraphIndex = info->mCharacterParagraphIndex;
- const Vector<int>& visualToLogicalMap = info->mVisualToLogicalMap;
-
- // The text can be appended as it's already reordered.
- paragraph.mRightToLeftLayout->mText.Append( info->mText );
-
- // The visual to logical map needs to be used to reorder the styles.
- for( std::size_t index = 0u, size = visualToLogicalMap.Count(); index < size; ++index )
- {
- paragraph.mRightToLeftLayout->mTextStyles.PushBack( *( paragraph.mTextStyles.Begin() + ( characterParagraphIndex + *( visualToLogicalMap.Begin() + index ) ) ) );
- }
- }
-
- // Reorder Layout Info.
-
- // Reserve space for the new word layout.
- paragraph.mRightToLeftLayout->mWordsLayoutInfo.reserve( paragraph.mWordsLayoutInfo.size() );
-
- // Traverses all the bidirectional info per line.
- for( Vector<TextProcessor::BidirectionalLineInfo*>::ConstIterator it = paragraph.mBidirectionalLinesInfo.Begin(), endIt = paragraph.mBidirectionalLinesInfo.End(); it != endIt; ++it )
- {
- TextProcessor::BidirectionalLineInfo* info( *it );
-
- // Reserve space for all characters.
- TextViewProcessor::CharacterLayoutInfoContainer characters;
- characters.resize( info->mNumberOfCharacters );
-
- // Uses the visual to logical map to set every character in its new position.
- for( std::size_t index = 0u; index < info->mNumberOfCharacters; ++index )
- {
- SetCharacter( paragraph.mWordsLayoutInfo,
- info->mCharacterParagraphIndex + info->mVisualToLogicalMap[index],
- *( characters.begin() + index ) );
- }
-
- // Sets the new 'x' position for each character.
- // Updates the text-view's layout info table with the new position of the character.
- float xPosition = 0.f;
- std::size_t index = 0u;
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator it = characters.begin(), endIt = characters.end(); it != endIt; ++it, ++index )
- {
- TextViewProcessor::CharacterLayoutInfo& character( *it );
-
- // Set the 'x' position.
- character.mPosition.x = xPosition;
-
- // Update layout info table.
- relayoutData.mCharacterLayoutInfoTable[characterGlobalIndex + info->mVisualToLogicalMap[index]].mPosition = character.mPosition;
-
- // Update the position for the next character.
- xPosition += character.mSize.width;
- }
-
- // Split the reordered text in words.
- std::size_t previousPosition = 0u;
- Vector<std::size_t> positions;
- TextProcessor::SplitInWords( info->mText, positions );
-
- // Whether last character is a word or a paragraph separator.
- const std::size_t lastCharacterIndex = info->mText.GetLength() - 1u;
- const bool isLastCharacterParagraphSeparator = info->mText.IsNewLine( lastCharacterIndex );
- const bool isLastCharacterWordSeparator = info->mText.IsWhiteSpace( lastCharacterIndex );
-
- // Sets the characters into the words they belong to.
- for( Vector<std::size_t>::ConstIterator it = positions.Begin(), endIt = positions.End(); it != endIt; ++it )
- {
- const std::size_t position = *it;
-
- TextViewProcessor::WordLayoutInfo word;
- word.mCharactersLayoutInfo.insert( word.mCharactersLayoutInfo.end(),
- characters.begin() + previousPosition,
- characters.begin() + position );
-
- if( !word.mCharactersLayoutInfo.empty() )
- {
- // Updates the layout of the word.
- TextViewProcessor::UpdateLayoutInfo( word );
-
- paragraph.mRightToLeftLayout->mWordsLayoutInfo.push_back( word );
- }
-
- // white space or new paragraph.
- TextViewProcessor::WordLayoutInfo space;
-
- space.mCharactersLayoutInfo.insert( space.mCharactersLayoutInfo.end(),
- characters.begin() + position,
- characters.begin() + position + 1u );
-
- space.mType = TextViewProcessor::WordSeparator;
-
- TextViewProcessor::UpdateLayoutInfo( space );
-
- paragraph.mRightToLeftLayout->mWordsLayoutInfo.push_back( space );
-
- previousPosition = position + 1u;
- }
-
- // The last word.
- if( previousPosition < paragraph.mRightToLeftLayout->mText.GetLength() )
- {
- TextViewProcessor::WordLayoutInfo word;
- word.mCharactersLayoutInfo.insert( word.mCharactersLayoutInfo.end(),
- characters.begin() + previousPosition,
- characters.end() );
-
- if( isLastCharacterParagraphSeparator )
- {
- word.mType = TextViewProcessor::ParagraphSeparator;
- }
- else if( isLastCharacterWordSeparator )
- {
- word.mType = TextViewProcessor::WordSeparator;
- }
- TextViewProcessor::UpdateLayoutInfo( word );
-
- paragraph.mRightToLeftLayout->mWordsLayoutInfo.push_back( word );
- }
- }
-}
-
-/**
- * Creates the bidirectional info needed to reorder each line of the paragraph.
- *
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info.
- * @param[in,out] paragraph Layout info for the paragraph.
- * @param[in] characterGlobalIndex Index to the character within the whole text.
- * @param[in] lineLayoutInfoIndex Index to the table of lines.
- */
-void CreateBidirectionalInfoForLines( TextView::RelayoutData& relayoutData,
- TextViewProcessor::ParagraphLayoutInfo& paragraph,
- std::size_t& characterGlobalIndex,
- std::size_t& lineLayoutInfoIndex )
-{
- const std::size_t lineLayoutInfoSize = relayoutData.mLines.size(); // Number or laid out lines.
- bool lineLayoutEnd = false; // Whether lineLayoutInfoIndex points at the last laid out line.
-
- // Clear previously created bidirectional info.
- paragraph.ClearBidirectionalInfo();
-
- // For each character, it sets the character's direction.
-
- // Initialize the paragraph direction. Used to set the direction of weak characters.
- const bool isParagraphRightToLeft = paragraph.mBidirectionalParagraphInfo->IsRightToLeftParagraph();
- bool isPreviousRightToLeft = isParagraphRightToLeft;
-
- for( std::size_t index = 0u; index < paragraph.mNumberOfCharacters; ++index )
- {
- // Get the character's layout information (the one is shared with text-input)
- Toolkit::TextView::CharacterLayoutInfo& info = *( relayoutData.mCharacterLayoutInfoTable.begin() + ( characterGlobalIndex + index ) );
-
- // Gets the character's direction.
- const Character::CharacterDirection direction = paragraph.mText[index].GetCharacterDirection();
- if( Character::RightToLeft == direction )
- {
- info.mIsRightToLeftCharacter = true;
- }
- else if( Character::Neutral == direction )
- {
- // For neutral characters it check's the next and previous directions.
- // If they are equals set that direction. If they are not, sets the paragraph direction.
- // If there is no next, sets the previous direction.
-
- // Check next character's direction.
- bool isNextRightToLeft = isPreviousRightToLeft;
- if( index < paragraph.mNumberOfCharacters - 1u )
- {
- const Character::CharacterDirection nextDirection = paragraph.mText[index + 1u].GetCharacterDirection();
- isNextRightToLeft = Character::RightToLeft == nextDirection;
- }
-
- info.mIsRightToLeftCharacter = isPreviousRightToLeft == isNextRightToLeft ? isPreviousRightToLeft : isParagraphRightToLeft;
- }
- else
- {
- info.mIsRightToLeftCharacter = false;
- }
-
- isPreviousRightToLeft = info.mIsRightToLeftCharacter;
- }
-
- std::size_t characterParagraphIndex = 0u; // Index to the character (within the paragraph).
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = paragraph.mWordsLayoutInfo.begin(), wordEndIt = paragraph.mWordsLayoutInfo.end();
- wordIt != wordEndIt;
- ++wordIt )
- {
- TextViewProcessor::WordLayoutInfo& word( *wordIt );
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterIt = word.mCharactersLayoutInfo.begin(), characterEndIt = word.mCharactersLayoutInfo.end();
- characterIt != characterEndIt;
- ++characterIt )
- {
- TextProcessor::BidirectionalLineInfo* bidirectionalLineInfo = NULL;
-
- // Check if there is a new line.
- const bool newLine = !lineLayoutEnd && ( characterGlobalIndex == relayoutData.mLines[lineLayoutInfoIndex].mCharacterGlobalIndex );
-
- if( newLine )
- {
- // Point to the next line.
- ++lineLayoutInfoIndex;
- if( lineLayoutInfoIndex >= lineLayoutInfoSize )
- {
- // Arrived at last line.
- lineLayoutEnd = true; // Avoids access out of bounds in the relayoutData.mLines vector.
- }
-
- // Number of characters of the line.
- const size_t numberOfCharacters = ( lineLayoutEnd ? relayoutData.mTextLayoutInfo.mNumberOfCharacters : relayoutData.mLines[lineLayoutInfoIndex].mCharacterGlobalIndex ) - characterGlobalIndex;
-
- // There is right to left characters in this line. It needs to be reordered.
- bidirectionalLineInfo = new TextProcessor::BidirectionalLineInfo();
- bidirectionalLineInfo->mCharacterParagraphIndex = characterParagraphIndex;
- bidirectionalLineInfo->mNumberOfCharacters = numberOfCharacters;
-
- // Set all the Text's characters in the visual order and creates the mapping tables.
- TextProcessor::ReorderLine( paragraph.mBidirectionalParagraphInfo,
- bidirectionalLineInfo );
-
- paragraph.mBidirectionalLinesInfo.PushBack( bidirectionalLineInfo );
-
- for( std::size_t index = 0u; index < numberOfCharacters; ++index )
- {
- relayoutData.mCharacterLogicalToVisualMap.push_back( characterGlobalIndex + bidirectionalLineInfo->mLogicalToVisualMap[index] );
- relayoutData.mCharacterVisualToLogicalMap.push_back( characterGlobalIndex + bidirectionalLineInfo->mVisualToLogicalMap[index] );
- }
- }
-
- ++characterGlobalIndex;
- ++characterParagraphIndex;
- } // characters
- } // words
-}
-
-void ReorderRightToLeftLayout( TextView::RelayoutData& relayoutData )
-{
- // Reset conversion tables shared through public-api
- relayoutData.mCharacterLogicalToVisualMap.clear();
- relayoutData.mCharacterVisualToLogicalMap.clear();
-
- std::size_t characterGlobalIndex = 0u; // Index to the global character (within the whole text).
- std::size_t lineLayoutInfoIndex = 0u; // Index to the line info.
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(), paragraphEndIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphIt != paragraphEndIt;
- ++paragraphIt )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraph( *paragraphIt );
-
- if( NULL != paragraph.mBidirectionalParagraphInfo )
- {
- // There is right to left text in this paragraph.
-
- // Stores the current global character index as is needed in both functions.
- const std::size_t currentGlobalIndex = characterGlobalIndex;
-
- // Creates the bidirectional info needed to reorder each line of the paragraph.
- CreateBidirectionalInfoForLines( relayoutData,
- paragraph,
- characterGlobalIndex,
- lineLayoutInfoIndex );
-
- // Reorder each line of the paragraph
- ReorderLayout( currentGlobalIndex, paragraph, relayoutData );
- }
- else
- {
- // Identity in case the paragraph has no right to left text.
- for( std::size_t index = 0u; index < paragraph.mNumberOfCharacters; ++index )
- {
- const std::size_t globalIndex = characterGlobalIndex + index;
- relayoutData.mCharacterLogicalToVisualMap.push_back( globalIndex );
- relayoutData.mCharacterVisualToLogicalMap.push_back( globalIndex );
- }
- characterGlobalIndex += paragraph.mNumberOfCharacters;
- }
- } // paragraphs
-}
-
-float CalculateXoffset( Toolkit::Alignment::Type horizontalTextAlignment, float parentWidth, float wholeTextWidth )
-{
- float xOffset( 0.f );
- switch( horizontalTextAlignment )
- {
- case Toolkit::Alignment::HorizontalLeft:
- {
- // nothing to do.
- break;
- }
- case Toolkit::Alignment::HorizontalCenter:
- {
- xOffset = 0.5f * ( parentWidth - wholeTextWidth );
- break;
- }
- case Toolkit::Alignment::HorizontalRight:
- {
- xOffset = parentWidth - wholeTextWidth;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextViewRelayout::CalculateXoffset: Wrong horizontal text alignment. Did you set a vertical one?" );
- }
- }
-
- return xOffset;
-}
-
-float CalculateYoffset( Toolkit::Alignment::Type verticalTextAlignment, float parentHeight, float wholeTextHeight )
-{
- float yOffset( 0.f );
- switch( verticalTextAlignment )
- {
- case Toolkit::Alignment::VerticalTop:
- {
- // nothing to do.
- break;
- }
- case Toolkit::Alignment::VerticalCenter:
- {
- yOffset = 0.5f * ( parentHeight - wholeTextHeight );
- break;
- }
- case Toolkit::Alignment::VerticalBottom:
- {
- yOffset = parentHeight - wholeTextHeight;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextViewRelayout::CalculateXoffset: Wrong vertical text alignment. Did you set an horizontal one?" );
- }
- }
-
- return yOffset;
-}
-
-float CalculateJustificationOffset( Toolkit::TextView::LineJustification justification, float wholeTextWidth, float lineLength )
-{
- float offset = 0.f;
- switch( justification )
- {
- case Toolkit::TextView::Left:
- {
- offset = 0.f;
- break;
- }
- case Toolkit::TextView::Center:
- {
- offset = 0.5f * ( wholeTextWidth - lineLength );
- break;
- }
- case Toolkit::TextView::Right:
- {
- offset = wholeTextWidth - lineLength;
- break;
- }
- case Toolkit::TextView::Justified:
- {
- offset = 0.f;
- break;
- }
- }
-
- return offset;
-}
-
-bool IsVisible( const Vector3& position, const Size& size, const Size& parentSize, VisibilityTestType type )
-{
- bool visible = false;
-
- switch( type )
- {
- case FULLY_VISIBLE:
- {
- // Whether the text-actor is fully inside the boundaries of the text-view.
- visible = ( ( position.x >= 0.f ) && ( position.x + size.width <= parentSize.width ) &&
- ( position.y >= size.height ) && ( position.y <= parentSize.height ) );
- break;
- }
- case FULLY_VISIBLE_WIDTH:
- {
- // Whether the text-actor is between the left and right boundaries of the text-view.
- visible = ( ( position.x >= 0.f ) && ( position.x + size.width <= parentSize.width ) );
- break;
- }
- case FULLY_VISIBLE_HEIGHT:
- {
- // Whether the text-actor is between the top and bottom boundaries of the text-view.
- visible = ( ( position.y >= size.height ) && ( position.y <= parentSize.height ) );
- break;
- }
- case PARTIALLY_VISIBLE:
- {
- // Whether the text-actor is partially inside the boundaries of the text-view.
- visible = ( ( position.x < parentSize.width ) &&
- ( position.x + size.width > 0.f ) &&
- ( position.y > 0.f ) &&
- ( position.y - size.height < parentSize.height ) );
- break;
- }
- case PARTIALLY_VISIBLE_WIDTH:
- {
- // Whether the text-actor is partially inside the area defined by the left and the right boundaries of the text-view.
- // It may not be partially inside the text-view.
- visible = ( ( position.x < parentSize.width ) &&
- ( position.x + size.width > 0.f ) );
- break;
- }
- case PARTIALLY_VISIBLE_HEIGHT:
- {
- // Whether the text-actor is partially inside the area defined by the top and the bottom boundaries of the text-view.
- // It may not be partially inside the text-view.
- visible = ( ( position.y > 0.f ) &&
- ( position.y - size.height < parentSize.height ) );
- break;
- }
- }
-
- return visible;
-}
-
-Vector2 CalculateRectParameters( const Vector2& p0, const Vector2& p1 )
-{
- const float gradient = ( p1.y - p0.y ) / ( p1.x - p0.x );
-
- return Vector2( gradient, p0.y - gradient * p0.x );
-}
-
-void UpdateAlignment( const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- // Calculates an offset to align the whole text within the text-view's boundary accordingly with the set alignment and justification options.
- // The offset could be negative if the whole text is bigger than the boundary of the text-view.
-
- // If the exceed policy is ellipsize at the end, negative offsets are not wanted.
- // In that case, it will align the line to the left and/or top, and ellipsize the end.
- const bool ellipsizeAlignToLeft = ( layoutParameters.mExceedPolicy == TextView::EllipsizeEndOriginal ) ||
- ( layoutParameters.mExceedPolicy == TextView::EllipsizeEnd ) ||
- ( layoutParameters.mExceedPolicy == TextView::SplitEllipsizeEnd );
- const bool ellipsizeAlignToTop = ( layoutParameters.mExceedPolicy == TextView::EllipsizeEnd ) ||
- ( layoutParameters.mExceedPolicy == TextView::SplitEllipsizeEnd );
-
- RelayoutParameters relayoutParameters;
-
- // Calculates the vertical and horizontal offsets.
- const float textHorizontalOffset = CalculateXoffset( layoutParameters.mHorizontalAlignment, relayoutData.mTextViewSize.width, relayoutData.mTextSizeForRelayoutOption.width );
- const float textVerticalOffset = CalculateYoffset( layoutParameters.mVerticalAlignment, relayoutData.mTextViewSize.height, relayoutData.mTextSizeForRelayoutOption.height );
-
- // Index to the global character (within the whole text).
- std::size_t characterGlobalIndex = 0u;
-
- // Index to the line info.
- std::size_t lineLayoutInfoIndex = 0u;
-
- relayoutParameters.mIndices.mParagraphIndex = 0u;
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(),
- endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphLayoutIt != endParagraphLayoutIt;
- ++paragraphLayoutIt, ++relayoutParameters.mIndices.mParagraphIndex )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
-
- float justificationOffset = 0.f;
-
- const std::size_t lineLayoutInfoSize = relayoutData.mLines.size(); // Number of lines.
- bool lineLayoutEnd = false; // Whether lineLayoutInfoIndex points at the last line.
-
- relayoutParameters.mIndices.mWordIndex = 0u;
-
- const bool isRightToLeftLayout = NULL != paragraphLayoutInfo.mRightToLeftLayout;
- TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayoutInfo.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayoutInfo.mWordsLayoutInfo;
-
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = wordsLayoutInfo.begin(),
- endWordLayoutIt = wordsLayoutInfo.end();
- wordLayoutIt != endWordLayoutIt;
- ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
- {
- TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
-
- relayoutParameters.mIndices.mCharacterIndex = 0u;
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
- endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
- characterLayoutIt != endCharacterLayoutIt;
- ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex, ++characterGlobalIndex )
- {
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
-
- // Check if there is a new line.
- const bool newLine = !lineLayoutEnd && ( characterGlobalIndex == relayoutData.mLines[lineLayoutInfoIndex].mCharacterGlobalIndex );
-
- if( newLine )
- {
- // Calculate line justification offset.
- justificationOffset = CalculateJustificationOffset( layoutParameters.mLineJustification, relayoutData.mTextSizeForRelayoutOption.width, relayoutData.mLines[lineLayoutInfoIndex].mSize.width );
-
- // Point to the next line.
- ++lineLayoutInfoIndex;
- if( lineLayoutInfoIndex >= lineLayoutInfoSize )
- {
- // Arrived at last line.
- lineLayoutEnd = true; // Avoids access out of bounds in the relayoutData.mLines vector.
- }
- }
-
- // Deletes the offsets if the exceed policies are EllipsizeEnd.
- const float horizontalOffset = textHorizontalOffset + justificationOffset;
- characterLayoutInfo.mOffset.x = ( ellipsizeAlignToLeft && ( horizontalOffset < 0.f ) ) ? 0.f : horizontalOffset;
- characterLayoutInfo.mOffset.y = ( ellipsizeAlignToTop && ( textVerticalOffset < 0.f ) ) ? 0.f : textVerticalOffset;
-
- // Updates the size and position table for text-input with the alignment offset.
- Vector3 positionOffset( characterLayoutInfo.mPosition );
-
- // Update layout info table.
- std::vector<Toolkit::TextView::CharacterLayoutInfo>::iterator infoTableIt = relayoutData.mCharacterLayoutInfoTable.begin() + relayoutData.mCharacterVisualToLogicalMap[characterGlobalIndex];
- Toolkit::TextView::CharacterLayoutInfo& characterTableInfo( *infoTableIt );
-
- characterTableInfo.mPosition.x = positionOffset.x + characterLayoutInfo.mOffset.x;
- characterTableInfo.mPosition.y = positionOffset.y + characterLayoutInfo.mOffset.y;
-
- positionOffset.x += characterLayoutInfo.mSize.width * relayoutData.mShrinkFactor;
- } // end characters
- } // end words
- } // end paragraphs
-}
-
-void CalculateBearing( TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
- TextView::RelayoutData& relayoutData )
-{
- // No bearing used.
- //
- // gggggggggg
- // gggggggggg
- // gggg gggg
- // gggg gggg
- // gggg gggg
- // gggg gggg
- // gggg gggg
- // gggg gggg
- // ggggg gggggggggg bb ggggg
- // gg gg gggggggggg bb gg gg
- // gg gg gggg bb gg gg
- // gg gg gggg bb gg gg
- // ggggg gg gggg bbbbbbb ggggg
- // gg gg gggg bb bb gg
- // g gg gggggggggg bb bb g gg
- // ggggg gggggggggg bbbbbbb ggggg
- //
- // Bearing used.
- //
- // gggggggggg
- // gggggggggg
- // gggg gggg bb
- // gggg gggg bb
- // gggg gggg bb
- // ggggg gggg gggg bb ggggg
- // gg gg gggg gggg bbbbbbb gg gg
- // gg gg gggg gggg bb bb gg gg
- // gg gg gggggggggg bb bb gg gg
- // ggggg gggggggggg bbbbbbb ggggg
- // gg gggg gg
- // g gg gggg g gg
- // ggggg gg gggg ggggg
- // gg gggg
- // gggggggggg
- // gggggggggg
-
- const Toolkit::TextView::LineLayoutInfo& lineInfo( *( relayoutData.mLines.end() - 1u ) );
- const float bearingOffset = ( lineInfo.mSize.height - lineInfo.mAscender ) - ( characterLayoutInfo.mSize.height - characterLayoutInfo.mAscender );
-
- characterLayoutInfo.mPosition.y -= bearingOffset * relayoutData.mShrinkFactor;
-}
-
-void UpdateLayoutInfoTable( Vector4& minMaxXY,
- TextViewProcessor::WordLayoutInfo& wordLayoutInfo,
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
- RelayoutParameters& relayoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- // updates min and max position to calculate the text size for multiline policies.
- minMaxXY.x = std::min( minMaxXY.x, characterLayoutInfo.mPosition.x );
- minMaxXY.z = std::max( minMaxXY.z, characterLayoutInfo.mPosition.x + characterLayoutInfo.mSize.width * relayoutData.mShrinkFactor );
-
- minMaxXY.y = std::min( minMaxXY.y, characterLayoutInfo.mPosition.y - characterLayoutInfo.mSize.height * relayoutData.mShrinkFactor );
- minMaxXY.w = std::max( minMaxXY.w, characterLayoutInfo.mPosition.y );
-
- // Adds layout info to be retrieved by external controls or applications.
- Vector3 positionOffset( characterLayoutInfo.mPosition );
-
- const float descender = characterLayoutInfo.mSize.height - characterLayoutInfo.mAscender;
-
- const Toolkit::TextView::CharacterLayoutInfo characterLayoutTableInfo( Size( characterLayoutInfo.mSize.width * relayoutData.mShrinkFactor,
- characterLayoutInfo.mSize.height * relayoutData.mShrinkFactor ),
- positionOffset,
- ( TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType ),
- false, // whether the character is right to left. The value is set in a next step in the CreateBidirectionalInfoForLines function
- true, // whether the character is visible.
- descender );
-
- relayoutData.mCharacterLayoutInfoTable.push_back( characterLayoutTableInfo );
-
- positionOffset.x += characterLayoutInfo.mSize.width * relayoutData.mShrinkFactor;
-}
-
-void CalculateVisibilityForFade( const Internal::TextView::LayoutParameters& layoutParameters,
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
- const TextStyle& style,
- RelayoutParameters& relayoutParameters,
- FadeParameters& fadeParameters,
- TextView::RelayoutData& relayoutData )
-{
- if( ( TextView::Fade != layoutParameters.mExceedPolicy ) &&
- ( TextView::SplitFade != layoutParameters.mExceedPolicy ) &&
- ( TextView::FadeOriginal != layoutParameters.mExceedPolicy ) &&
- ( TextView::OriginalFade != layoutParameters.mExceedPolicy ) )
- {
- // nothing to fade
- return;
- }
-
- // Calculates visibility of a text-actor according the exceed policies.
-
- // position + alignment offset.
- const Vector3 position( characterLayoutInfo.mPosition.x + characterLayoutInfo.mOffset.x,
- characterLayoutInfo.mPosition.y + characterLayoutInfo.mOffset.y,
- characterLayoutInfo.mPosition.z );
-
- // Whether the text actor is fully, partially or non visible (according exceed policies).
- switch( layoutParameters.mExceedPolicy )
- {
- case TextView::Fade:
- {
- // All text-actors which are not completely inside the text-view's boundaries are set as non visible.
- // All text-actors which are partially inside the text-view's boundaries are set as partially visible.
- if( !IsVisible( position,
- characterLayoutInfo.mSize,
- relayoutData.mTextViewSize,
- FULLY_VISIBLE ) )
- {
- relayoutParameters.mIsVisible = false;
- if( IsVisible( position,
- characterLayoutInfo.mSize,
- relayoutData.mTextViewSize,
- PARTIALLY_VISIBLE ) )
- {
- fadeParameters.mIsPartiallyVisible = true;
-
- // Checks if a text-actor is exceeding more than one boundary as this case is not supported.
- if( IsExceedingWidth( position,
- characterLayoutInfo.mSize,
- relayoutData.mTextViewSize ) &&
- IsExceedingHeight( position,
- characterLayoutInfo.mSize,
- relayoutData.mTextViewSize ) )
- {
- // Combination not fully supported by text-view.
- // Need to check if text-actor really supports this combination.
- fadeParameters.mIsPartiallyVisible = false;
- }
- }
- }
- break;
- }
- case TextView::FadeOriginal:
- {
- // All text-actors which are not completely between the left and right text-view's boundaries are set as non visible.
- // All text-actors which are partially inside the text-view's boundaries are set as partially visible.
- if( !IsVisible( position,
- characterLayoutInfo.mSize,
- relayoutData.mTextViewSize,
- FULLY_VISIBLE_WIDTH ) )
- {
- relayoutParameters.mIsVisible = false;
- if( IsVisible( position,
- characterLayoutInfo.mSize,
- relayoutData.mTextViewSize,
- PARTIALLY_VISIBLE_WIDTH ) )
- {
- fadeParameters.mIsPartiallyVisible = true;
- }
- }
- break;
- }
- case TextView::OriginalFade:
- case TextView::SplitFade: // Fallthrough
- {
- // All text-actors which are not completely between the top and bottom text-view's boundaries are set as non visible.
- // All text-actors which are partially inside the text-view's boundaries are set as partially visible.
- if( !IsVisible( position,
- characterLayoutInfo.mSize,
- relayoutData.mTextViewSize,
- FULLY_VISIBLE_HEIGHT ) )
- {
- relayoutParameters.mIsVisible = false;
- if( IsVisible( position,
- characterLayoutInfo.mSize,
- relayoutData.mTextViewSize,
- PARTIALLY_VISIBLE_HEIGHT ) )
- {
- fadeParameters.mIsPartiallyVisible = true;
- }
- }
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextViewRelayout::CalculateVisibilityForFade. Wrong exceed policies." )
- break;
- }
- }
-
- if( relayoutParameters.mIsVisible || fadeParameters.mIsPartiallyVisible )
- {
- characterLayoutInfo.mIsVisible = true;
-
- const Size size = characterLayoutInfo.mSize * relayoutData.mShrinkFactor;
- const float characterPositionPlusWidth = position.x + size.width;
- const float characterPositionMinusHeight = position.y - size.height;
-
- // Calculates which edges need to be faded-out.
- bool rightFadeOut = false;
- bool leftFadeOut = false;
- bool bottomFadeOut = false;
- bool topFadeOut = false;
-
- switch( layoutParameters.mExceedPolicy )
- {
- case TextView::Fade:
- {
- // All text-actors exceeding any of the boundaries will be faded-out.
- rightFadeOut = ( characterPositionPlusWidth > fadeParameters.mRightFadeThreshold );
- leftFadeOut = ( position.x < fadeParameters.mLeftFadeThreshold );
- bottomFadeOut = ( position.y > fadeParameters.mBottomFadeThreshold );
- topFadeOut = ( characterPositionMinusHeight < fadeParameters.mTopFadeThreshold );
- break;
- }
- case TextView::FadeOriginal:
- {
- // Only text-actors exceeding the left or the right boundaries will be faded-out.
- rightFadeOut = ( characterPositionPlusWidth > fadeParameters.mRightFadeThreshold );
- leftFadeOut = ( position.x < fadeParameters.mLeftFadeThreshold );
- break;
- }
- case TextView::SplitFade:
- case TextView::OriginalFade: //Fallthrough
- {
- // Only text-actors exceeding the top or the bottom boundaries will be faded-out.
- bottomFadeOut = ( position.y > fadeParameters.mBottomFadeThreshold );
- topFadeOut = ( characterPositionMinusHeight < fadeParameters.mTopFadeThreshold );
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextViewRelayout::CalculateVisibilityForFade. Wrong exceed policies." );
- break;
- }
- }
-
- // Calculates gradient parameters for a text-actor.
- Vector4 gradientColor = Vector4::ZERO;
- Vector2 startPoint = Vector2::ZERO;
- Vector2 endPoint = Vector2::ZERO;
-
- if( !( rightFadeOut && leftFadeOut ) )
- {
- // Current implementation can't set gradient parameters for a text-actor exceeding at the same time the left and the right boundaries.
- if( rightFadeOut )
- {
- gradientColor = style.GetTextColor();
-
- // Calculates gradient coeficients.
- characterLayoutInfo.mColorAlpha = gradientColor.a * std::min( 1.f, fadeParameters.mRightAlphaCoeficients.x * position.x + fadeParameters.mRightAlphaCoeficients.y );
- gradientColor.a *= std::max( 0.f, fadeParameters.mRightAlphaCoeficients.x * characterPositionPlusWidth + fadeParameters.mRightAlphaCoeficients.y );
-
- startPoint = Vector2( std::max( 0.f, std::min( 1.f, ( fadeParameters.mRightFadeThresholdOffset - position.x ) / size.width ) ), 0.5f );
- endPoint = Vector2( std::min( 1.f, std::max( 0.f, ( relayoutData.mTextViewSize.width - position.x ) / size.width ) ), 0.5f );
-
- if( NULL == characterLayoutInfo.mGradientInfo )
- {
- characterLayoutInfo.mGradientInfo = new TextViewProcessor::GradientInfo();
- }
- }
- else if( leftFadeOut )
- {
- gradientColor = style.GetTextColor();
-
- // Calculates gradient coeficients.
- characterLayoutInfo.mColorAlpha = std::min( 1.f, fadeParameters.mLeftAlphaCoeficients.x * characterPositionPlusWidth + fadeParameters.mLeftAlphaCoeficients.y );
- gradientColor.a *= gradientColor.a * std::max( 0.f, fadeParameters.mLeftAlphaCoeficients.x * position.x + fadeParameters.mLeftAlphaCoeficients.y );
-
- startPoint = Vector2( std::max( 0.f, std::min( 1.f, ( fadeParameters.mLeftFadeThresholdOffset - position.x ) / size.width ) ), 0.5f );
- endPoint = Vector2( std::min( 1.f, std::max( 0.f, -position.x / size.width ) ), 0.5f );
-
- if( NULL == characterLayoutInfo.mGradientInfo )
- {
- characterLayoutInfo.mGradientInfo = new TextViewProcessor::GradientInfo();
- }
- }
- }
-
- if( !( bottomFadeOut && topFadeOut ) )
- {
- // Current implementation can't set gradient parameters for a text-actor exceeding at the same time the top and the bottom boundaries.
- if( bottomFadeOut )
- {
- gradientColor = style.GetTextColor();
-
- // Calculates gradient coeficients.
- characterLayoutInfo.mColorAlpha = gradientColor.a * std::min( 1.f, fadeParameters.mBottomAlphaCoeficients.x * characterPositionMinusHeight + fadeParameters.mBottomAlphaCoeficients.y );
- gradientColor.a *= std::max( 0.f, fadeParameters.mBottomAlphaCoeficients.x * position.y + fadeParameters.mBottomAlphaCoeficients.y );
-
- startPoint = Vector2( 0.5f, std::max( 0.f, std::min( 1.f, ( fadeParameters.mBottomFadeThresholdOffset - characterPositionMinusHeight ) / size.height ) ) );
- endPoint = Vector2( 0.5f, std::min( 1.f, std::max( 0.f, ( relayoutData.mTextViewSize.height - characterPositionMinusHeight ) / size.height ) ) );
-
- if( NULL == characterLayoutInfo.mGradientInfo )
- {
- characterLayoutInfo.mGradientInfo = new TextViewProcessor::GradientInfo();
- }
- }
- else if( topFadeOut )
- {
- gradientColor = style.GetTextColor();
-
- // Calculates gradient coeficients.
- characterLayoutInfo.mColorAlpha *= gradientColor.a * std::min( 1.f, fadeParameters.mTopAlphaCoeficients.x * position.y + fadeParameters.mTopAlphaCoeficients.y );
- gradientColor.a *= std::max( 0.f, fadeParameters.mTopAlphaCoeficients.x * characterPositionMinusHeight + fadeParameters.mTopAlphaCoeficients.y );
-
- startPoint = Vector2( 0.5f, std::max( 0.f, std::min( 1.f, ( fadeParameters.mTopFadeThresholdOffset - characterPositionMinusHeight ) / size.height ) ) );
- endPoint = Vector2( 0.5f, std::min( 1.f, std::max( 0.f, -characterPositionMinusHeight / size.height ) ) );
-
- if( NULL == characterLayoutInfo.mGradientInfo )
- {
- characterLayoutInfo.mGradientInfo = new TextViewProcessor::GradientInfo();
- }
- }
- }
-
- if( NULL != characterLayoutInfo.mGradientInfo )
- {
- characterLayoutInfo.mGradientInfo->mGradientColor = gradientColor;
- characterLayoutInfo.mGradientInfo->mStartPoint = startPoint;
- characterLayoutInfo.mGradientInfo->mEndPoint = endPoint;
- }
- }
- else
- {
- characterLayoutInfo.mIsVisible = false;
- }
-}
-
-bool CalculateVisibilityForEllipsizeEndOriginal( TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
- const EllipsizeParameters& ellipsizeParameters )
-{
- bool isPartiallyVisible = false;
-
- if( !IsVisible( ellipsizeParameters.mPosition,
- characterLayoutInfo.mSize,
- ellipsizeParameters.mEllipsizeBoundary,
- FULLY_VISIBLE_WIDTH ) )
- {
- // The character doesn't fit in the text-view's width.
- characterLayoutInfo.mIsVisible = false;
-
- // Checks if the character is partially visible (it's cut by the boundary)
- isPartiallyVisible = IsVisible( ellipsizeParameters.mPosition,
- characterLayoutInfo.mSize,
- ellipsizeParameters.mEllipsizeBoundary,
- PARTIALLY_VISIBLE_WIDTH );
- }
- else
- {
- // The character fits in the text-view's width. Set it to visible.
- characterLayoutInfo.mIsVisible = true;
- }
-
- return isPartiallyVisible;
-}
-
-bool CalculateVisibilityForEllipsizeEnd( TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
- const EllipsizeParameters& ellipsizeParameters )
-{
- bool isPartiallyVisible = false;
-
- if( !IsVisible( ellipsizeParameters.mPosition,
- characterLayoutInfo.mSize,
- ellipsizeParameters.mEllipsizeBoundary,
- FULLY_VISIBLE ) )
- {
- // The character is not fully visible. Needs to check if it's partially visible.
- characterLayoutInfo.mIsVisible = false;
-
- // Checks if the character doesn't cut the bottom edge of the text-view.
- const bool fullyVisibleHeight = IsVisible( ellipsizeParameters.mPosition,
- characterLayoutInfo.mSize,
- ellipsizeParameters.mEllipsizeBoundary,
- FULLY_VISIBLE_HEIGHT );
-
- // Checks if the character cuts the right edge of the text-view.
- const bool partiallyVisibleWidth = IsVisible( ellipsizeParameters.mPosition,
- characterLayoutInfo.mSize,
- ellipsizeParameters.mEllipsizeBoundary,
- PARTIALLY_VISIBLE_WIDTH );
-
- // Character will be ellipsized if it cuts the right edge of the text-view but fits completely in the text-view's height.
- isPartiallyVisible = ( fullyVisibleHeight && partiallyVisibleWidth );
- }
- else
- {
- // The character fits in the boundary of the text-view. Set it to visible.
- characterLayoutInfo.mIsVisible = true;
- }
-
- return isPartiallyVisible;
-}
-
-void CalculateVisibilityForEllipsize( const Internal::TextView::LayoutParameters& layoutParameters,
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
- EllipsizeParameters& ellipsizeParameters,
- TextView::RelayoutData& relayoutData )
-{
- // Calculates visibility for EllipsizeEnd exceed policies.
-
- // It defines a boundary on the right side of the text-view by substracting the ellipsize-text's size (...) to the text-view's size.
- // If a character is cut by this boundary and the whole line (if the multi-line policy is split-by-new-line-char)
- // or the whole word (if the multi-line policy is split-by-word) doesn't fit in the text-view's width, then it's replaced by the ellipsize-text.
-
- // Position of the character used to do the visibility test.
- ellipsizeParameters.mPosition = Vector3( characterLayoutInfo.mPosition.x + characterLayoutInfo.mOffset.x,
- characterLayoutInfo.mPosition.y + characterLayoutInfo.mOffset.y,
- characterLayoutInfo.mPosition.z );
-
- // Text will be ellipsized if a character is partially visible (it's cut by the boundary defined in the right side of the text-view).
- bool isPartiallyVisible = false;
-
- // Checks if the whole line or the whole word fits in the text-view's width accordingly with the multiline policy.
- const bool fitsInWidth = ( Toolkit::TextView::SplitByNewLineChar == layoutParameters.mMultilinePolicy ) ? ellipsizeParameters.mLineFits: ellipsizeParameters.mWordFits;
-
- // Will only ellipsize the text if it cuts the right vertical edge and it doesn't fit in the text-view's width.
- if( fitsInWidth )
- {
- // The line or word fits completely inside the text-view's width. Nothing else to do.
- characterLayoutInfo.mIsVisible = true;
- }
- else
- {
- // The line or word doesn't fit in the text-view's width.
-
- // Calculates visibility for each type of ellipsize policies.
- switch( layoutParameters.mExceedPolicy )
- {
- case TextView::EllipsizeEndOriginal:
- {
- // Ellipsizes the text if it doesn't fit in the width but it doesn't ellipsize if the text doesn't fit in the height.
-
- isPartiallyVisible = CalculateVisibilityForEllipsizeEndOriginal( characterLayoutInfo,
- ellipsizeParameters );
-
- break;
- }
- case TextView::SplitEllipsizeEnd:
- case TextView::EllipsizeEnd:
- {
- // Ellipsizes the text if it doesn't fit in the width and fully fits in the text-view's height.
-
- isPartiallyVisible = CalculateVisibilityForEllipsizeEnd( characterLayoutInfo,
- ellipsizeParameters );
-
- break;
- }
- default:
- {
- DALI_ASSERT_DEBUG( !"TextViewRelayout::CalculateVisibilityForEllipsize. Wrong exceed value." );
- break;
- }
- }
- }
-
- // If the current character is not fully visible but is partially visible, it is cut by the boundary of the text-view.
- // In that case, the charater needs to be replaced by the ellipsize text.
- ellipsizeParameters.mCreateEllipsizedTextActors = ( !characterLayoutInfo.mIsVisible && isPartiallyVisible );
-}
-
-void CreateEllipsizeTextActor( const EllipsizeParameters& ellipsizeParameters,
- TextView::RelayoutData& relayoutData )
-{
- // The default ellipsize text is '...' and all dots have the same style. However, a differernt ellipsize text could be set and it can have characters with differernt styles.
- // The code bellow creates the text-actors needed for the ellipsize text.
-
- // Set ellipsize's position by the end of visible text.
- Vector3 ellipsizePosition = ellipsizeParameters.mPosition;
- // Stores current ellipsize text.
- Text ellipsizeText;
- // Stores current ellipsize style.
- TextStyle ellipsizeStyle;
- // Stores the current size.
- Size ellipsizeSize;
- //Whether current glyph is an emoticon.
- bool isColorGlyph = false;
-
- float bearingOffset = 0.f;
-
- // Create ellipsize text-actor.
- std::size_t characterIndex = 0u;
- for( TextViewProcessor::CharacterLayoutInfoContainer::const_iterator ellipsizeCharacterLayoutIt = relayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo.mCharactersLayoutInfo.begin(),
- endEllipsizeCharacterLayoutIt = relayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo.mCharactersLayoutInfo.end();
- ellipsizeCharacterLayoutIt != endEllipsizeCharacterLayoutIt;
- ++ellipsizeCharacterLayoutIt, ++characterIndex )
- {
- const TextViewProcessor::CharacterLayoutInfo& ellipsizeCharacterLayoutInfo( *ellipsizeCharacterLayoutIt );
- const TextStyle& style = *( *( relayoutData.mTextLayoutInfo.mEllipsisTextStyles.Begin() + characterIndex ) );
-
- if( isColorGlyph ||
- ( isColorGlyph != ellipsizeCharacterLayoutInfo.mIsColorGlyph ) ||
- ( ellipsizeStyle != style ) )
- {
- // The style is different, so a new text-actor is needed.
- if( !ellipsizeText.IsEmpty() )
- {
- // It only creates a text-actor if there is any text.
- RenderableActor ellipsizeGlyphActor = CreateGlyphActor( ellipsizeText, ellipsizeStyle, relayoutData.mTextActorCache );
- ellipsizeGlyphActor.SetSize( ellipsizeSize );
- ellipsizeGlyphActor.SetPosition( Vector3( ellipsizePosition.x, ellipsizePosition.y - bearingOffset, ellipsizePosition.z ) );
-
- // Updates the position for the next text-actor.
- ellipsizePosition.x += ellipsizeSize.width;
-
- // Adds the text-actor to the list.
- relayoutData.mEllipsizedGlyphActors.push_back( ellipsizeGlyphActor );
- }
-
- // Resets the current ellipsize info.
- ellipsizeText = Text( relayoutData.mTextLayoutInfo.mEllipsisText[characterIndex] );
- ellipsizeStyle = style;
- ellipsizeSize = ellipsizeCharacterLayoutInfo.mSize;
- isColorGlyph = ellipsizeCharacterLayoutInfo.mIsColorGlyph;
-
- bearingOffset = ( ellipsizeParameters.mLineDescender - ( ellipsizeCharacterLayoutInfo.mSize.height - ellipsizeCharacterLayoutInfo.mAscender ) ) * relayoutData.mShrinkFactor;
- }
- else
- {
- // Updates text and size with the new character.
- ellipsizeText.Append( relayoutData.mTextLayoutInfo.mEllipsisText[characterIndex] );
- TextViewProcessor::UpdateSize( ellipsizeSize, ellipsizeCharacterLayoutInfo.mSize );
- }
- }
-
- if( !ellipsizeText.IsEmpty() )
- {
- // Creates the last glyph-actor.
- RenderableActor ellipsizeGlyphActor = CreateGlyphActor( ellipsizeText, ellipsizeStyle, relayoutData.mTextActorCache );
- ellipsizeGlyphActor.SetSize( ellipsizeSize );
- ellipsizeGlyphActor.SetPosition( Vector3( ellipsizePosition.x, ellipsizePosition.y - bearingOffset, ellipsizePosition.z ) );
-
- // Adds the glyph-actor to the list.
- relayoutData.mEllipsizedGlyphActors.push_back( ellipsizeGlyphActor );
- }
-}
-
-void EllipsizeLine( const TextView::LayoutParameters& layoutParameters,
- EllipsizeParameters& ellipsizeParameters,
- TextView::RelayoutData& relayoutData )
-{
- // Traverses the text layout info from the first character of the line
- // to the last one setting to each character its visibility. If needed, it adds the ellipsize text (...).
-
- // Indices to the first character of the line.
- TextViewProcessor::TextInfoIndices firstIndices;
- TextViewProcessor::GetIndicesFromGlobalCharacterIndex( ellipsizeParameters.mFirstIndex,
- relayoutData.mTextLayoutInfo,
- firstIndices );
-
- // Indices to the last character of the line.
- TextViewProcessor::TextInfoIndices lastIndices;
- TextViewProcessor::GetIndicesFromGlobalCharacterIndex( ellipsizeParameters.mLastIndex,
- relayoutData.mTextLayoutInfo,
- lastIndices );
-
- // Defines a boundary by substracting the ellipsize-text's width to the text-view's width.
- // This is the boundary used to check if a character have to be ellipsized.
- ellipsizeParameters.mEllipsizeBoundary = relayoutData.mTextViewSize;
- ellipsizeParameters.mEllipsizeBoundary.width -= relayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo.mSize.width;
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + firstIndices.mParagraphIndex,
- endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + lastIndices.mParagraphIndex + 1u;
- paragraphLayoutIt != endParagraphLayoutIt;
- ++paragraphLayoutIt )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
-
- ellipsizeParameters.mLineFits = ellipsizeParameters.mIsLineWidthFullyVisible && ellipsizeParameters.mIsLineHeightFullyVisible && ellipsizeParameters.mIsNextLineFullyVisibleHeight;
-
- if( !ellipsizeParameters.mIsNextLineFullyVisibleHeight )
- {
- ellipsizeParameters.mEllipsizeBoundary.width = ellipsizeParameters.mLineWidth;
- }
-
- bool firstWord = true;
- bool lastWord = false;
-
- std::size_t wordCount = 0u;
-
- const bool isRightToLeftLayout = NULL != paragraphLayoutInfo.mRightToLeftLayout;
- TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayoutInfo.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayoutInfo.mWordsLayoutInfo;
-
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = wordsLayoutInfo.begin() + firstIndices.mWordIndex,
- endWordLayoutIt = wordsLayoutInfo.begin() + lastIndices.mWordIndex + 1u;
- wordLayoutIt != endWordLayoutIt;
- ++wordLayoutIt, ++wordCount )
- {
- TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
-
- if( wordCount == lastIndices.mWordIndex - firstIndices.mWordIndex )
- {
- lastWord = true;
- }
-
- const std::size_t firstCharacterIndex = firstWord ? firstIndices.mCharacterIndex : 0u;
- const std::size_t lastCharacterIndex = lastWord ? lastIndices.mCharacterIndex : wordLayoutInfo.mCharactersLayoutInfo.size() - 1u;
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin() + firstCharacterIndex,
- endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin() + lastCharacterIndex + 1u;
- characterLayoutIt != endCharacterLayoutIt;
- ++characterLayoutIt )
- {
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
-
- if( ellipsizeParameters.mEllipsizeLine )
- {
- // Calculates the character visibility and whether it needs to be replace by ellipsized text.
- CalculateVisibilityForEllipsize( layoutParameters,
- characterLayoutInfo,
- ellipsizeParameters,
- relayoutData );
-
- if( ellipsizeParameters.mCreateEllipsizedTextActors )
- {
- // Create ellipsize text-actors if the character needs to be replaced.
- CreateEllipsizeTextActor( ellipsizeParameters,
- relayoutData );
- }
- }
- else
- {
- if( ( TextView::EllipsizeEnd == layoutParameters.mExceedPolicy ) ||
- ( TextView::SplitEllipsizeEnd == layoutParameters.mExceedPolicy ))
- {
- if( !ellipsizeParameters.mIsLineHeightFullyVisible )
- {
- // Make characters invisible.
- characterLayoutInfo.mIsVisible = false;
- }
- }
- }
- } // end characters
- firstWord = false;
- } // end words
- } // end paragraphs
-}
-
-void SetTextVisible( TextView::RelayoutData& relayoutData )
-{
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(),
- endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphLayoutIt != endParagraphLayoutIt;
- ++paragraphLayoutIt )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
- std::size_t characterIndex = 0u;
-
- const bool isRightToLeftLayout = NULL != paragraphLayoutInfo.mRightToLeftLayout;
- TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayoutInfo.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayoutInfo.mWordsLayoutInfo;
-
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = wordsLayoutInfo.begin(),
- endWordLayoutIt = wordsLayoutInfo.end();
- wordLayoutIt != endWordLayoutIt;
- ++wordLayoutIt )
- {
- TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
- endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
- characterLayoutIt != endCharacterLayoutIt;
- ++characterLayoutIt, ++characterIndex )
- {
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
-
- characterLayoutInfo.mIsVisible = true;
- delete characterLayoutInfo.mGradientInfo;
- characterLayoutInfo.mGradientInfo = NULL;
- characterLayoutInfo.mColorAlpha = ( *( paragraphLayoutInfo.mTextStyles.Begin() + characterIndex ) )->GetTextColor().a;
- } // end characters
- } // end words
- } // end paragraphs
-
- // Updates the visibility for text-input..
- for( std::vector<Toolkit::TextView::CharacterLayoutInfo>::iterator it = relayoutData.mCharacterLayoutInfoTable.begin(),
- endIt = relayoutData.mCharacterLayoutInfoTable.end();
- it != endIt;
- ++it )
- {
- Toolkit::TextView::CharacterLayoutInfo& characterLayoutInfo( *it );
-
- characterLayoutInfo.mIsVisible = true;
- }
-}
-
-void UpdateVisibilityForFade( const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData )
-{
- RelayoutParameters relayoutParameters;
- FadeParameters fadeParameters;
-
- // Calculates the fade thresholds (from where the text starts to fade out). If any of the fade boundaries is zero, it sets a very small value just to avoid a zero division.
- fadeParameters.mRightFadeBoundary = static_cast<float>( visualParameters.mFadeBoundary.mRight );
- fadeParameters.mRightFadeBoundaryOffset = ( visualParameters.mFadeBoundary.mRight > 0u ? fadeParameters.mRightFadeBoundary : MINIMUM_FADE_BOUNDARY );
- fadeParameters.mRightFadeThreshold = relayoutData.mTextViewSize.width - fadeParameters.mRightFadeBoundary;
- fadeParameters.mRightFadeThresholdOffset = relayoutData.mTextViewSize.width - fadeParameters.mRightFadeBoundaryOffset;
- fadeParameters.mLeftFadeBoundary = static_cast<float>( visualParameters.mFadeBoundary.mLeft );
- fadeParameters.mLeftFadeBoundaryOffset = ( visualParameters.mFadeBoundary.mLeft > 0u ? fadeParameters.mLeftFadeBoundary : MINIMUM_FADE_BOUNDARY );
- fadeParameters.mLeftFadeThreshold = fadeParameters.mLeftFadeBoundary;
- fadeParameters.mLeftFadeThresholdOffset = fadeParameters.mLeftFadeBoundaryOffset;
- fadeParameters.mTopFadeBoundary = static_cast<float>( visualParameters.mFadeBoundary.mTop );
- fadeParameters.mTopFadeBoundaryOffset = ( visualParameters.mFadeBoundary.mTop > 0u ? fadeParameters.mTopFadeBoundary : MINIMUM_FADE_BOUNDARY );
- fadeParameters.mTopFadeThreshold = fadeParameters.mTopFadeBoundary;
- fadeParameters.mTopFadeThresholdOffset = fadeParameters.mTopFadeBoundaryOffset;
- fadeParameters.mBottomFadeBoundary = static_cast<float>( visualParameters.mFadeBoundary.mBottom );
- fadeParameters.mBottomFadeBoundaryOffset = ( visualParameters.mFadeBoundary.mBottom > 0u ? fadeParameters.mBottomFadeBoundary : MINIMUM_FADE_BOUNDARY );
- fadeParameters.mBottomFadeThreshold = relayoutData.mTextViewSize.height - fadeParameters.mBottomFadeBoundary;
- fadeParameters.mBottomFadeThresholdOffset = relayoutData.mTextViewSize.height - fadeParameters.mBottomFadeBoundaryOffset;
-
- // Calculates the fade out rect coeficients for the right, left, top and bottom sides of the text-view.
- fadeParameters.mRightAlphaCoeficients = CalculateRectParameters( Vector2( fadeParameters.mRightFadeThresholdOffset, 1.f ), Vector2( relayoutData.mTextViewSize.width, 0.f ) );
- fadeParameters.mLeftAlphaCoeficients = CalculateRectParameters( Vector2( fadeParameters.mLeftFadeThresholdOffset, 1.f ), Vector2( 0.f, 0.f ) );
- fadeParameters.mTopAlphaCoeficients = CalculateRectParameters( Vector2( fadeParameters.mTopFadeThresholdOffset, 1.f ), Vector2( 0.f, 0.f ) );
- fadeParameters.mBottomAlphaCoeficients = CalculateRectParameters( Vector2( fadeParameters.mBottomFadeThresholdOffset, 1.f ), Vector2( relayoutData.mTextViewSize.height, 0.f ) );
-
- // Traverses all characters and calculates the visibility.
-
- std::size_t infoTableCharacterIndex = 0u;
-
- relayoutParameters.mIndices.mParagraphIndex = 0u;
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(),
- endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphLayoutIt != endParagraphLayoutIt;
- ++paragraphLayoutIt, ++relayoutParameters.mIndices.mParagraphIndex )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
-
- std::size_t characterIndex = 0u;
- relayoutParameters.mIndices.mWordIndex = 0u;
-
- const bool isRightToLeftLayout = NULL != paragraphLayoutInfo.mRightToLeftLayout;
- TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayoutInfo.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayoutInfo.mWordsLayoutInfo;
-
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = wordsLayoutInfo.begin(),
- endWordLayoutIt = wordsLayoutInfo.end();
- wordLayoutIt != endWordLayoutIt;
- ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
- {
- TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
-
- relayoutParameters.mIsFirstCharacterOfWord = true;
- relayoutParameters.mWordSize = wordLayoutInfo.mSize;
- relayoutParameters.mIndices.mCharacterIndex = 0u;
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
- endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
- characterLayoutIt != endCharacterLayoutIt;
- ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex, ++infoTableCharacterIndex, ++characterIndex )
- {
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
-
- relayoutParameters.mIsVisible = true;
- fadeParameters.mIsPartiallyVisible = false;
-
- // Calculates the visibility for the current character.
- CalculateVisibilityForFade( layoutParameters,
- characterLayoutInfo,
- *( *( paragraphLayoutInfo.mTextStyles.Begin() + characterIndex ) ),
- relayoutParameters,
- fadeParameters,
- relayoutData );
-
- // Updates the visibility for text-input..
- std::vector<Toolkit::TextView::CharacterLayoutInfo>::iterator it = relayoutData.mCharacterLayoutInfoTable.begin() + relayoutData.mCharacterVisualToLogicalMap[infoTableCharacterIndex];
-
- Toolkit::TextView::CharacterLayoutInfo& characterLayoutTableInfo( *it );
-
- characterLayoutTableInfo.mIsVisible = relayoutParameters.mIsVisible;
-
- relayoutParameters.mIsFirstCharacterOfWord = false;
- } // end character
- } // end words
- } // end paragraphs
-}
-
-void UpdateVisibilityForEllipsize( const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData )
-{
- // TODO check ellipsis with rtl text.
-
- // Traverses the lines and checks which ones doesn't fit in the text-view's boundary.
- for( Toolkit::TextView::LineLayoutInfoContainer::const_iterator lineInfoIt = relayoutData.mLines.begin(), endLineInfoIt = relayoutData.mLines.end();
- lineInfoIt != endLineInfoIt;
- ++lineInfoIt )
- {
- const Toolkit::TextView::LineLayoutInfo& lineInfo( *lineInfoIt );
-
- // To check if a line fits in the text-view's boundary,
- // get the position of the first character is needed and do the test
- // with the line size.
-
- // An bearing offset may have been applied to the first character so it's needed to
- // get the start position of the line.
-
- // Some parameters used in the CalculateVisibilityForEllipsize() function.
- EllipsizeParameters ellipsizeParameters;
-
- // Retrieves the first index and the last index of the line.
- ellipsizeParameters.mFirstIndex = lineInfo.mCharacterGlobalIndex;
- ellipsizeParameters.mLastIndex = 0u;
- if( ( lineInfoIt + 1u ) != endLineInfoIt )
- {
- const Toolkit::TextView::LineLayoutInfo& nextLineInfo( *( lineInfoIt + 1u ) );
- ellipsizeParameters.mLastIndex = nextLineInfo.mCharacterGlobalIndex - 1u;
- }
- else
- {
- ellipsizeParameters.mLastIndex = relayoutData.mCharacterLayoutInfoTable.size() - 1u;
- }
-
- // Retrieves the first character of the line and build the position of the line with the bearing.
- const Toolkit::TextView::CharacterLayoutInfo& characterInfo = *( relayoutData.mCharacterLayoutInfoTable.begin() + ellipsizeParameters.mFirstIndex );
-
- // Calculates the bearing offset applied to the first character.
- const float bearingOffset = ( lineInfo.mSize.height - lineInfo.mAscender ) - characterInfo.mDescender;
-
- // Build the position of the line by removing the bearing offset from the first character's position.
- const Vector3 position( characterInfo.mPosition.x,
- characterInfo.mPosition.y + bearingOffset,
- characterInfo.mPosition.z );
-
- // Checks if the line needs to be ellipsized,
- ellipsizeParameters.mIsLineWidthFullyVisible = IsVisible( position,
- lineInfo.mSize,
- relayoutData.mTextViewSize,
- FULLY_VISIBLE_WIDTH );
-
- // If the exceed policy is EllipsizeEndOriginal it's enough to check
- // if the line fits in the width.
- ellipsizeParameters.mEllipsizeLine = !ellipsizeParameters.mIsLineWidthFullyVisible;
-
- // If the exceed policy is EllipsizeEnd, it's needed to check if the next line exceeds the text-view's height.
- // If the next line exceeds the text-view height then it's going to be invisible and current line needs to be ellipsized.
- ellipsizeParameters.mIsLineHeightFullyVisible = true;
- ellipsizeParameters.mIsNextLineFullyVisibleHeight = true;
- if( ( TextView::EllipsizeEnd == layoutParameters.mExceedPolicy ) ||
- ( TextView::SplitEllipsizeEnd == layoutParameters.mExceedPolicy ) )
- {
- // Need to check if there is lines which doesn't fit in the height.
-
- ellipsizeParameters.mIsLineHeightFullyVisible = IsVisible( position,
- lineInfo.mSize,
- relayoutData.mTextViewSize,
- FULLY_VISIBLE_HEIGHT );
-
- ellipsizeParameters.mEllipsizeLine = ellipsizeParameters.mEllipsizeLine && ellipsizeParameters.mIsLineHeightFullyVisible;
-
- if( ellipsizeParameters.mIsLineHeightFullyVisible && !ellipsizeParameters.mEllipsizeLine )
- {
- // Current line is not ellipsized.
- // Need to check if there is a next line and if it's not visible. If there is, current line needs to be ellipsized.
- Toolkit::TextView::LineLayoutInfoContainer::const_iterator nextLineInfoIt = lineInfoIt + 1u;
- if( nextLineInfoIt != endLineInfoIt )
- {
- // Retrives the position of the first character of the line and remove
- // the bearing offset to build to build the position of the line.
- const Toolkit::TextView::LineLayoutInfo& nextLineInfo( *nextLineInfoIt );
- const Toolkit::TextView::CharacterLayoutInfo& characterInfo = *( relayoutData.mCharacterLayoutInfoTable.begin() + nextLineInfo.mCharacterGlobalIndex );
-
- const float bearingOffset = ( ( lineInfo.mSize.height - lineInfo.mAscender ) - characterInfo.mDescender ) * relayoutData.mShrinkFactor;
-
- const Vector3 position( characterInfo.mPosition.x,
- characterInfo.mPosition.y + bearingOffset,
- characterInfo.mPosition.z );
-
- ellipsizeParameters.mIsNextLineFullyVisibleHeight = IsVisible( position,
- nextLineInfo.mSize,
- relayoutData.mTextViewSize,
- FULLY_VISIBLE_HEIGHT );
-
- // If the next line is not visible, current line have to be ellipsized.
- ellipsizeParameters.mEllipsizeLine = !ellipsizeParameters.mIsNextLineFullyVisibleHeight;
- }
- }
- }
-
- if( !ellipsizeParameters.mIsNextLineFullyVisibleHeight )
- {
- ellipsizeParameters.mLineWidth = position.x + lineInfo.mSize.width - relayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo.mSize.width;
- }
-
- // Sets the line descender.
- ellipsizeParameters.mLineDescender = lineInfo.mSize.height - lineInfo.mAscender;
-
- // At this point, ellipsizeLine distinguish if a piece of line have to be ellipsized or not.
- EllipsizeLine( layoutParameters, ellipsizeParameters, relayoutData );
- }
-}
-
-void UpdateVisibility( const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData )
-{
- switch( layoutParameters.mExceedPolicy )
- {
- case TextView::FadeOriginal:
- case TextView::OriginalFade:
- case TextView::Fade:
- case TextView::SplitFade: // Fall through
- {
- UpdateVisibilityForFade( layoutParameters,
- visualParameters,
- relayoutData );
- break;
- }
- case TextView::EllipsizeEndOriginal:
- case TextView::SplitEllipsizeEnd:
- case TextView::EllipsizeEnd: // Fall through
- {
- // Set first all characters to visible as UpdateVisibilityForEllipsize() doesn't traverse all of them.
- SetTextVisible( relayoutData );
-
- UpdateVisibilityForEllipsize( layoutParameters,
- visualParameters,
- relayoutData );
- break;
- }
- default:
- {
- SetTextVisible( relayoutData );
- break;
- }
- }
-}
-
-/**
- * Creates an image actor for the emoticon.
- *
- * @param[in] visualParameters Some visual parameters (fade, sort modifier and blending).
- * @param[in,out] characterLayout Layout info for the character.
- * @param[in] character The character.
- */
-void CreateEmoticon( const TextView::VisualParameters& visualParameters,
- TextViewProcessor::CharacterLayoutInfo& characterLayout,
- const Character& character )
-{
- // The character is an emoticon.
- ImageActor imageActor = ImageActor::DownCast( characterLayout.mGlyphActor );
- if( !imageActor )
- {
- imageActor = ImageActor::New();
-
- GlyphImage image = GlyphImage::New( character );
-
- if( image )
- {
- imageActor.SetImage( image );
- }
- }
-
- imageActor.SetPosition( Vector3( characterLayout.mPosition.x + characterLayout.mOffset.x,
- characterLayout.mPosition.y + characterLayout.mOffset.y,
- characterLayout.mPosition.z ) );
- imageActor.SetSize( characterLayout.mSize );
-
- // Sets the sort modifier value.
- imageActor.SetSortModifier( visualParameters.mSortModifier );
-
- characterLayout.mGlyphActor = imageActor;
-}
-
-/**
- * Creates text-actors for the given text.
- *
- * @param[in] visualParameters Some visual parameters (fade, sort modifier and blending).
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info.
- * @param[in,out] paragraph Layout info for the paragraph.
- * @param[in,out] wordLayout Layout info for the word.
- * @param[in,out] characterLayout Layout info for the character.
- * @param[in] character The character.
- * @param[in] style The character's style.
- * @param[in,out] currentTextActorInfo Temporary stores the text-actor's info to be set.
- * @param[in,out] createGlyphActors Whether to initialize renderable-actor handles.
- * @param[in,out] textActorCreated Whether a text-actor
- */
-void CreateTextActor( const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData,
- const TextViewProcessor::ParagraphLayoutInfo& paragraph,
- TextViewProcessor::WordLayoutInfo& wordLayout,
- TextViewProcessor::CharacterLayoutInfo& characterLayout,
- const Character& character,
- const TextStyle& style,
- CurrentTextActorInfo& currentTextActorInfo,
- bool createGlyphActors,
- bool& textActorCreated )
-{
- textActorCreated = false;
-
- // Set the text-actor for the current traversed text.
- if( currentTextActorInfo.textActor )
- {
- if( ( NULL != currentTextActorInfo.characterLayout ) &&
- currentTextActorInfo.characterLayout->mSetText )
- {
- currentTextActorInfo.textActor.SetText( currentTextActorInfo.text );
- currentTextActorInfo.characterLayout->mSetText = false;
- }
- currentTextActorInfo.textActor.SetPosition( currentTextActorInfo.position );
- currentTextActorInfo.textActor.SetSize( currentTextActorInfo.size );
-
- SetVisualParameters( currentTextActorInfo,
- visualParameters,
- relayoutData,
- paragraph.mSize.height );
- }
-
- float rightToLeftOffset = 0.f;
- if( character.IsWhiteSpace() )
- {
- // In left to right text, a word never starts with a white space but
- // it may happen in right to left text as the text is reversed.
- // The text alignment and justification offset is calculated without this white space.
- // It causes a missalignment which can be corrected by removing the size of the white space.
- rightToLeftOffset = characterLayout.mSize.width * relayoutData.mShrinkFactor;
- }
-
- // Whether this word is not a white space or if it is, it is underlined.
- // Don't want to create text-actors for white spaces unless they are underlined.
- bool isNotWhiteSpace = ( TextViewProcessor::NoSeparator == wordLayout.mType ) || ( ( TextViewProcessor::WordSeparator == wordLayout.mType ) && style.IsUnderlineEnabled() );
-
- if( isNotWhiteSpace )
- {
- currentTextActorInfo.text = Text( character );
- }
- else
- {
- currentTextActorInfo.text = Text();
- }
- currentTextActorInfo.position = Vector3( characterLayout.mPosition.x + characterLayout.mOffset.x - rightToLeftOffset,
- characterLayout.mPosition.y + characterLayout.mOffset.y,
- characterLayout.mPosition.z );
- currentTextActorInfo.size = characterLayout.mSize * relayoutData.mShrinkFactor;
-
- currentTextActorInfo.color = style.GetTextColor();
- currentTextActorInfo.color.a = characterLayout.mColorAlpha;
-
- TextActor textActor = TextActor::DownCast( characterLayout.mGlyphActor );
-
- if( createGlyphActors && isNotWhiteSpace )
- {
- textActorCreated = true;
- if( textActor )
- {
- // Try to reuse first the text-actor of this character.
- textActor.SetTextStyle( style );
- }
- else
- {
- // If there is no text-actor, try to retrieve one from the cache.
- textActor = relayoutData.mTextActorCache.RetrieveTextActor();
-
- // If still there is no text-actor, create one.
- if( !textActor )
- {
- TextActorParameters parameters( style, TextActorParameters::FONT_DETECTION_OFF );
- textActor = TextActor::New( Text(), parameters );
- }
- else
- {
- textActor.SetTextStyle( style );
- }
- }
- characterLayout.mSetText = true;
- currentTextActorInfo.characterLayout = &characterLayout;
-
- characterLayout.mGlyphActor = textActor;
- }
-
- // Update the current text-actor.
- currentTextActorInfo.textActor = textActor;
-}
-
-/**
- * Traverses the whole paragraph initializating renderable-actor handles and updating them with the new size and position.
- *
- * @param[in] visualParameters Some visual parameters (fade, sort modifier and blending).
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info.
- * @param[in,out] paragraph Layout info for the paragraph.
- * @param[in,out] characterGlobalIndex Index to the character within the whole text.
- * @param[in,out] lineLayoutInfoIndex Index to the table of lines.
- * @param[in,out] createGlyphActors Whether to initialize renderable-actor handles.
- */
-void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData,
- TextViewProcessor::ParagraphLayoutInfo& paragraphLayout,
- std::size_t& characterGlobalIndex,
- std::size_t& lineLayoutInfoIndex,
- bool createGlyphActors )
-{
- CurrentTextActorInfo currentTextActorInfo;
- currentTextActorInfo.characterLayout = NULL;
-
- const std::size_t lineLayoutInfoSize = relayoutData.mLines.size(); // Number of lines.
- bool lineLayoutEnd = false; // Whether lineLayoutInfoIndex points at the last line.
- bool textActorCreated = false; // Whether a text actor has been created for this the current group of characters traversed.
-
- TextStyle currentStyle; // style for the current text-actor.
-
- TextViewProcessor::GradientInfo* currentGradientInfo = NULL; // gradient color for the current text-actor.
- // start point for the current text-actor.
- // end point for the current text-actor.
-
- bool currentIsColorGlyph = false; // Whether current glyph is an emoticon.
-
- std::vector<TextActor> textActorsToRemove; // Keep a vector of text-actors to be included into the cache.
-
- // Retrieve the layout info to traverse. If there is right to left text it retrieves the right to left layout.
- const bool isRightToLeftLayout = NULL != paragraphLayout.mRightToLeftLayout;
-
- TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayout.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayout.mWordsLayoutInfo;
- Text& text = isRightToLeftLayout ? paragraphLayout.mRightToLeftLayout->mText : paragraphLayout.mText;
- Vector<TextStyle*>& textStyles = isRightToLeftLayout ? paragraphLayout.mRightToLeftLayout->mTextStyles : paragraphLayout.mTextStyles;
-
- // In case the previous right to left layout has been cleared, all text-actors have been removed as well. If this bool is set to true, text-actors will be created again.
- createGlyphActors = createGlyphActors || ( ( isRightToLeftLayout ) ? paragraphLayout.mRightToLeftLayout->mPreviousLayoutCleared : false );
-
- std::size_t characterParagraphIndex = 0u; // Index to the character (within the paragraph).
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = wordsLayoutInfo.begin(), wordEndIt = wordsLayoutInfo.end();
- wordIt != wordEndIt;
- ++wordIt )
- {
- TextViewProcessor::WordLayoutInfo& wordLayout( *wordIt );
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterIt = wordLayout.mCharactersLayoutInfo.begin(), characterEndIt = wordLayout.mCharactersLayoutInfo.end();
- characterIt != characterEndIt;
- ++characterIt )
- {
- TextViewProcessor::CharacterLayoutInfo& characterLayout( *characterIt );
-
- // Check if there is a new line.
- const bool newLine = !lineLayoutEnd && ( characterGlobalIndex == relayoutData.mLines[lineLayoutInfoIndex].mCharacterGlobalIndex );
-
- if( newLine )
- {
- // Point to the next line.
- ++lineLayoutInfoIndex;
- if( lineLayoutInfoIndex >= lineLayoutInfoSize )
- {
- // Arrived at last line.
- lineLayoutEnd = true; // Avoids access out of bounds in the relayoutData.mLines vector.
- }
- textActorCreated = false;
- }
-
- // Do not create a glyph-actor if there is no text.
- const Character character = text[characterParagraphIndex];
- const TextStyle& style = *( *( textStyles.Begin() + characterParagraphIndex ) );
-
- // Check if the character has the same gradient info than the current one.
- bool differentGradientInfo = false;
- if( characterLayout.mGradientInfo && currentGradientInfo )
- {
- differentGradientInfo = ( characterLayout.mGradientInfo->mGradientColor != currentGradientInfo->mGradientColor ) ||
- ( characterLayout.mGradientInfo->mStartPoint != currentGradientInfo->mStartPoint ) ||
- ( characterLayout.mGradientInfo->mEndPoint != currentGradientInfo->mEndPoint );
- }
- else if( ( NULL != currentGradientInfo ) || ( NULL != characterLayout.mGradientInfo ) )
- {
- differentGradientInfo = true;
- }
-
- if( ( createGlyphActors && !textActorCreated ) ||
- characterLayout.mIsColorGlyph ||
- differentGradientInfo ||
- ( characterLayout.mIsColorGlyph != currentIsColorGlyph ) ||
- ( style != currentStyle ) )
- {
- characterLayout.mSetText = false;
- characterLayout.mSetStyle = false;
-
- if( characterLayout.mIsColorGlyph )
- {
- CreateEmoticon( visualParameters,
- characterLayout,
- character );
-
- characterLayout.mGlyphActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
- characterLayout.mGlyphActor.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
- }
- else
- {
- // There is a new style or a new line.
-
- CreateTextActor( visualParameters,
- relayoutData,
- paragraphLayout,
- wordLayout,
- characterLayout,
- character,
- style,
- currentTextActorInfo,
- createGlyphActors,
- textActorCreated );
-
- if( textActorCreated )
- {
- characterLayout.mGlyphActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
- characterLayout.mGlyphActor.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
- }
- }
-
- // Update style to be checked with next characters.
- currentStyle = style;
- currentGradientInfo = characterLayout.mGradientInfo;
- currentIsColorGlyph = characterLayout.mIsColorGlyph;
- }
- else
- {
- DALI_ASSERT_DEBUG( !characterLayout.mIsColorGlyph && "TextViewProcessor::InitializeTextActorInfo. An image-actor doesn't store more than one emoticon." );
-
- // Same style than previous one.
-
- // Add the character to the current text-actor and update the size.
- if( characterLayout.mIsVisible && ( TextViewProcessor::ParagraphSeparator != wordLayout.mType ) )
- {
- currentTextActorInfo.text.Append( character );
-
- currentTextActorInfo.position.y = std::min( currentTextActorInfo.position.y, ( characterLayout.mPosition.y + characterLayout.mOffset.y ) );
- currentTextActorInfo.size.width += characterLayout.mSize.width * relayoutData.mShrinkFactor;
- currentTextActorInfo.size.height = std::max( currentTextActorInfo.size.height, characterLayout.mSize.height * relayoutData.mShrinkFactor );
- }
- }
-
- if( ( createGlyphActors ) &&
- !characterLayout.mIsColorGlyph &&
- !textActorCreated )
- {
- TextActor textActor = TextActor::DownCast( characterLayout.mGlyphActor );
- if( textActor )
- {
- // There is a previously created text-actor for this character.
- // If this character has another one put it into the cache.
- textActor.SetText( "" );
- textActorsToRemove.push_back( textActor );
- }
-
- if( characterLayout.mGlyphActor )
- {
- characterLayout.mGlyphActor.Reset();
- }
- }
- ++characterGlobalIndex;
- ++characterParagraphIndex;
- } // characters
- } // words
-
- if( !currentTextActorInfo.text.IsEmpty() )
- {
- if( currentTextActorInfo.textActor )
- {
- if( ( NULL != currentTextActorInfo.characterLayout ) &&
- currentTextActorInfo.characterLayout->mSetText )
- {
- currentTextActorInfo.textActor.SetText( currentTextActorInfo.text );
- currentTextActorInfo.characterLayout->mSetText = false;
- }
- currentTextActorInfo.textActor.SetPosition( currentTextActorInfo.position );
- currentTextActorInfo.textActor.SetSize( currentTextActorInfo.size );
-
- SetVisualParameters( currentTextActorInfo,
- visualParameters,
- relayoutData,
- paragraphLayout.mSize.height );
- }
- }
-
- // Insert the spare text-actors into the cache.
- relayoutData.mTextActorCache.InsertTextActors( textActorsToRemove );
-}
-
-void UpdateTextActorInfo( const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData,
- bool createGlyphActors )
-{
- if( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
- {
- // nothing to do if there is no paragraphs.
- return;
- }
-
- std::size_t characterGlobalIndex = 0u; // Index to the global character (within the whole text).
- std::size_t lineLayoutInfoIndex = 0u; // Index to the line info.
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(), paragraphEndIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphIt != paragraphEndIt;
- ++paragraphIt )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraph( *paragraphIt );
-
- UpdateTextActorInfoForParagraph( visualParameters,
- relayoutData,
- paragraph,
- characterGlobalIndex,
- lineLayoutInfoIndex,
- createGlyphActors );
- } // paragraphs
-
- // Set visual parameters for ellipsis renderable actors.
- for( std::vector<RenderableActor>::iterator it = relayoutData.mEllipsizedGlyphActors.begin(),
- endIt = relayoutData.mEllipsizedGlyphActors.end();
- it != endIt;
- ++it )
- {
- RenderableActor glyphActor = ( *it );
-
- glyphActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
- glyphActor.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
-
- // Sets the sort modifier value.
- glyphActor.SetSortModifier( visualParameters.mSortModifier );
-
- // Enables or disables the blending.
- glyphActor.SetBlendMode( !visualParameters.mSnapshotModeEnabled ? BlendingMode::ON : BlendingMode::OFF );
- }
-}
-
-void CalculateUnderlineInfo( TextView::RelayoutData& relayoutData, TextViewRelayout::TextUnderlineStatus& textUnderlineStatus )
-{
- // Traverse the whole text to find all groups of consecutive underlined characters in the same line.
- //
- // Note that relayoutData.mTextLayoutInfo contains layout info per paragraph but these paragraphs are the result of split the whole text every time a '\n' is found.
- // According with the layout option, one of this paragraphs could be laid-out in more than one line.
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(), paragraphEndIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphIt != paragraphEndIt;
- ++paragraphIt )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraph( *paragraphIt );
-
- std::size_t characterIndex = 0u;
-
- const bool isRightToLeftLayout = NULL != paragraph.mRightToLeftLayout;
- TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraph.mRightToLeftLayout->mWordsLayoutInfo : paragraph.mWordsLayoutInfo;
-
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = wordsLayoutInfo.begin(), wordEndIt = wordsLayoutInfo.end();
- wordIt != wordEndIt;
- ++wordIt )
- {
- TextViewProcessor::WordLayoutInfo& word( *wordIt );
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterIt = word.mCharactersLayoutInfo.begin(), characterEndIt = word.mCharactersLayoutInfo.end();
- characterIt != characterEndIt;
- ++characterIt, ++characterIndex )
- {
- TextViewProcessor::CharacterLayoutInfo& character( *characterIt );
- const TextStyle& style = *( *( paragraph.mTextStyles.Begin() + characterIndex ) );
-
- // Check if current character is the first of a new line
- const bool isNewLine = ( textUnderlineStatus.mLineGlobalIndex < relayoutData.mLines.size() ) &&
- ( textUnderlineStatus.mCharacterGlobalIndex == ( *( relayoutData.mLines.begin() + textUnderlineStatus.mLineGlobalIndex ) ).mCharacterGlobalIndex );
- if( isNewLine )
- {
- ++textUnderlineStatus.mLineGlobalIndex; // If it's a new line, point to the next one.
- }
-
- if( style.IsUnderlineEnabled() )
- {
- if( !textUnderlineStatus.mCurrentUnderlineStatus || // Current character is underlined but previous one it wasn't.
- isNewLine ) // Current character is underlined and is the first of current line.
- {
- // Create a new underline info for the current underlined characters.
- UnderlineInfo underlineInfo;
- underlineInfo.mMaxHeight = character.mSize.height;
- underlineInfo.mMaxThickness = character.mUnderlineThickness;
- underlineInfo.mPosition = character.mUnderlinePosition;
-
- textUnderlineStatus.mUnderlineInfo.push_back( underlineInfo );
-
- textUnderlineStatus.mCurrentUnderlineStatus = true; // Set the current text is underlined.
- }
- else
- {
- // Retrieve last underline info and update it if current underline thickness is bigger.
- UnderlineInfo& underlineInfo( *( textUnderlineStatus.mUnderlineInfo.end() - 1u ) );
-
- underlineInfo.mMaxHeight = std::max( underlineInfo.mMaxHeight, character.mSize.height );
-
- if( character.mUnderlineThickness > underlineInfo.mMaxThickness )
- {
- underlineInfo.mMaxThickness = character.mUnderlineThickness;
- underlineInfo.mPosition = character.mUnderlinePosition;
- }
- }
- }
- else
- {
- textUnderlineStatus.mCurrentUnderlineStatus = false;
- }
-
- ++textUnderlineStatus.mCharacterGlobalIndex;
- } // end characters.
- } // end words.
- } // end paragraphs.
-}
-
-void SetUnderlineInfo( TextView::RelayoutData& relayoutData )
-{
- // Stores for each group of consecutive underlined characters in each line its maximum thicknes, its position of that thickness and the maximum character's height.
- TextViewRelayout::TextUnderlineStatus textUnderlineStatus;
-
- // Traverse the whole text to find all groups of consecutive underlined characters in the same line.
- CalculateUnderlineInfo( relayoutData, textUnderlineStatus );
-
- if( textUnderlineStatus.mUnderlineInfo.empty() )
- {
- // There is no underlined text. Just exit.
- return;
- }
-
- // At this point textUnderlineStatus.mUnderlineInfo has for each group of consecutive underlined characters their maximum thickness, position and maximum height.
- // Traverse the whole text and set the previously stored underline info in the text style.
-
- std::vector<UnderlineInfo>::const_iterator underlineInfoIt = textUnderlineStatus.mUnderlineInfo.begin();
- std::vector<UnderlineInfo>::const_iterator underlineInfoEndIt = textUnderlineStatus.mUnderlineInfo.end();
-
- UnderlineInfo underlineInfo;
-
- if( underlineInfoIt < underlineInfoEndIt )
- {
- underlineInfo = ( *underlineInfoIt );
- }
-
- // Whether current text is underlined.
- textUnderlineStatus.mCurrentUnderlineStatus = false;
- textUnderlineStatus.mCharacterGlobalIndex = 0u;
- textUnderlineStatus.mLineGlobalIndex = 0u;
-
- float currentLineHeight = 0.f;
- float currentLineAscender = 0.f;
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(), paragraphEndIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphIt != paragraphEndIt;
- ++paragraphIt )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraph( *paragraphIt );
- std::size_t characterIndex = 0u;
-
- const bool isRightToLeftLayout = NULL != paragraph.mRightToLeftLayout;
- TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraph.mRightToLeftLayout->mWordsLayoutInfo : paragraph.mWordsLayoutInfo;
-
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = wordsLayoutInfo.begin(), wordEndIt = wordsLayoutInfo.end();
- wordIt != wordEndIt;
- ++wordIt )
- {
- TextViewProcessor::WordLayoutInfo& word( *wordIt );
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterIt = word.mCharactersLayoutInfo.begin(), characterEndIt = word.mCharactersLayoutInfo.end();
- characterIt != characterEndIt;
- ++characterIt, ++characterIndex )
- {
- TextViewProcessor::CharacterLayoutInfo& character( *characterIt );
- TextStyle& style = *( *( paragraph.mTextStyles.Begin() + characterIndex ) );
-
- // Check if current character is the first of a new line
-
- bool isNewLine = false;
-
- if( textUnderlineStatus.mLineGlobalIndex < relayoutData.mLines.size() )
- {
- const Toolkit::TextView::LineLayoutInfo& lineLayoutInfo( *( relayoutData.mLines.begin() + textUnderlineStatus.mLineGlobalIndex ) );
- isNewLine = ( textUnderlineStatus.mCharacterGlobalIndex == lineLayoutInfo.mCharacterGlobalIndex );
-
- if( isNewLine )
- {
- currentLineHeight = lineLayoutInfo.mSize.height;
- currentLineAscender = lineLayoutInfo.mAscender;
- ++textUnderlineStatus.mLineGlobalIndex; // If it's a new line, point to the next one.
- }
- }
-
- if( style.IsUnderlineEnabled() )
- {
- if( textUnderlineStatus.mCurrentUnderlineStatus )
- {
- if( isNewLine )
- {
- // Retrieves the thickness and position for the next piece of underlined text.
- if( underlineInfoIt < underlineInfoEndIt )
- {
- ++underlineInfoIt;
- if( underlineInfoIt < underlineInfoEndIt )
- {
- underlineInfo = *underlineInfoIt;
- }
- }
- }
- }
-
- textUnderlineStatus.mCurrentUnderlineStatus = true;
-
- // Before setting the position it needs to be adjusted to match the base line.
- const float bearingOffset = ( currentLineHeight - currentLineAscender ) - ( character.mSize.height - character.mAscender );
- const float positionOffset = ( underlineInfo.mMaxHeight - character.mSize.height ) - bearingOffset;
-
- // Sets the underline's parameters.
- style.SetUnderline( true, underlineInfo.mMaxThickness, underlineInfo.mPosition - positionOffset );
-
- // Mark the character to be set the new style into the text-actor.
- character.mSetStyle = true;
- }
- else
- {
- if( textUnderlineStatus.mCurrentUnderlineStatus )
- {
- textUnderlineStatus.mCurrentUnderlineStatus = false;
-
- // Retrieves the thickness and position for the next piece of underlined text.
- if( underlineInfoIt < underlineInfoEndIt )
- {
- ++underlineInfoIt;
- if( underlineInfoIt < underlineInfoEndIt )
- {
- underlineInfo = *underlineInfoIt;
- }
- }
- }
- }
-
- ++textUnderlineStatus.mCharacterGlobalIndex;
- } // end of characters.
- } // end of word.
- } // end of paragraphs.
-}
-
-void RemoveGlyphActors( Actor textView,
- const std::vector<RenderableActor>& glyphActors )
-{
- // Removes previously inserted renderable-actors.
- // The SplitByNewLineChar::Relayout(), SplitByWord::Relayout() and SplitByChar::Relayout() functions add
- // renderable-actors to the text-view. A handle to these renderable-actors are stored and passed to this function
- // in order to remove 'only' renderable-actors added by these functions.
- // Any other actor added by a programmer or application won't be removed.
-
- for( std::vector<RenderableActor>::const_reverse_iterator it = glyphActors.rbegin(), endIt = glyphActors.rend(); it != endIt; ++it )
- {
- textView.Remove( *it );
- }
-}
-
-void InsertToTextView( Actor textView,
- TextView::RelayoutData& relayoutData )
-{
- // Add text-actors to the text-view.
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(),
- endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphLayoutIt != endParagraphLayoutIt;
- ++paragraphLayoutIt )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
-
- // Retrieve the layout info to traverse. If there is right to left text it retrieves the right to left layout.
- const bool isRightToLeftLayout = NULL != paragraphLayoutInfo.mRightToLeftLayout;
- TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayoutInfo.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayoutInfo.mWordsLayoutInfo;
-
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = wordsLayoutInfo.begin(),
- endWordLayoutIt = wordsLayoutInfo.end();
- wordLayoutIt != endWordLayoutIt;
- ++wordLayoutIt )
- {
- TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
- endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
- characterLayoutIt != endCharacterLayoutIt;
- ++characterLayoutIt )
- {
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
-
- if( characterLayoutInfo.mIsVisible && characterLayoutInfo.mGlyphActor ) // White spaces and '\n' characters doesn't have a text-actor.
- {
- //Add to the text-view.
- textView.Add( characterLayoutInfo.mGlyphActor );
- relayoutData.mGlyphActors.push_back( characterLayoutInfo.mGlyphActor );
- }
- } // end character
- } // end words
- } // end paragraphs
-
- for( std::vector<RenderableActor>::iterator it = relayoutData.mEllipsizedGlyphActors.begin(),
- endIt = relayoutData.mEllipsizedGlyphActors.end();
- it != endIt;
- ++it )
- {
- RenderableActor glyphActor = ( *it );
-
- //Add to the text-view.
- textView.Add( glyphActor );
- relayoutData.mGlyphActors.push_back( glyphActor );
- }
- relayoutData.mEllipsizedGlyphActors.clear();
-}
-
-RenderableActor CreateGlyphActor( const Text& text, const TextStyle& style, TextActorCache& cache )
-{
- TextActor textActor = cache.RetrieveTextActor();
-
- if( textActor )
- {
- // Update the text-actor.
- textActor.SetText( text );
- textActor.SetTextStyle( style );
- }
- else
- {
- // The text-actor cache is empty. Create a new one.
- TextActorParameters parameters( style, TextActorParameters::FONT_DETECTION_OFF );
- textActor = TextActor::New( text, parameters );
- }
-
- return textActor;
-}
-
-} // namespace TextViewRelayout
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_RELAYOUT_UTILITIES_H__
-#define __DALI_TOOLKIT_INTERNAL_RELAYOUT_UTILITIES_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/alignment/alignment.h>
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-//Forward declarations.
-class TextActorCache;
-
-namespace TextViewRelayout
-{
-
-extern const float MINIMUM_FADE_BOUNDARY; // When the fade boundary is the same as the text-view boundary, this constant reduces it in order to avoid a zero division.
-
-/**
- * Define how to wrap a paragraph in lines.
- */
-enum HorizontalWrapType
-{
- WrapByCharacter, ///< Wrap the paragraph per character (It may split a word in two).
- WrapByWord, ///< Wrap the paragraph by word.
- WrapByWordAndSplit, ///< Wrap the paragraph by word and split a word if it doesn't fit.
- WrapByParagraphCharacter, ///< Wrap the paragraph when a '\n' is found.
- WrapByParagraphCharacterAndSplit ///< Wrap the paragraph when a '\n' is found and split if it doesn't fit.
-};
-
-/**
- * Different types of visibility tests (text-actor - text-view).
- */
-enum VisibilityTestType
-{
- FULLY_VISIBLE, ///< The text-actor is completely inside the text-view.
- FULLY_VISIBLE_WIDTH, ///< The text-actor is completely between the right and the left boundaries of the text-view.
- FULLY_VISIBLE_HEIGHT, ///< The text-actor is completely between the top and the bottom boundaries of the text-view.
- PARTIALLY_VISIBLE, ///< The text-actor is partially inside the text-view.
- PARTIALLY_VISIBLE_WIDTH, ///< The text-actor is partially inside the width of the text-view. It may be completely above and bellow the top and bottom boundaries of the text-view.
- PARTIALLY_VISIBLE_HEIGHT ///< The text-actor is partially inside the height of the text-view. It may be completely on the left and on the right the left and right boundaries of the text-view.
-};
-
-/**
- * Temporary parameters used in the relayout process.
- */
-struct RelayoutParameters
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their defaults.
- */
- RelayoutParameters();
-
- /**
- * Empty destructor.
- *
- * @note Added to increase coverage.
- */
- ~RelayoutParameters();
-
- Vector3 mPositionOffset; ///< Offset (position.x + size.width, position.y, position.z) of the previous text-actor.
- Size mParagraphSize; ///< Current paragraphs's size.
- Size mWordSize; ///< Current word's size.
- Size mCharacterSize; ///< Current character's size.
- TextViewProcessor::TextInfoIndices mIndices; ///< Current indices to paragraph, word and character.
- std::size_t mCharacterGlobalIndex; ///< Index to a single character within the whole text.
- bool mIsFirstCharacter:1; ///< Whether is the first character of the whole text.
- bool mIsFirstCharacterOfWord:1; ///< Whether is the first character of the word.
- bool mIsNewLine:1; ///< Whether the current character is the first character of a new line.
- bool mIsNewParagraphCharacter:1; ///< Whether the current character is a new paragraph character.
- bool mIsWhiteSpace:1; ///< Whether the current character is a white space.
- bool mIsVisible:1; ///< Whether the current character is visible.
-};
-
-/**
- * Parameters used to calculate the gradient of text-actors when fading is enabled.
- */
-struct FadeParameters
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their defaults.
- */
- FadeParameters();
-
- /**
- * Empty destructor.
- *
- * @note Added to increase coverage.
- */
- ~FadeParameters();
-
- float mRightFadeBoundary; ///< Distance from the right edge of the text-view to the right edge of the fade boundary.
- float mRightFadeThreshold; ///< Point from where fade out starts (by right edge).
- float mRightFadeBoundaryOffset; ///< Same as above plus an offset if the value is zero. Used to avoid a zero division.
- float mRightFadeThresholdOffset; ///< Same as above plus an offset if the value is zero. Used to avoid a zero division.
- Vector2 mRightAlphaCoeficients; ///< The fade out rect coeficients for the right side of the text-view.
- float mLeftFadeBoundary; ///< Distance from the left edge of the text-view to the left edge of the fade boundary.
- float mLeftFadeThreshold; ///< Point from where fade out starts (by left edge).
- float mLeftFadeBoundaryOffset; ///< Same as above plus an offset if the value is zero. Used to avoid a zero division.
- float mLeftFadeThresholdOffset; ///< Same as above plus an offset if the value is zero. Used to avoid a zero division.
- Vector2 mLeftAlphaCoeficients; ///< The fade out rect coeficients for the left side of the text-view.
- float mTopFadeBoundary; ///< Distance from the top edge of the text-view to the top edge of the fade boundary.
- float mTopFadeThreshold; ///< Point from where fade out starts (by top edge).
- float mTopFadeBoundaryOffset; ///< Same as above plus an offset if the value is zero. Used to avoid a zero division.
- float mTopFadeThresholdOffset; ///< Same as above plus an offset if the value is zero. Used to avoid a zero division.
- Vector2 mTopAlphaCoeficients; ///< The fade out rect coeficients for the top side of the text-view.
- float mBottomFadeBoundary; ///< Distance from the bottom edge of the text-view to the bottom edge of the fade boundary.
- float mBottomFadeThreshold; ///< Point from where fade out starts (by bottom edge).
- float mBottomFadeBoundaryOffset; ///< Same as above plus an offset if the value is zero. Used to avoid a zero division.
- float mBottomFadeThresholdOffset; ///< Same as above plus an offset if the value is zero. Used to avoid a zero division.
- Vector2 mBottomAlphaCoeficients; ///< The fade out rect coeficients for the bottom side of the text-view.
- bool mIsPartiallyVisible:1; ///< Whether the current character is partially visible.
-};
-
-/**
- * Parameters used to calculate the ellipsize.
- */
-struct EllipsizeParameters
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their defaults.
- */
- EllipsizeParameters();
-
- /**
- * Empty destructor.
- *
- * @note Added to increase coverage.
- */
- ~EllipsizeParameters();
-
- Vector3 mPosition; ///< Position of the first character of the ellipsize text.
- float mLineDescender; ///< Distance from the base line to the bottom.
- float mLineWidth; ///< Current line's width.
- Size mEllipsizeBoundary; ///< Where to start to ellipsize a line.
- std::size_t mFirstIndex; ///< Global index within the whole text of the first character of the line.
- std::size_t mLastIndex; ///< Global index within the whole text of the last character of the line.
- bool mEllipsizeLine:1; ///< Whether current line must be ellipsized.
- bool mIsLineWidthFullyVisible:1; ///< Whether current line fits in text-view's width.
- bool mIsLineHeightFullyVisible:1; ///< Whether current line fits in text-view's height.
- bool mIsNextLineFullyVisibleHeight:1; ///< Whether next line fits in text-view's height.
- bool mCreateEllipsizedTextActors:1; ///< Whether to create text-actors for the ellipsized text.
- bool mLineFits:1; ///< Whether the current line fits in the boundary of the text-view.
- bool mWordFits:1; ///< Whether the current word fits in the boundary of the text-view.
-};
-
-/**
- * Stores underline info for a group of consecutive characters in the same line.
- */
-struct UnderlineInfo
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their defaults.
- */
- UnderlineInfo();
-
- /**
- * Empty destructor.
- *
- * @note Added to increase coverage.
- */
- ~UnderlineInfo();
-
- float mMaxHeight; ///< The maximum height.
- float mMaxThickness; ///< The maximum underline's thickness.
- float mPosition; ///< The underline's position of the character with the maximum underline's thickness.
-};
-
-/**
- * Stores underline info for each group of consecutive underlined characters.
- * It also stores some status used when traversing the whole text.
- */
-struct TextUnderlineStatus
-{
- /**
- * Default constructor.
- *
- * Initializes each member to its default.
- */
- TextUnderlineStatus();
-
- /**
- * Empty destructor.
- *
- * @note Added to increase coverage.
- */
- ~TextUnderlineStatus();
-
- std::vector<UnderlineInfo> mUnderlineInfo; ///< Underline info for each group of consecutive underlined characters.
- std::size_t mCharacterGlobalIndex; ///< Global index (within the whole text) to current character.
- std::size_t mLineGlobalIndex; ///< Index to current line. It takes into account the current layout configuration (is not the number of \n)
- bool mCurrentUnderlineStatus:1; ///< Whether current character is underlined.
-};
-
-/**
- * Stores layout information of a line.
- */
-struct LineLayoutInfo
-{
- /**
- * Default constructor.
- *
- * Initializes each member to its default.
- */
- LineLayoutInfo();
-
- /**
- * Empty destructor.
- *
- * @note Added to increase coverage.
- */
- ~LineLayoutInfo();
-
- float mLineLength; ///< The length of the portion of the paragraph which fits on the text-view width.
- float mMaxCharHeight; ///< The maximum height of all characters of the portion of the paragraph which fits on the text-view width.
- float mMaxAscender; ///< The maximum ascender of all characters of the portion of the paragraph which fits on the text-view width.
-};
-
-/**
- * Calculates the layout info of the portion of the paragraph which fits on the text-view width.
- *
- * @param[in] parentWidth Text-view width
- * @param[in] indices Indices to the word and character.
- * @param[in] paragraphLayoutInfo Layout info for the paragraph.
- * @param[in] splitPolicy Whether a paragraph is wraped by word, by character or by word and character.
- * @param[in] shrinkFactor Shrink factor used.
- * @param[out] layoutInfo Layout information of the part of the paragraph which fits in the text-view width.
- */
-void CalculateLineLayout( float parentWidth,
- const TextViewProcessor::TextInfoIndices& indices,
- const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo,
- HorizontalWrapType splitPolicy,
- float shrinkFactor,
- LineLayoutInfo& layoutInfo );
-
-/**
- * Reorders the text layout of each line of each paragraph of the text.
- *
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void ReorderRightToLeftLayout( TextView::RelayoutData& relayoutData );
-
-/**
- * Calculates the \e x offset position for the whole text.
- *
- * @param[in] horizontalTextAlignment The horizontal alignment type.
- * @param[in] parentWidth The parent's width.
- * @param[in] wholeTextWidth The whole text's width.
- * @return The \e x position offset.
- */
-float CalculateXoffset( Toolkit::Alignment::Type horizontalTextAlignment, float parentWidth, float wholeTextWidth );
-
-/**
- * Calculates the \e y offset position for the whole text.
- *
- * @param[in] verticalTextAlignment The vertical alignment type.
- * @param[in] parentHeight The parent's height.
- * @param[in] wholeTextHeight The whole text's height.
- * @return The \e y position offset.
- */
-float CalculateYoffset( Toolkit::Alignment::Type verticalTextAlignment, float parentHeight, float wholeTextHeight );
-
-/**
- * Calculates the \e x offset position for one line.
- *
- * @param[in] justification The line justification type.
- * @param[in] wholeTextWidth The whole text's width.
- * @param[in] lineLength The line's length.
- * @return The \e x position offset.
- *
- */
-float CalculateJustificationOffset( Toolkit::TextView::LineJustification justification, float wholeTextWidth, float lineLength );
-
-/**
- * Whether text-actor is visible for Fade and Ellipsize exceed policies.
- *
- * It does different visibility tests according the given parameter \e type. @see VisibilityTestType.
- *
- * @param[in] position Position of the character.
- * @param[in] size Size of the character.
- * @param[in] parentSize Parent's size.
- * @param[in] type One of FULLY_VISIBLE, PARTIALLY_VISIBLE, PARTIALLY_VISIBLE_WIDTH or PARTIALLI_VISIBLE_HEIGHT.
- * @return \e true if is visible.
- */
-bool IsVisible( const Vector3& position, const Size& size, const Size& parentSize, VisibilityTestType type );
-
-/**
- * Calculates the coeficients of the rect equation for the two given points.
- *
- * @param[in] p0 A point of the rect.
- * @param[in] p1 Another point of the rect.
- *
- * @return The \e gradient is returned in the \e x member and the \e constant \e term is returned in the \e y value.
- */
-Vector2 CalculateRectParameters( const Vector2& p0, const Vector2& p1 );
-
-/**
- * Aligns the whole text within the text-view.
- *
- * @param[in] layoutParameters The layout parameters.
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void UpdateAlignment( const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Calculates the bearing for the given character.
- *
- * @param[in,out] characterLayoutInfo Character layout info.
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void CalculateBearing( TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Updates the character's layout info table.
- *
- * This table is used to pass the size, the position and other layout info to other controls/actors.
- *
- * @param[in,out] minMaxXY The boundary box of the whole text.
- * @param[in,out] wordLayoutInfo Word layout info.
- * @param[in,out] characterLayoutInfo Character layout info.
- * @param[in,out] relayoutParameters Temporary layout parameters.
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void UpdateLayoutInfoTable( Vector4& minMaxXY,
- TextViewProcessor::WordLayoutInfo& wordLayoutInfo,
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
- RelayoutParameters& relayoutParameters,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Calculates the text-actor visibility and fade parameters.
- *
- * @param[in] layoutParameters The layout parameters.
- * @param[in] characterLayoutInfo Character layout info.
- * @param[in] style The style of the character. Used to get the color (and alpha) of the character.
- * @param[in,out] relayoutParameters Temporary layout parameters.
- * @param[in,out] fadeParameters Temporary fade parameters.
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void CalculateVisibilityForFade( const Internal::TextView::LayoutParameters& layoutParameters,
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
- const TextStyle& style,
- RelayoutParameters& relayoutParameters,
- FadeParameters& fadeParameters,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Calculates the text-actor visibility and creates eliipsize text-actors.
- *
- * @param[in] layoutParameters The layout parameters.
- * @param[in] characterLayoutInfo Character layout info.
- * @param[in,out] ellipsizeParameters Temporary ellipsize parameters.
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void CalculateVisibilityForEllipsize( const Internal::TextView::LayoutParameters& layoutParameters,
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
- EllipsizeParameters& ellipsizeParameters,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Creates the actors needed for the ellipsized text.
- *
- * @param[in,out] ellipsizeParameters Temporary ellipsize parameters.
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void CreateEllipsizeTextActor( const EllipsizeParameters& ellipsizeParameters,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Replace the text which exceeds the boundary by the ellipsis text.
- *
- * @param[in] layoutParameters The layout parameters.
- * @param[in,out] ellipsisParameters Temporary ellipsis parameters.
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void EllipsizeLine( const TextView::LayoutParameters& layoutParameters,
- EllipsizeParameters& ellipsizeParameters,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Traverse all text data structure setting its visibility to true.
- *
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void SetTextVisible( TextView::RelayoutData& relayoutData );
-
-/**
- * Calculates the visibility and fade parameters.
- *
- * @param[in] layoutParameters The layout parameters.
- * @param[in] visualParameters Some visual parameters (fade, sort modifier and blending).
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void UpdateVisibilityForFade( const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData );
-/**
- * Calculates the visibility for text ellipsize.
- *
- * @param[in] layoutParameters The layout parameters.
- * @param[in] visualParameters Some visual parameters (fade, sort modifier and blending).
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void UpdateVisibilityForEllipsize( const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData );
-/**
- * Calculates the visibility and fade parameters.
- *
- * @param[in] layoutParameters The layout parameters.
- * @param[in] visualParameters Some visual parameters (fade, sort modifier and blending).
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void UpdateVisibility( const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Traverse all text initializing all non initialized text-actor handles
- * and updating text-actor handles with new size, position, ...
- *
- * @param[in] visualParameters Some visual parameters (fade, sort modifier and blending).
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info.
- * @param[in] createGlyphActors Whether to create RenderableActor for text-actors or emojis.
- */
-void UpdateTextActorInfo( const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData,
- bool createGlyphActors );
-
-/**
- * Traverses the whole text and for each piece of underlined text,
- * it calculates the maximum thickness and the position of that particular piece of underlined text.
- *
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info and conversion from visual to logical order and vice versa (for RTL text).
- */
-void CalculateUnderlineInfo( TextView::RelayoutData& relayoutData );
-
-/**
- * Traverses the whole text and for each piece of underlined text,
- * it sets the previously calculated maximum thickness and the position of that particular piece of underlined text.
- *
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info and conversion from visual to logical order and vice versa (for RTL text).
- */
-void SetUnderlineInfo( TextView::RelayoutData& relayoutData );
-
-/**
- * Remove renderable-actor from the text-view.
- *
- * @param[in,out] textView The text-view.
- * @param[in] glyphActors renderable-actors to be removed from the text-view.
- */
-void RemoveGlyphActors( Actor textView,
- const std::vector<RenderableActor>& glyphActors );
-
-/**
- * Inserts the text-actors into the text-view and the text-actor's list.
- *
- * @param[in,out] textView The text-view.
- * @param[in,out] relayoutData The text-view's data structures.
- */
-void InsertToTextView( Actor textView,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Retrieves a new glyph-actor from the cache of text-actors or creating a new one if it's empty.
- *
- * @param[in] text The text-actor's text.
- * @param[in] style The text-actor's style.
- * @param[in] cache The cache of text-actors.
- *
- * @return a RenderableActor with the text's glyph.
- */
-RenderableActor CreateGlyphActor( const Text& text, const TextStyle& style, TextActorCache& cache );
-
-} // namespace TextViewRelayout
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_RELAYOUT_UTILITIES_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-view/split-by-char-policies.h>
-
-// EXTERNAL INCLUDES
-#include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace SplitByChar
-{
-
-namespace
-{
-
-Vector3 NoShrinkWhenExceedPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
- const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
-
- if( ( relayoutParameters.mIsNewLine ||
- relayoutParameters.mIsFirstCharacter ||
- ( wordOffset + relayoutParameters.mCharacterSize.width > relayoutData.mTextViewSize.width ) ) )
- {
- if( !relayoutParameters.mIsNewLine &&
- ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewParagraphCharacter ) )
- {
- // Current character is a white space. Don't want to move a white space to the next line.
- // These white spaces are placed just in the edge.
- return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
- }
- else
- {
- // Calculate the line length and the max character height for the current line.
- TextViewRelayout::LineLayoutInfo subLineInfo;
- subLineInfo.mLineLength = 0.f;
- subLineInfo.mMaxCharHeight = 0.f;
- subLineInfo.mMaxAscender = 0.f;
- const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + relayoutParameters.mIndices.mParagraphIndex ) );
-
- TextViewRelayout::CalculateLineLayout( relayoutData.mTextViewSize.width,
- relayoutParameters.mIndices,
- paragraphLayoutInfo,
- TextViewRelayout::WrapByCharacter,
- 1.f, // Shrink factor
- subLineInfo );
-
- Toolkit::TextView::LineLayoutInfo lineInfo;
- lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
- lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
- lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
- relayoutData.mLines.push_back( lineInfo );
-
- return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
- }
- }
- else
- {
- return Vector3( wordOffset, previousPositionY, 0.f );
- }
-}
-
-void CalculateSizeAndPosition( const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- TextViewRelayout::RelayoutParameters relayoutParameters;
-
- // clear
- relayoutData.mCharacterLayoutInfoTable.clear();
- relayoutData.mLines.clear();
- relayoutData.mTextSizeForRelayoutOption = Size();
-
- // Calculate the text size for split by char.
- Vector4 minMaxXY( std::numeric_limits<float>::max(),
- std::numeric_limits<float>::max(),
- std::numeric_limits<float>::min(),
- std::numeric_limits<float>::min() );
-
- relayoutData.mShrinkFactor = 1.f; // Shrink factor used when the exceed policy contains ShrinkToFit
-
- relayoutParameters.mPositionOffset = Vector3::ZERO;
- relayoutParameters.mIsFirstCharacter = true;
- relayoutParameters.mIndices.mParagraphIndex = 0u;
- relayoutParameters.mCharacterGlobalIndex = 0u;
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(),
- endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphLayoutIt != endParagraphLayoutIt;
- ++paragraphLayoutIt, ++relayoutParameters.mIndices.mParagraphIndex )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
-
- relayoutParameters.mIsNewLine = true;
- relayoutParameters.mParagraphSize = paragraphLayoutInfo.mSize;
- relayoutParameters.mIndices.mWordIndex = 0u;
-
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
- endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
- wordLayoutIt != endWordLayoutIt;
- ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
- {
- TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
- relayoutParameters.mIsWhiteSpace = TextViewProcessor::WordSeparator == wordLayoutInfo.mType;
- relayoutParameters.mIsNewParagraphCharacter = TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType;
-
- relayoutParameters.mIsFirstCharacterOfWord = true;
- relayoutParameters.mWordSize = wordLayoutInfo.mSize;
- relayoutParameters.mIndices.mCharacterIndex = 0u;
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
- endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
- characterLayoutIt != endCharacterLayoutIt;
- ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex )
- {
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
-
- relayoutParameters.mCharacterSize = characterLayoutInfo.mSize;
-
- switch( layoutParameters.mExceedPolicy )
- {
- case TextView::OriginalShrink:
- case TextView::SplitOriginal:
- case TextView::SplitFade:
- case TextView::SplitEllipsizeEnd:
- case TextView::SplitShrink:
- case TextView::ShrinkOriginal:
- case TextView::ShrinkFade:
- case TextView::Shrink:
- case TextView::EllipsizeEndOriginal:
- case TextView::EllipsizeEnd: // Fall Through
- {
- DALI_LOG_WARNING( "SplitByChar::CalculateSizeAndPosition() policy not implemented.\n" );
- break;
- }
- case TextView::OriginalFade:
- case TextView::FadeOriginal:
- case TextView::Original:
- case TextView::Fade: // Fall Through
- {
- characterLayoutInfo.mPosition = NoShrinkWhenExceedPosition( relayoutParameters,
- layoutParameters,
- relayoutData );
-
- relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
- break;
- }
- default:
- {
- DALI_LOG_WARNING( "SplitByChar::CalculateSizeAndPosition() policy combination not possible.\n" );
- }
- }
-
- // Get last line info and calculate the bearing (used to align glyphs with the baseline).
- TextViewRelayout::CalculateBearing( characterLayoutInfo, relayoutData );
-
- // updates min and max position to calculate the text size for split by char.
- TextViewRelayout::UpdateLayoutInfoTable( minMaxXY,
- wordLayoutInfo,
- characterLayoutInfo,
- relayoutParameters,
- relayoutData );
-
- ++relayoutParameters.mCharacterGlobalIndex;
- relayoutParameters.mIsFirstCharacter = false;
- relayoutParameters.mIsNewLine = false;
- } // end characters
- } // end words
- } // end paragraphs
-
- if( relayoutData.mCharacterLayoutInfoTable.empty() )
- {
- relayoutData.mTextSizeForRelayoutOption = Size();
- }
- else
- {
- relayoutData.mTextSizeForRelayoutOption.width = minMaxXY.z - minMaxXY.x;
- relayoutData.mTextSizeForRelayoutOption.height = minMaxXY.w - minMaxXY.y;
- }
-
- // Check if the last character is a new paragraph character. In that case the height should be added.
- if( !relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u ) );
-
- if( paragraphLayoutInfo.mWordsLayoutInfo.empty() ) // if it's empty, it means the last character is a new paragraph character.
- {
- relayoutData.mTextSizeForRelayoutOption.height += paragraphLayoutInfo.mSize.height;
- }
- }
-}
-
-} // namespace
-
-void Relayout( Actor textView,
- TextView::RelayoutOperationMask relayoutOperationMask,
- const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData )
-{
- if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
- {
- CalculateSizeAndPosition( layoutParameters,
- relayoutData );
-
- TextViewRelayout::ReorderRightToLeftLayout( relayoutData );
-
- TextViewRelayout::SetUnderlineInfo( relayoutData );
- }
-
- if( relayoutOperationMask & TextView::RELAYOUT_ALIGNMENT )
- {
- TextViewRelayout::UpdateAlignment( layoutParameters,
- relayoutData );
- }
-
- if( relayoutOperationMask & TextView::RELAYOUT_VISIBILITY )
- {
- TextViewRelayout::UpdateVisibility( layoutParameters,
- visualParameters,
- relayoutData );
- }
-
- const bool initializeTextActors = relayoutOperationMask & TextView::RELAYOUT_INITIALIZE_TEXT_ACTORS;
- const bool updateTextActors = relayoutOperationMask & TextView::RELAYOUT_TEXT_ACTOR_UPDATE;
- if( initializeTextActors || updateTextActors )
- {
- TextViewRelayout::UpdateTextActorInfo( visualParameters,
- relayoutData,
- initializeTextActors );
- }
-
- if( relayoutOperationMask & TextView::RELAYOUT_INSERT_TO_TEXT_VIEW )
- {
- TextViewRelayout::InsertToTextView( textView,
- relayoutData );
- }
-}
-
-} // namespace SplitByChar
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_SPLIT_BY_CHAR_POLICIES_H__
-#define __DALI_TOOLKIT_INTERNAL_SPLIT_BY_CHAR_POLICIES_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace SplitByChar
-{
-
-/**
- * Sets text-actor's size and position accordingly with the given text-view's size and layout parameters.
- * Visible text-actors are added to the text-view. Non visible actors are not added.
- *
- * @param[in] textView The handle to the text-view actor.
- * @param[in] relayoutOperationMask Mask which defines which operations need to be done in the relayout process.
- * @param[in] layoutParameters The layout parameters.
- * @param[in] visualParameters Some visual parameters (fade, sort modifier and blending).
- * @param[in] relayoutData The text-view's data structures which are modified by this function.
- */
-void Relayout( Actor textView,
- TextView::RelayoutOperationMask relayoutOperationMask,
- const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData );
-
-} // namespace SplitByChar
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_SPLIT_BY_CHAR_POLICIES_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-view/split-by-new-line-char-policies.h>
-
-// INTERNAL INCLUDES
-#include <dali/integration-api/debug.h>
-#include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace SplitByNewLineChar
-{
-
-namespace
-{
-
-Vector3 SplitPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
- const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
-
- if( relayoutParameters.mIsNewLine ||
- relayoutParameters.mIsFirstCharacter ||
- ( wordOffset + relayoutParameters.mCharacterSize.width > relayoutData.mTextViewSize.width ) )
- {
- if( !relayoutParameters.mIsNewLine &&
- ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewParagraphCharacter ) )
- {
- // Current character is a white space. Don't want to move a white space to the next line.
- // These white spaces are placed just in the edge.
- return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
- }
- else
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + relayoutParameters.mIndices.mParagraphIndex ) );
-
- TextViewRelayout::LineLayoutInfo subLineInfo;
- subLineInfo.mLineLength = 0.f;
- subLineInfo.mMaxCharHeight = 0.f;
- subLineInfo.mMaxAscender = 0.f;
- TextViewRelayout::CalculateLineLayout( relayoutData.mTextViewSize.width,
- relayoutParameters.mIndices,
- paragraphLayoutInfo,
- TextViewRelayout::WrapByParagraphCharacterAndSplit,
- 1.f, // Shrink factor
- subLineInfo );
-
- Toolkit::TextView::LineLayoutInfo lineInfo;
- lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
- lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
- lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
- relayoutData.mLines.push_back( lineInfo );
-
- return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
- }
- }
- else
- {
- return Vector3( wordOffset, previousPositionY, 0.f );
- }
-}
-
-void CalculateSizeAndPosition( const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- // clear
- relayoutData.mCharacterLayoutInfoTable.clear();
- relayoutData.mLines.clear();
- relayoutData.mTextSizeForRelayoutOption = Size();
- relayoutData.mShrinkFactor = 1.f;
-
- // Calculates the text size for split by char.
- Vector4 minMaxXY( std::numeric_limits<float>::max(),
- std::numeric_limits<float>::max(),
- std::numeric_limits<float>::min(),
- std::numeric_limits<float>::min() );
-
- TextViewRelayout::RelayoutParameters relayoutParameters;
-
- if( TextView::ShrinkOriginal == layoutParameters.mExceedPolicy )
- {
- if( relayoutData.mTextLayoutInfo.mWholeTextSize.width > relayoutData.mTextViewSize.width )
- {
- relayoutData.mShrinkFactor = relayoutData.mTextViewSize.width / relayoutData.mTextLayoutInfo.mWholeTextSize.width;
- }
- }
- else if( TextView::Shrink == layoutParameters.mExceedPolicy )
- {
- if( ( relayoutData.mTextLayoutInfo.mWholeTextSize.width > relayoutData.mTextViewSize.width ) ||
- ( relayoutData.mTextLayoutInfo.mWholeTextSize.height > relayoutData.mTextViewSize.height ) )
- {
- relayoutData.mShrinkFactor = std::min( relayoutData.mTextViewSize.width / relayoutData.mTextLayoutInfo.mWholeTextSize.width,
- relayoutData.mTextViewSize.height / relayoutData.mTextLayoutInfo.mWholeTextSize.height );
- }
- }
-
- relayoutParameters.mIsFirstCharacter = true;
- relayoutParameters.mIndices.mParagraphIndex = 0u;
- relayoutParameters.mPositionOffset = Vector3::ZERO;
- relayoutParameters.mCharacterGlobalIndex = 0u;
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(),
- endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphLayoutIt != endParagraphLayoutIt;
- ++paragraphLayoutIt, ++relayoutParameters.mIndices.mParagraphIndex )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
-
- relayoutParameters.mParagraphSize = paragraphLayoutInfo.mSize * relayoutData.mShrinkFactor;
-
- relayoutParameters.mIsNewLine = true;
- relayoutParameters.mIndices.mWordIndex = 0u;
-
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
- endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
- wordLayoutIt != endWordLayoutIt;
- ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
- {
- TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
- relayoutParameters.mIsWhiteSpace = TextViewProcessor::WordSeparator == wordLayoutInfo.mType;
- relayoutParameters.mIsNewParagraphCharacter = TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType;
-
- relayoutParameters.mIsFirstCharacterOfWord = true;
- relayoutParameters.mWordSize = wordLayoutInfo.mSize;
- relayoutParameters.mIndices.mCharacterIndex = 0u;
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
- endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
- characterLayoutIt != endCharacterLayoutIt;
- ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex )
- {
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
- relayoutParameters.mCharacterSize = characterLayoutInfo.mSize;
-
- relayoutParameters.mCharacterSize = characterLayoutInfo.mSize;
-
- switch( layoutParameters.mExceedPolicy )
- {
- case TextView::OriginalShrink:
- case TextView::SplitShrink:
- case TextView::ShrinkFade: // Fall Through
- {
- DALI_LOG_WARNING( "SplitByNewLineChar::CalculateSizeAndPosition() policy not implemented.\n" );
- break;
- }
- case TextView::Original: // Fall Through
- case TextView::ShrinkOriginal: // Fall Through
- case TextView::Shrink: // Fall Through
- case TextView::OriginalFade: // Fall Through
- case TextView::FadeOriginal: // Fall Through
- case TextView::Fade: // Fall Through
- case TextView::EllipsizeEndOriginal: // Fall Through
- case TextView::EllipsizeEnd: // Fall Through
- {
- if( relayoutParameters.mIsNewLine )
- {
- relayoutParameters.mPositionOffset.x = 0.f;
- relayoutParameters.mPositionOffset.y += paragraphLayoutInfo.mSize.height * relayoutData.mShrinkFactor;
- }
-
- characterLayoutInfo.mPosition = relayoutParameters.mPositionOffset;
-
- relayoutParameters.mPositionOffset.x += characterLayoutInfo.mSize.width * relayoutData.mShrinkFactor;
-
- if( relayoutParameters.mIsNewLine ||
- relayoutParameters.mIsFirstCharacter )
- {
- Toolkit::TextView::LineLayoutInfo lineInfo;
- lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
- lineInfo.mSize = relayoutParameters.mParagraphSize; // Size of this piece of paragraph.
- lineInfo.mAscender = paragraphLayoutInfo.mAscender * relayoutData.mShrinkFactor; // Ascender of this piece of paragraph.
- relayoutData.mLines.push_back( lineInfo );
- }
- break;
- }
- case TextView::SplitOriginal:
- case TextView::SplitFade:
- case TextView::SplitEllipsizeEnd: // Fall Through
- {
- characterLayoutInfo.mPosition = SplitPosition( relayoutParameters,
- layoutParameters,
- relayoutData );
-
- relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
- break;
- }
- default:
- {
- DALI_LOG_WARNING( "SplitByNewLineChar::CalculateSizeAndPosition() Layout configuration not possible.\n" );
- break;
- }
- }
-
- // Get last line info and calculate the bearing (used to align glyphs with the baseline).
- TextViewRelayout::CalculateBearing( characterLayoutInfo, relayoutData );
-
- // updates min and max position to calculate the text size for split by new line char.
- TextViewRelayout::UpdateLayoutInfoTable( minMaxXY,
- wordLayoutInfo,
- characterLayoutInfo,
- relayoutParameters,
- relayoutData );
-
- ++relayoutParameters.mCharacterGlobalIndex;
- relayoutParameters.mIsFirstCharacter = false;
- relayoutParameters.mIsNewLine = false;
- } // end characters
- } // end words
- } // end paragraphs
-
- if( relayoutData.mCharacterLayoutInfoTable.empty() )
- {
- relayoutData.mTextSizeForRelayoutOption = Size();
- }
- else
- {
- relayoutData.mTextSizeForRelayoutOption.width = minMaxXY.z - minMaxXY.x;
- relayoutData.mTextSizeForRelayoutOption.height = minMaxXY.w - minMaxXY.y;
- }
-
- // Check if the last character is a new paragraph character. In that case the height should be added.
- if( !relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u ) );
-
- if( paragraphLayoutInfo.mWordsLayoutInfo.empty() ) // if it's empty, it means the last character is a new paragraph character.
- {
- relayoutData.mTextSizeForRelayoutOption.height += paragraphLayoutInfo.mSize.height * relayoutData.mShrinkFactor;
- }
- }
-}
-
-} // namespace
-
-void Relayout( Actor textView,
- TextView::RelayoutOperationMask relayoutOperationMask,
- const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData )
-{
- if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
- {
- CalculateSizeAndPosition( layoutParameters,
- relayoutData );
-
- TextViewRelayout::ReorderRightToLeftLayout( relayoutData );
-
- TextViewRelayout::SetUnderlineInfo( relayoutData );
- }
-
- if( relayoutOperationMask & TextView::RELAYOUT_ALIGNMENT )
- {
- TextViewRelayout::UpdateAlignment( layoutParameters,
- relayoutData );
- }
-
- if( relayoutOperationMask & TextView::RELAYOUT_VISIBILITY )
- {
- TextViewRelayout::UpdateVisibility( layoutParameters,
- visualParameters,
- relayoutData );
- }
-
- const bool initializeTextActors = relayoutOperationMask & TextView::RELAYOUT_INITIALIZE_TEXT_ACTORS;
- const bool updateTextActors = relayoutOperationMask & TextView::RELAYOUT_TEXT_ACTOR_UPDATE;
- if( initializeTextActors || updateTextActors )
- {
- TextViewRelayout::UpdateTextActorInfo( visualParameters,
- relayoutData,
- initializeTextActors );
- }
-
- if( relayoutOperationMask & TextView::RELAYOUT_INSERT_TO_TEXT_VIEW )
- {
- TextViewRelayout::InsertToTextView( textView,
- relayoutData );
- }
-}
-
-} // namespace SplitByNewLineChar
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_SPLIT_BY_NEW_LINE_CHAR_POLICIES_H__
-#define __DALI_TOOLKIT_INTERNAL_SPLIT_BY_NEW_LINE_CHAR_POLICIES_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace SplitByNewLineChar
-{
-
-/**
- * Sets text-actor's size and position accordingly with the given text-view's size and layout parameters.
- * Visible text-actors are added to the text-view. Non visible actors are not added.
- *
- * @param[in] textView The handle to the text-view actor.
- * @param[in] relayoutOperationMask Mask which defines which operations need to be done in the relayout process.
- * @param[in] layoutParameters The layout parameters.
- * @param[in] visualParameters Some visual parameters (fade, sort modifier and blending).
- * @param[in] relayoutData The text-view's data structures which are modified by this function.
- */
-void Relayout( Actor textView,
- TextView::RelayoutOperationMask relayoutOperationMask,
- const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData );
-
-} // namespace SplitByNewLineChar
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_SPLIT_BY_NEW_LINE_CHAR_POLICIES_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-view/split-by-word-policies.h>
-
-// INTERNAL INCLUDES
-#include <dali/integration-api/debug.h>
-#include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace SplitByWord
-{
-
-namespace
-{
-
-Vector3 OriginalPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
- const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
-
- if( relayoutParameters.mIsNewLine ||
- relayoutParameters.mIsFirstCharacter ||
- ( relayoutParameters.mIsFirstCharacterOfWord && ( wordOffset + relayoutParameters.mWordSize.width > relayoutData.mTextViewSize.width ) ) )
- {
- if( !relayoutParameters.mIsNewLine &&
- ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewParagraphCharacter ) )
- {
- // Current character is a white space. Don't want to move a white space to the next line.
- // These white spaces are placed just in the edge.
- return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
- }
- else
- {
- // Calculates the length of the portion of the paragraph which doesn't exceed the text-view's width and the max character height for the current line.
- TextViewRelayout::LineLayoutInfo subLineInfo;
- subLineInfo.mLineLength = 0.f;
- subLineInfo.mMaxCharHeight = 0.f;
- subLineInfo.mMaxAscender = 0.f;
- const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + relayoutParameters.mIndices.mParagraphIndex ) );
-
- TextViewRelayout::CalculateLineLayout( relayoutData.mTextViewSize.width,
- relayoutParameters.mIndices,
- paragraphLayoutInfo,
- TextViewRelayout::WrapByWord,
- 1.f, // Shrink factor
- subLineInfo );
-
- if( subLineInfo.mLineLength < Math::MACHINE_EPSILON_1000 )
- {
- // It may mean there is a word which is actually longer than the width of the text-view.
- // In that case the length of this word is needed.
- if( !paragraphLayoutInfo.mWordsLayoutInfo.empty() )
- {
- const TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *( paragraphLayoutInfo.mWordsLayoutInfo.begin() + relayoutParameters.mIndices.mWordIndex ) );
- subLineInfo.mLineLength = wordLayoutInfo.mSize.width;
- }
- }
-
- Toolkit::TextView::LineLayoutInfo lineInfo;
- lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
- lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
- lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
- relayoutData.mLines.push_back( lineInfo );
-
- return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
- }
- }
- else
- {
- return Vector3( wordOffset, previousPositionY, 0.f );
- }
-}
-
-/**
- * Calculates character position.
- * @param[in] relayoutParameters Temporary layout parameters (previous size, previous position, ... )
- * @param[in] layoutParameters The layout parameters.
- * @param[in] relayoutData The text-view's data structures.
- * @return The character's position.
- */
-Vector3 SplitWhenExceedPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
- const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
-
- if( ( relayoutParameters.mIsNewLine || relayoutParameters.mIsFirstCharacter ) ||
- ( relayoutParameters.mIsFirstCharacterOfWord && ( wordOffset + relayoutParameters.mWordSize.width > relayoutData.mTextViewSize.width ) ) ||
- ( wordOffset + relayoutParameters.mCharacterSize.width > relayoutData.mTextViewSize.width ) )
- {
- if( !relayoutParameters.mIsNewLine &&
- ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewParagraphCharacter ) )
- {
- // Current character is a white space. Don't want to move a white space to the next line.
- // These white spaces are placed just in the edge.
- return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
- }
- else
- {
- // Calculates the line length and the max character height for the current line.
- TextViewRelayout::LineLayoutInfo subLineInfo;
- subLineInfo.mLineLength = 0.f;
- subLineInfo.mMaxCharHeight = 0.f;
- subLineInfo.mMaxAscender = 0.f;
- const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + relayoutParameters.mIndices.mParagraphIndex ) );
-
- TextViewRelayout::CalculateLineLayout( relayoutData.mTextViewSize.width,
- relayoutParameters.mIndices,
- paragraphLayoutInfo,
- TextViewRelayout::WrapByWordAndSplit,
- 1.f, // Shrink factor.
- subLineInfo );
-
- Toolkit::TextView::LineLayoutInfo lineInfo;
- lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
- lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
- lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
- relayoutData.mLines.push_back( lineInfo );
-
- return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
- }
- }
- else
- {
- return Vector3( wordOffset, previousPositionY, 0.f );
- }
-}
-
-/**
- * Calculates character position.
- * @param[in] relayoutParameters Temporary layout parameters (previous size, previous position, ... )
- * @param[in] layoutParameters The layout parameters.
- * @param[in] relayoutData The text-view's data structures.
- * @return The character's position.
- */
-Vector3 ShrinkWidthWhenExceedPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
- const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
- const Size wordSize = relayoutParameters.mWordSize * relayoutData.mShrinkFactor;
-
- if( ( relayoutParameters.mIsNewLine || relayoutParameters.mIsFirstCharacter ) || // isNewLine is true when '\n' is found.
- ( relayoutParameters.mIsFirstCharacterOfWord && ( wordOffset + wordSize.width > relayoutData.mTextViewSize.width ) ) ) // The word doesn't fit in the parent width.
- {
- if( !relayoutParameters.mIsNewLine &&
- ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewParagraphCharacter ) )
- {
- // Current character is a white space. Don't want to move a white space to the next line.
- // These white spaces are placed just in the edge.
- return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
- }
- else
- {
- // Calculates the line length and the max character height for the current line.
- TextViewRelayout::LineLayoutInfo subLineInfo;
- subLineInfo.mLineLength = 0.f;
- subLineInfo.mMaxCharHeight = 0.f;
- subLineInfo.mMaxAscender = 0.f;
- const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + relayoutParameters.mIndices.mParagraphIndex ) );
-
- TextViewRelayout::CalculateLineLayout( relayoutData.mTextViewSize.width,
- relayoutParameters.mIndices,
- paragraphLayoutInfo,
- TextViewRelayout::WrapByWord,
- relayoutData.mShrinkFactor,
- subLineInfo );
-
- Toolkit::TextView::LineLayoutInfo lineInfo;
- lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
- lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
- lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
- relayoutData.mLines.push_back( lineInfo );
-
- return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset * relayoutData.mShrinkFactor, 0.f );
- }
- }
- else
- {
- return Vector3( wordOffset, previousPositionY, 0.f );
- }
-}
-
-void CalculatePositionsForShrinkWhenExceed( TextView::RelayoutData& relayoutData,
- const TextView::LayoutParameters& layoutParameters,
- const float shrinkFactor,
- float& newTextHeight )
-{
- const float parentWidth = relayoutData.mTextViewSize.width;
- TextViewProcessor::TextLayoutInfo& textLayoutInfo = relayoutData.mTextLayoutInfo;
-
- // Reset the text height. This value is returned in order to shrink further or not the text.
- newTextHeight = 0.f;
-
- // Whether the first character is being processed.
- bool isFirstChar = true;
-
- // Stores the size of the previous character.
- Size previousSize;
- // Stores the position of the previous character.
- Vector3 previousPosition;
-
- // Reset the index of paragraphs.
- TextViewProcessor::TextInfoIndices indices;
-
- // Whether the last character of the whole text is a new paragraph char.
- // This information is used to increase or not the height of the whole text by one line.
- // Increase the whole text's height by one line is useful i.e. in TextInput to place the cursor
- // after pressing 'Enter' in the last paragraph.
- bool isLastCharacterNewParagraphChar = false;
- // Stores the height of the last character. This height used to be added to the whole text height if
- // isLastCharacterNewParagraphChar is true.
- float lastCharHeight = 0.f;
-
- relayoutData.mLines.clear();
- std::size_t characterGlobalIndex = 0u;
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphIt = textLayoutInfo.mParagraphsLayoutInfo.begin(), paragraphEndIt = textLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphIt != paragraphEndIt;
- ++paragraphIt, ++indices.mParagraphIndex )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphIt );
-
- // The next character is in a new line.
- bool isNewLine = true;
-
- // Reset the index of words.
- indices.mWordIndex = 0u;
-
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(), wordEndIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
- wordIt != wordEndIt;
- ++wordIt, ++indices.mWordIndex )
- {
- TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordIt );
-
- // Reset the index of the character.
- indices.mCharacterIndex = 0u;
-
- // Whether current character is the first of the word.
- bool isFirstCharOfWord = true;
- const float wordOffset = previousPosition.x + previousSize.width;
-
- isLastCharacterNewParagraphChar = ( TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType );
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator charIt = wordLayoutInfo.mCharactersLayoutInfo.begin(), charEndIt = wordLayoutInfo.mCharactersLayoutInfo.end();
- charIt != charEndIt;
- ++charIt, ++indices.mCharacterIndex )
- {
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *charIt );
- lastCharHeight = characterLayoutInfo.mSize.height * shrinkFactor;
-
- const float previousPositionY = isFirstChar ? 0.f : previousPosition.y;
-
- if( ( isNewLine || isFirstChar ) ||
- ( isFirstCharOfWord && ( wordOffset + wordLayoutInfo.mSize.width * shrinkFactor > parentWidth ) ) )
- {
- isFirstChar = false;
-
- // Calculates the line length and the max character height for the current line.
- TextViewRelayout::LineLayoutInfo subLineInfo;
- subLineInfo.mLineLength = 0.f;
- subLineInfo.mMaxCharHeight = 0.f;
- subLineInfo.mMaxAscender = 0.f;
- TextViewRelayout::CalculateLineLayout( parentWidth,
- indices,
- paragraphLayoutInfo,
- TextViewRelayout::WrapByWord,
- shrinkFactor,
- subLineInfo );
-
- characterLayoutInfo.mPosition = Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset * shrinkFactor, 0.f );
-
- newTextHeight += subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset * shrinkFactor;
-
- Toolkit::TextView::LineLayoutInfo lineInfo;
- lineInfo.mCharacterGlobalIndex = characterGlobalIndex; // Index to the first character of the next line.
- lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
- lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
- relayoutData.mLines.push_back( lineInfo );
- }
- else
- {
- characterLayoutInfo.mPosition = previousPosition + Vector3( previousSize.width, 0.f, 0.f );
- }
-
- // Get last line info and calculate the bearing.
- const Toolkit::TextView::LineLayoutInfo& lineInfo( *( relayoutData.mLines.end() - 1u ) );
- const float bearingOffset = ( ( lineInfo.mSize.height - lineInfo.mAscender ) - ( characterLayoutInfo.mSize.height - characterLayoutInfo.mAscender ) ) * shrinkFactor;
-
- previousSize = characterLayoutInfo.mSize * shrinkFactor;
- previousPosition = characterLayoutInfo.mPosition;
- characterLayoutInfo.mPosition.y -= bearingOffset;
- isFirstCharOfWord = false;
- isNewLine = false;
-
- ++characterGlobalIndex;
- }
- }
- }
-
- if( isLastCharacterNewParagraphChar )
- {
- newTextHeight += lastCharHeight + layoutParameters.mLineHeightOffset * shrinkFactor;
- }
-}
-
-float RelayoutForShrinkToFit( TextView::RelayoutData& relayoutData,
- const TextView::LayoutParameters& layoutParameters )
-{
- const Size& textViewSize = relayoutData.mTextViewSize;
- TextViewProcessor::TextLayoutInfo& textLayoutInfo = relayoutData.mTextLayoutInfo;
-
- // First step is assure the longest word fits in the text view width.
- float shrinkFactor = ( textLayoutInfo.mMaxWordWidth > textViewSize.width ? textViewSize.width / textLayoutInfo.mMaxWordWidth : 1.f );
-
- // Out parameter. Will store the new text height after relayout the text.
- float newTextHeight = 0.f;
-
- // Relayout the text for the given character's sizes.
- CalculatePositionsForShrinkWhenExceed( relayoutData,
- layoutParameters,
- shrinkFactor,
- newTextHeight );
-
- if( newTextHeight > textViewSize.height )
- {
- // After relayouting, the text exceeds the text view height.
- // Find a new scale factor to fit all the text in the text view size is needed.
-
- // The next algorithm does some iterations to calculate an acceptable scale factor.
- // Some magic numbers are defined.
-
- const float MIN_RATIO( 0.90f ); // The algorithm finishes if the ratio
- const float MAX_RATIO( 1.00f ); // new_text_height / text_view_height is between this two values
- const unsigned int MAX_ITERATIONS( 8u ); // or max_iteration is reached.
-
- float ratio = newTextHeight / textViewSize.height;
-
- float maxScaleFactor = shrinkFactor; // bigger scale factors than maxScaleFactor will produce a too big text.
- float minScaleFactor = shrinkFactor * ( textViewSize.height / newTextHeight ); // smaller scale factors than minScaleFactor will produce a too small text.
-
- for( unsigned int iterations = 0u; ( ( MIN_RATIO > ratio ) || ( ratio > MAX_RATIO ) ) && ( iterations < MAX_ITERATIONS ); ++iterations )
- {
- // Calculates the new scale factor.
- // The new scale factor is always between the min and max scale factors.
- // If ratio < 1 it means the text is too small and a bigger scale factor is needed. In this case the algorithm selects a new scale factor close to
- // minScaleFactor. Alternatively if the text is too big a new scale factor close to maxScaleFactor is selected.
- // This allows the text shrink or grow smoothly.
- shrinkFactor = minScaleFactor + ( ratio < 1.f ? 0.4f : 0.6f ) * ( maxScaleFactor - minScaleFactor );
-
- CalculatePositionsForShrinkWhenExceed( relayoutData, // Relayout the text for the given character's sizes.
- layoutParameters,
- shrinkFactor,
- newTextHeight );
-
- // Calculates the new text size ratio. It allows update the min and max scale factors.
- // If the ratio is not good enough a new scale factor between min and max could be used in next iteration.
- ratio = newTextHeight / textViewSize.height;
- if( ratio < 1.f )
- {
- minScaleFactor = shrinkFactor;
- }
- else
- {
- maxScaleFactor = shrinkFactor;
- }
- }
-
- if( ratio > MAX_RATIO )
- {
- // The algorithm didn't find an acceptable scale factor.
- // In that case the text is shrunk to fit in the boundaries of the text view actor.
- shrinkFactor = minScaleFactor;
-
- CalculatePositionsForShrinkWhenExceed( relayoutData,
- layoutParameters,
- shrinkFactor,
- newTextHeight );
- }
- }
-
- return shrinkFactor;
-}
-
-void CalculateSizeAndPosition( const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- TextViewRelayout::RelayoutParameters relayoutParameters;
-
- // clear
- relayoutData.mCharacterLayoutInfoTable.clear();
- relayoutData.mLines.clear();
- relayoutData.mTextSizeForRelayoutOption = Size();
-
- // Calculates the text size for split by char.
- Vector4 minMaxXY( std::numeric_limits<float>::max(),
- std::numeric_limits<float>::max(),
- std::numeric_limits<float>::min(),
- std::numeric_limits<float>::min() );
-
- relayoutData.mShrinkFactor = 1.f; // Shrink factor used when the exceed policy contains ShrinkToFit
-
- if( TextView::Shrink == layoutParameters.mExceedPolicy )
- {
- // Relays-out the text for the shrink to fit policy.
- relayoutData.mShrinkFactor = RelayoutForShrinkToFit( relayoutData, layoutParameters );
- }
- else if( TextView::ShrinkOriginal == layoutParameters.mExceedPolicy )
- {
- relayoutData.mShrinkFactor = ( relayoutData.mTextLayoutInfo.mMaxWordWidth > relayoutData.mTextViewSize.width ? relayoutData.mTextViewSize.width / relayoutData.mTextLayoutInfo.mMaxWordWidth : 1.f );
- }
-
- relayoutParameters.mPositionOffset = Vector3::ZERO;
- relayoutParameters.mIsFirstCharacter = true;
- relayoutParameters.mIndices.mParagraphIndex = 0u;
- relayoutParameters.mCharacterGlobalIndex = 0u;
-
- for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(),
- endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphLayoutIt != endParagraphLayoutIt;
- ++paragraphLayoutIt, ++relayoutParameters.mIndices.mParagraphIndex )
- {
- TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
-
- relayoutParameters.mIsNewLine = true;
- relayoutParameters.mParagraphSize = paragraphLayoutInfo.mSize;
- relayoutParameters.mIndices.mWordIndex = 0u;
-
- for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
- endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
- wordLayoutIt != endWordLayoutIt;
- ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
- {
- TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
- relayoutParameters.mIsWhiteSpace = TextViewProcessor::WordSeparator == wordLayoutInfo.mType;
- relayoutParameters.mIsNewParagraphCharacter = TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType;
-
- relayoutParameters.mIsFirstCharacterOfWord = true;
- relayoutParameters.mWordSize = wordLayoutInfo.mSize;
- relayoutParameters.mIndices.mCharacterIndex = 0u;
-
- for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
- endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
- ( characterLayoutIt != endCharacterLayoutIt );
- ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex )
- {
- TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
-
- relayoutParameters.mCharacterSize = characterLayoutInfo.mSize;
-
- switch( layoutParameters.mExceedPolicy )
- {
- case TextView::OriginalShrink:
- case TextView::SplitShrink:
- case TextView::ShrinkFade:
- {
- DALI_LOG_WARNING( "SplitByWord::CalculateSizeAndPosition() policy not implemented.\n" );
- break;
- }
- case TextView::Original:
- case TextView::OriginalFade:
- case TextView::FadeOriginal:
- case TextView::Fade:
- case TextView::EllipsizeEndOriginal:
- case TextView::EllipsizeEnd: // Fall Through
- {
- characterLayoutInfo.mPosition = OriginalPosition( relayoutParameters,
- layoutParameters,
- relayoutData );
-
- relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
- break;
- }
- case TextView::SplitOriginal:
- case TextView::SplitFade:
- case TextView::SplitEllipsizeEnd:
- {
- characterLayoutInfo.mPosition = SplitWhenExceedPosition( relayoutParameters,
- layoutParameters,
- relayoutData );
-
- relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
- break;
- }
- case TextView::ShrinkOriginal:
- {
- characterLayoutInfo.mPosition = ShrinkWidthWhenExceedPosition( relayoutParameters,
- layoutParameters,
- relayoutData );
-
- relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width * relayoutData.mShrinkFactor, 0.f, 0.f );
- break;
- }
- case TextView::Shrink:
- {
- // Does nothing. All the job has been done in the RelayoutForShrinkToFit() function.
- break;
- }
- default:
- {
- DALI_LOG_WARNING( "SplitByWord::CalculateSizeAndPosition() policy combination not possible.\n" );
- }
- }
-
- // Get last line info and calculate the bearing (used to align glyphs with the baseline).
- if( TextView::Shrink != layoutParameters.mExceedPolicy )
- {
- TextViewRelayout::CalculateBearing( characterLayoutInfo, relayoutData );
- }
-
- // updates min and max position to calculate the text size for split by word.
- TextViewRelayout::UpdateLayoutInfoTable( minMaxXY,
- wordLayoutInfo,
- characterLayoutInfo,
- relayoutParameters,
- relayoutData );
-
- ++relayoutParameters.mCharacterGlobalIndex;
- relayoutParameters.mIsFirstCharacter = false;
- relayoutParameters.mIsFirstCharacterOfWord = false;
- relayoutParameters.mIsNewLine = false;
- } // end characters
- } // end words
- } // end paragraphs
-
- if( relayoutData.mCharacterLayoutInfoTable.empty() )
- {
- relayoutData.mTextSizeForRelayoutOption = Size();
- }
- else
- {
- relayoutData.mTextSizeForRelayoutOption.width = minMaxXY.z - minMaxXY.x;
- relayoutData.mTextSizeForRelayoutOption.height = minMaxXY.w - minMaxXY.y;
- }
-
- // Check if the last character is a new paragraph character. In that case the height should be added.
- if( !relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
- {
- const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u ) );
-
- if( paragraphLayoutInfo.mWordsLayoutInfo.empty() ) // if it's empty, it means the last character is a new paragraph character.
- {
- relayoutData.mTextSizeForRelayoutOption.height += paragraphLayoutInfo.mSize.height * relayoutData.mShrinkFactor;
- }
- }
-}
-
-} // namespace
-
-void Relayout( Actor textView,
- TextView::RelayoutOperationMask relayoutOperationMask,
- const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData )
-{
- if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
- {
- CalculateSizeAndPosition( layoutParameters,
- relayoutData );
-
- TextViewRelayout::ReorderRightToLeftLayout( relayoutData );
-
- TextViewRelayout::SetUnderlineInfo( relayoutData );
- }
-
- if( relayoutOperationMask & TextView::RELAYOUT_ALIGNMENT )
- {
- TextViewRelayout::UpdateAlignment( layoutParameters,
- relayoutData );
- }
-
- if( relayoutOperationMask & TextView::RELAYOUT_VISIBILITY )
- {
- TextViewRelayout::UpdateVisibility( layoutParameters,
- visualParameters,
- relayoutData );
- }
- const bool initializeTextActors = relayoutOperationMask & TextView::RELAYOUT_INITIALIZE_TEXT_ACTORS;
- const bool updateTextActors = relayoutOperationMask & TextView::RELAYOUT_TEXT_ACTOR_UPDATE;
- if( initializeTextActors || updateTextActors )
- {
- TextViewRelayout::UpdateTextActorInfo( visualParameters,
- relayoutData,
- initializeTextActors );
- }
-
- if( relayoutOperationMask & TextView::RELAYOUT_INSERT_TO_TEXT_VIEW )
- {
- TextViewRelayout::InsertToTextView( textView,
- relayoutData );
- }
-}
-
-} // namespace SplitByWord
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_SPLIT_BY_WORD_POLICIES_H__
-#define __DALI_TOOLKIT_INTERNAL_SPLIT_BY_WORD_POLICIES_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace SplitByWord
-{
-
-/**
- * Sets text-actor's size and position accordingly with the given text-view's size and layout parameters.
- * Visible text-actors are added to the text-view. Non visible actors are not added.
- *
- * @param[in] textView The handle to the text-view actor.
- * @param[in] relayoutOperationMask Mask which defines which operations need to be done in the relayout process.
- * @param[in] layoutParameters The layout parameters.
- * @param[in] visualParameters Some visual parameters (fade, sort modifier and blending).
- * @param[in] relayoutData The text-view's data structures which are modified by this function.
- */
-void Relayout( Actor textView,
- TextView::RelayoutOperationMask relayoutOperationMask,
- const TextView::LayoutParameters& layoutParameters,
- const TextView::VisualParameters& visualParameters,
- TextView::RelayoutData& relayoutData );
-
-} // namespace SplitByWord
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_SPLIT_BY_WORD_POLICIES_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali-toolkit/internal/controls/text-view/text-actor-cache.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-TextActorCache::TextActorCache()
-: mTextActors()
-{
-}
-
-TextActorCache::~TextActorCache()
-{
-}
-
-void TextActorCache::InsertTextActors( const std::vector<TextActor>& textActors )
-{
- mTextActors.insert( mTextActors.end(), textActors.rbegin(), textActors.rend() );
-}
-
-TextActor TextActorCache::RetrieveTextActor()
-{
- // Text-actors are inserted in the order needed to retrieve always the last one.
-
- // Returns a non initialized handle if the cache is empty.
- TextActor textActor;
-
- if( !mTextActors.empty() )
- {
- textActor = mTextActors.back();
- mTextActors.pop_back();
- }
-
- return textActor;
-}
-
-void TextActorCache::ClearTexts()
-{
- for( std::vector<TextActor>::iterator it = mTextActors.begin(); it != mTextActors.end(); ++it )
- {
- (*it).SetText("");
- }
-}
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_ACTOR_CACHE_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_ACTOR_CACHE_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/public-api/actors/text-actor.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-/**
- * Stores text-actors to be reused.
- *
- * Is it asumed that the first text-actor of a group of text-actors added to the cache is the first one to be rehused.
- */
-class TextActorCache
-{
-
-public:
- /**
- * Default constructor.
- */
- TextActorCache();
-
- /**
- * Destructor.
- */
- ~TextActorCache();
-
- /**
- * Inserts the given text-actors into the cache.
- *
- * First text-actor of the vector is the first one to be reused.
- *
- * @param[in] textActors The text-actors to be inserted into the cache.
- */
- void InsertTextActors( const std::vector<TextActor>& textActors );
-
- /**
- * Retrieves a text-actor from the cache.
- *
- * @return A handle to a text-actor. It returns a non initialized handle if the cache has no text-actors.
- */
- TextActor RetrieveTextActor();
-
- /**
- * Clears the text of the text-actor in the cache.
- */
- void ClearTexts();
-
-private:
- std::vector<TextActor> mTextActors; ///< Stores cached text-actors.
-};
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_ACTOR_CACHE_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextProcessor
-{
-
-BidirectionalParagraphInfo::BidirectionalParagraphInfo()
-: mDirection( FRIBIDI_TYPE_ON ),
- mCharactersTypeBuffer(),
- mLevelsBuffer(),
- mLogicalUnicodeBuffer()
-{
-}
-
-BidirectionalParagraphInfo::~BidirectionalParagraphInfo()
-{
-}
-
-BidirectionalParagraphInfo::BidirectionalParagraphInfo( const BidirectionalParagraphInfo& info )
-: mDirection( info.mDirection ),
- mCharactersTypeBuffer( info.mCharactersTypeBuffer ),
- mLevelsBuffer( info.mLevelsBuffer ),
- mLogicalUnicodeBuffer( info.mLogicalUnicodeBuffer )
-{
-}
-
-BidirectionalParagraphInfo& BidirectionalParagraphInfo::operator=( const BidirectionalParagraphInfo& info )
-{
- if( this != &info )
- {
- mDirection = info.mDirection;
- mCharactersTypeBuffer = info.mCharactersTypeBuffer;
- mLevelsBuffer = info.mLevelsBuffer;
- mLogicalUnicodeBuffer = info.mLogicalUnicodeBuffer;
- }
-
- return *this;
-}
-
-bool BidirectionalParagraphInfo::IsRightToLeftParagraph() const
-{
- bool isRightToLeft = false;
-
- switch( mDirection )
- {
- case FRIBIDI_PAR_LTR: // Left-To-Right paragraph.
- case FRIBIDI_PAR_ON: // DirectiOn-Neutral paragraph.
- case FRIBIDI_PAR_WLTR: // Weak Left To Right paragraph.
- {
- isRightToLeft = false;
- break;
- }
- case FRIBIDI_PAR_RTL: // Right-To-Left paragraph.
- case FRIBIDI_PAR_WRTL: // Weak Right To Left paragraph.
- {
- isRightToLeft = true;
- break;
- }
- }
-
- return isRightToLeft;
-}
-
-BidirectionalLineInfo::BidirectionalLineInfo()
-: mCharacterParagraphIndex(),
- mNumberOfCharacters(),
- mText(),
- mVisualToLogicalMap(),
- mLogicalToVisualMap()
-{
-}
-
-BidirectionalLineInfo::~BidirectionalLineInfo()
-{
-}
-
-BidirectionalLineInfo::BidirectionalLineInfo( const BidirectionalLineInfo& info )
-: mCharacterParagraphIndex( info.mCharacterParagraphIndex ),
- mNumberOfCharacters( info.mNumberOfCharacters ),
- mText( info.mText ),
- mVisualToLogicalMap( info.mVisualToLogicalMap ),
- mLogicalToVisualMap( info.mLogicalToVisualMap )
-{
-}
-
-BidirectionalLineInfo& BidirectionalLineInfo::operator=( const BidirectionalLineInfo& info )
-{
- if( this != &info )
- {
- mCharacterParagraphIndex = info.mCharacterParagraphIndex;
- mNumberOfCharacters = info.mNumberOfCharacters;
- mText = info.mText;
- mVisualToLogicalMap = info.mVisualToLogicalMap;
- mLogicalToVisualMap = info.mLogicalToVisualMap;
- }
-
- return *this;
-}
-
-bool BeginsRightToLeftCharacter( const Text& text )
-{
- for( size_t i = 0u, length = text.GetLength(); i < length; ++i )
- {
- Character::CharacterDirection direction = text[i].GetCharacterDirection();
- if( direction != Character::Neutral )
- {
- return ( direction == Character::RightToLeft || direction == Character::RightToLeftWeak );
- }
- }
-
- return false;
-}
-
-bool ContainsRightToLeftCharacter( const Dali::Text& text )
-{
- for( size_t i = 0u, length = text.GetLength(); i < length; ++i )
- {
- Character::CharacterDirection direction = ( text[i] ).GetCharacterDirection();
- if( ( Character::RightToLeft == direction ) || ( Character::RightToLeftWeak == direction ) )
- {
- return true;
- }
- }
-
- return false;
-}
-
-void ProcessBidirectionalText( Text& paragraph, BidirectionalParagraphInfo* info )
-{
- if( paragraph.IsEmpty() )
- {
- // nothing to do if the paragraph is empty.
- return;
- }
-
- const std::size_t stringSize = paragraph.GetText().size();
-
- // Text buffer in logical order. Coded in unicode.
- info->mLogicalUnicodeBuffer.resize( stringSize + 1u, 0u );
- FriBidiChar* logicalUnicodeBufferPointer = &info->mLogicalUnicodeBuffer[0u];
-
- // Converts from utf8 to unicode.
- const std::size_t length = fribidi_charset_to_unicode( FRIBIDI_CHAR_SET_UTF8, paragraph.GetText().c_str(), stringSize, logicalUnicodeBufferPointer );
-
- // Character type buffer.
- info->mCharactersTypeBuffer.resize( length, 0u );
-
- // Levels buffer.
- info->mLevelsBuffer.resize( length, 0u );
-
- // Joining type buffer.
- std::vector<FriBidiJoiningType> joiningTypeBuffer;
- joiningTypeBuffer.resize( length, 0u );
-
- // Pointers to the buffers.
- FriBidiCharType* charactersTypeBufferPointer = &info->mCharactersTypeBuffer[0u];
- FriBidiLevel* levelsBufferPointer = &info->mLevelsBuffer[0u];
- FriBidiJoiningType* joiningTypeBufferPointer = &joiningTypeBuffer[0u];
-
- // Retrieves the type of each character.
- fribidi_get_bidi_types( logicalUnicodeBufferPointer, length, charactersTypeBufferPointer );
-
- // Retrieves the paragraph direction.
- info->mDirection = fribidi_get_par_direction( charactersTypeBufferPointer, length );
-
- // Retrieve the embedding levels.
- fribidi_get_par_embedding_levels( charactersTypeBufferPointer, length, &info->mDirection, levelsBufferPointer );
-
- // Retrieve the joining types.
- fribidi_get_joining_types( logicalUnicodeBufferPointer, length, joiningTypeBufferPointer );
-
- fribidi_join_arabic( charactersTypeBufferPointer, length, levelsBufferPointer, joiningTypeBufferPointer );
-
- const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;
-
- fribidi_shape( flags, levelsBufferPointer, length, joiningTypeBufferPointer, logicalUnicodeBufferPointer );
-
- std::vector<char> bidiTextConverted;
-
- bidiTextConverted.resize( length * 4u + 1u ); // Maximum bytes to represent one UTF-8 character is 6.
- // Currently Dali doesn't support this UTF-8 extension. Dali only supports 'regular' UTF-8 which has a maximum of 4 bytes per character.
-
- fribidi_unicode_to_charset( FRIBIDI_CHAR_SET_UTF8, logicalUnicodeBufferPointer, length, &bidiTextConverted[0] );
-
- paragraph = Text( &bidiTextConverted[0u] );
-}
-
-void ReorderLine( BidirectionalParagraphInfo* paragraphInfo,
- BidirectionalLineInfo* lineInfo )
-{
- const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;
-
- lineInfo->mVisualToLogicalMap.Resize( lineInfo->mNumberOfCharacters, 0u );
- lineInfo->mLogicalToVisualMap.Resize( lineInfo->mNumberOfCharacters, 0u );
-
- std::vector<FriBidiChar> visualUnicodeBuffer;
- visualUnicodeBuffer.insert( visualUnicodeBuffer.end(),
- paragraphInfo->mLogicalUnicodeBuffer.begin() + lineInfo->mCharacterParagraphIndex,
- paragraphInfo->mLogicalUnicodeBuffer.begin() + ( lineInfo->mCharacterParagraphIndex + lineInfo->mNumberOfCharacters ) );
-
- // Pointers to the buffers.
- FriBidiCharType* charactersTypeBufferPointer = ¶graphInfo->mCharactersTypeBuffer[lineInfo->mCharacterParagraphIndex];
- FriBidiLevel* levelsBufferPointer = ¶graphInfo->mLevelsBuffer[lineInfo->mCharacterParagraphIndex];
- FriBidiChar* visualUnicodeBufferPointer = &visualUnicodeBuffer[0u];
- FriBidiStrIndex* visualToLogicalMapPointer = &lineInfo->mVisualToLogicalMap[0u];
-
- // Initialize the visual to logical mapping table to the identity. Otherwise fribidi_reorder_line fails to retrieve a valid mapping table.
- for( std::size_t index = 0u; index < lineInfo->mNumberOfCharacters; ++index )
- {
- lineInfo->mVisualToLogicalMap[ index ] = index;
- }
-
- fribidi_reorder_line( flags,
- charactersTypeBufferPointer,
- lineInfo->mNumberOfCharacters,
- 0u,
- paragraphInfo->mDirection,
- levelsBufferPointer,
- visualUnicodeBufferPointer,
- visualToLogicalMapPointer );
-
- // Fill the logical to visual mapping table.
- for( std::size_t index = 0u; index < lineInfo->mNumberOfCharacters; ++index )
- {
- lineInfo->mLogicalToVisualMap[ lineInfo->mVisualToLogicalMap[ index ] ] = index;
- }
-
- std::vector<char> bidiTextConverted;
-
- bidiTextConverted.resize( lineInfo->mNumberOfCharacters * 4u + 1u ); // Maximum bytes to represent one UTF-8 character is 6.
- // Currently Dali doesn't support this UTF-8 extension.
- // Dali only supports 'regular' UTF-8 which has a maximum of 4 bytes per character.
-
- fribidi_unicode_to_charset( FRIBIDI_CHAR_SET_UTF8, visualUnicodeBufferPointer, lineInfo->mNumberOfCharacters, &bidiTextConverted[0u] );
-
- lineInfo->mText = Text( &bidiTextConverted[0u] );
-}
-
-} // namespace TextProcessor
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_TEXT_PROCESSOR_BIDIRECTIONAL_INFO_H__
-#define __DALI_TOOLKIT_TEXT_PROCESSOR_BIDIRECTIONAL_INFO_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/public-api/common/vector-wrapper.h>
-#include <dali/public-api/text/text.h>
-
-// EXTERNAL INCLUDES
-#include <fribidi/fribidi.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextProcessor
-{
-
-/**
- * Stores the text containing right to left characters and info for each character needed by fribidi to reorder a line.
- */
-struct BidirectionalParagraphInfo
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their default values.
- */
- BidirectionalParagraphInfo();
-
- /**
- * Default destructor.
- */
- ~BidirectionalParagraphInfo();
-
- /**
- * Copy constructor.
- */
- BidirectionalParagraphInfo( const BidirectionalParagraphInfo& info );
-
- /**
- * Assignment operator.
- */
- BidirectionalParagraphInfo& operator=( const BidirectionalParagraphInfo& info );
-
-
- /**
- * @return Whether the paragraph is right to left.
- */
- bool IsRightToLeftParagraph() const;
-
- FriBidiParType mDirection; ///< The paragraph direction.
- std::vector<FriBidiCharType> mCharactersTypeBuffer; ///< Character type buffer.
- std::vector<FriBidiLevel> mLevelsBuffer; ///< Levels buffer.
- std::vector<FriBidiChar> mLogicalUnicodeBuffer; ///< Text buffer in logical order. Coded in unicode.
-};
-
-/**
- * Stores the reordered text, the conversion tables for a paragraph's line,
- * the index to the first character of the line and the number of characters.
- */
-struct BidirectionalLineInfo
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their default values.
- */
- BidirectionalLineInfo();
-
- /**
- * Default destructor.
- */
- ~BidirectionalLineInfo();
-
- /**
- * Copy constructor.
- */
- BidirectionalLineInfo( const BidirectionalLineInfo& info );
-
- /**
- * Assignment operator.
- */
- BidirectionalLineInfo& operator=( const BidirectionalLineInfo& info );
-
- std::size_t mCharacterParagraphIndex; ///< Index within the paragraph of the first character of the line.
- std::size_t mNumberOfCharacters; ///< Number of characters of the line.
- Text mText; ///< Text in visual order.
- Vector<int> mVisualToLogicalMap; ///< The character position map from the visual output text to the logical input text.
- Vector<int> mLogicalToVisualMap; ///< The character position map from the logical input text to the visual output text.
-};
-
-/**
- * Whether the text begins with right-to-left (bidirectional) character.
- * @param [in] text The given text.
- * @return \e true if the text begins right-to-left character.
- */
-bool BeginsRightToLeftCharacter( const Text& text );
-
-/**
- * Whether the text contains any right-to-left (bidirectional) character.
- * @param [in] text The given text.
- * @return \e true if the text contains right-to-left character.
- */
-bool ContainsRightToLeftCharacter( const Text& text );
-
-/**
- * Processes a bidirectional paragraph's text.
- *
- * It stores the paragraph's direction (the direction of the first non neutral character),
- * the direction of all characters, and the ligatures in case of arabic glyphs.
- *
- * It doesn't reorder the paragraph as this task must be done per line.
- * The stored info is needed to reorder each line of the paragraph.
- *
- * @param[in] paragraph The paragraph to be processed.
- * @param[out] info Struct containing the needed info to reorder each line of the paragraph.
- */
-void ProcessBidirectionalText( Text& paragraph,
- BidirectionalParagraphInfo* info );
-
-/**
- * Reorders one line of the paragraph according the Unicode Bidirectional Algorithm.
- *
- * The result is the text in the visual order and the conversion tables: logical <--> visual order
- *
- * @param[in] paragraphInfo Struct containing the needed info to reorder each line of the paragraph.
- * @param[in,out] lineInfo Struct containing (in) A character index pointing the first character of the line and the number of characters, (out) the reordered line and the conversion tables.
- */
-void ReorderLine( BidirectionalParagraphInfo* paragraphInfo,
- BidirectionalLineInfo* lineInfo );
-
-} // namespace TextProcessor
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_TEXT_PROCESSOR_BIDIRECTIONAL_INFO_H__
-
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-view/text-processor.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextProcessor
-{
-
-void SplitInParagraphs( const MarkupProcessor::StyledTextArray& styledTextArray,
- std::vector<Text>& paragraphs,
- std::vector< Vector<TextStyle*> >& styles )
-{
- // Stores the text for a paragraph.
- Text paragraph;
-
- // Stores the styles for each character of the paragraph.
- Vector<TextStyle*> stylesForParagraph;
-
- // Traverses all styled texts of the array.
- for( MarkupProcessor::StyledTextArray::const_iterator it = styledTextArray.begin(), endIt = styledTextArray.end(); it != endIt; ++it )
- {
- const MarkupProcessor::StyledText& styledText( *it );
-
- // Traverses all the characters of the styled text (It may have more than one).
- for( size_t i = 0u, length = styledText.mText.GetLength(); i < length; ++i )
- {
- const Dali::Character character = styledText.mText[i];
-
- if( character.IsNewLine() ) // LF
- {
- // The character is a new paragraph character.
-
- // Append the new paragraph character.
- paragraph.Append( character );
-
- // Creates a new text style for the character and insert it to the vector of styles for that paragraph.
- TextStyle* style = new TextStyle( styledText.mStyle );
- stylesForParagraph.PushBack( style );
-
- // Inserts the paragraph and the styles to the vector of paragraphs and the vector of styles.
- paragraphs.push_back( paragraph );
- styles.push_back( stylesForParagraph );
-
- // Clears the text and the vector of styles for the next paragraph.
- paragraph = Text();
- stylesForParagraph.Clear();
- }
- else
- {
- // The character is not a new paragraph character.
-
- // Append it to the paragraph's text
- paragraph.Append( character );
-
- // Add the style to the vector of styles for that paragraph.
- TextStyle* style = new TextStyle( styledText.mStyle );
- stylesForParagraph.PushBack( style );
- }
- }
- }
-
- // This paragraph could be empty if the last character of the previous paragraph is a 'new paragraph' character
- // and is the last of the text.
- paragraphs.push_back( paragraph );
- styles.push_back( stylesForParagraph );
-}
-
-void SplitInWords( const Dali::Text& paragraph,
- Vector<std::size_t>& positions )
-{
- const std::size_t length = paragraph.GetLength();
-
- // Magic number: Let's soupose there is ~6 characters per word. Used to do less memory reallocation inside Vector.
- const size_t magicNumberOfWords = ( length / 6u ) + 1u;
-
- // Find the positions of the new paragraph characters.
- positions.Reserve( magicNumberOfWords );
-
- // Find the position of all white spaces. A new paragraph character is also considered a white space but it doesn't matter at this point.
- paragraph.Find( Text::WHITE_SPACE, 0u, length - 1u, positions );
-}
-
-/**
- * Wheather the character of the text pointed by the given offset is a white space.
- *
- * @param[in] text The text.
- * @param[in] offset Offset pointing the character.
- *
- * @return \e true if the character pointed by the offset is a white space.
- */
-bool IsWhiteSpace( const MarkupProcessor::StyledTextArray& text, size_t offset )
-{
- DALI_ASSERT_DEBUG( offset < text.size() );
-
- // assume 1 Character per StyledText
- return ( *( text.begin() + offset ) ).mText[0u].IsWhiteSpace();
-}
-
-void FindNearestWord( const MarkupProcessor::StyledTextArray& text, size_t offset, size_t& start, size_t& end)
-{
- const size_t size(text.size());
- offset = std::min(offset, size-1u);
-
- size_t i(offset);
- size_t j(offset);
-
- // if currently looking at whitespace, then search left and right for non-whitespace.
- if(IsWhiteSpace(text, offset))
- {
- // scan left until non-white space / beginning of string.
- while(i > 0u && IsWhiteSpace(text, i))
- {
- i--;
- }
-
- // scan right until non-white space / end of string.
- while(j < size && IsWhiteSpace(text, j))
- {
- j++;
- }
- }
-
- // check if r.h.s. word is closer than l.h.s. word
- if( (j - offset) < // distance to closest right word <
- (offset - i) ) // distance to closest left word
- {
- // point left and right markers on start of right word
- i = j;
- }
- else
- {
- // point left and right markers on end of left word
- j = i;
- }
-
- // expand left and right markers to encompase entire word
- while(i > 0u && !IsWhiteSpace(text, i-1u))
- {
- i--;
- }
-
- while(j < size && !IsWhiteSpace(text, j))
- {
- j++;
- }
-
- // If both markers at same position and is whitespace then word is a whitespace word
- if ( i == j )
- {
- while(j < size && IsWhiteSpace(text, j))
- {
- j++;
- }
-
- while(i > 0 && IsWhiteSpace(text, i-1))
- {
- i--;
- }
- }
-
- start = i;
- end = j;
-}
-
-} // namespace TextProcessor
-
-} // namespace Internal
-
-} // namespace DaliToolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_TEXT_PROCESSOR_H__
-#define __DALI_TOOLKIT_TEXT_PROCESSOR_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/markup-processor/markup-processor.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextProcessor
-{
-// Forward declarations.
-struct BidirectionalParagraphInfo;
-
-/**
- * Splits the given text in paragraphs.
- *
- * @note Assumes the StyledTextArray has 1 Character per Text element. (which is the case for text in TextInput, but
- * not necessarily the case for text in TextView)
- *
- * @param [in] styledTextArray The given text.
- * @param [out] paragraphs The text split in paragraphs.
- * @param [out] styles The styles of each character of each paragraph.
- */
-void SplitInParagraphs( const MarkupProcessor::StyledTextArray& styledTextArray,
- std::vector<Text>& paragraphs,
- std::vector< Vector<TextStyle*> >& styles );
-
-/**
- * Finds the position of all word separators (currently white spaces and new paragraph characters '\n') in the given text.
- *
- * @param [in] paragraph The given paragraph.
- * @param [out] positions Positions within the paragraph of all word sepatators.
- */
-void SplitInWords( const Text& paragraph,
- Vector<std::size_t>& positions );
-
-/**
- * Finds the nearest word in a string to a specified
- * offset (in Characters).
- *
- * @note Assumes the StyledTextArray has 1 Character per Text element. (which is the case for text in TextInput, but
- * not necessarily the case for text in TextView)
- *
- * @param[in] text The text to search through.
- * @param[in] offset The current offset position to begin search from.
- * @param[out] start The start position of nearest word
- * @param[out] end The end position of nearest word
- */
-void FindNearestWord( const MarkupProcessor::StyledTextArray& text, size_t offset, size_t& start, size_t& end);
-
-} // namespace TextProcessor
-
-} // namespace Internal
-
-} // namespace DaliToolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_TEXT_PROCESSOR_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-types.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewProcessor
-{
-
-/////////////////////
-// Layout info.
-/////////////////////
-
-GradientInfo::GradientInfo()
-: mGradientColor(),
- mStartPoint(),
- mEndPoint()
-{
-}
-
-GradientInfo::~GradientInfo()
-{
-}
-
-GradientInfo::GradientInfo( const GradientInfo& info )
-: mGradientColor( info.mGradientColor ),
- mStartPoint( info.mStartPoint ),
- mEndPoint( info.mEndPoint )
-{
-}
-
-GradientInfo& GradientInfo::operator=( const GradientInfo& info )
-{
- if( this != &info )
- {
- mGradientColor = info.mGradientColor;
- mStartPoint = info.mStartPoint;
- mEndPoint = info.mEndPoint;
- }
-
- return *this;
-}
-
-CharacterLayoutInfo::CharacterLayoutInfo()
-: mSize(),
- mBearing( 0.f ),
- mAscender( 0.f ),
- mUnderlineThickness( 0.f ),
- mUnderlinePosition( 0.f ),
- mPosition(),
- mOffset(),
- mGlyphActor(),
- mColorAlpha( 1.f ),
- mGradientInfo( NULL ),
- mIsVisible( true ),
- mSetText( false ),
- mSetStyle( false ),
- mIsColorGlyph( false )
-{
-}
-
-CharacterLayoutInfo::~CharacterLayoutInfo()
-{
- // Deletes the gradient info.
- delete mGradientInfo;
-}
-
-CharacterLayoutInfo::CharacterLayoutInfo( const CharacterLayoutInfo& character )
-: mSize( character.mSize ),
- mBearing( character.mBearing ),
- mAscender( character.mAscender ),
- mUnderlineThickness( character.mUnderlineThickness ),
- mUnderlinePosition( character.mUnderlinePosition ),
- mPosition( character.mPosition ),
- mOffset( character.mOffset ),
- mGlyphActor( character.mGlyphActor ),
- mColorAlpha( character.mColorAlpha ),
- mGradientInfo( ( NULL == character.mGradientInfo ) ? NULL : new GradientInfo( *character.mGradientInfo ) ), // Copies the gradient info.
- mIsVisible( character.mIsVisible ),
- mSetText( character.mSetText ),
- mSetStyle( character.mSetStyle ),
- mIsColorGlyph( character.mIsColorGlyph )
-{
-}
-
-CharacterLayoutInfo& CharacterLayoutInfo::operator=( const CharacterLayoutInfo& character )
-{
- mSize = character.mSize;
- mAscender = character.mAscender;
- mBearing = character.mBearing;
- mUnderlineThickness = character.mUnderlineThickness;
- mUnderlinePosition = character.mUnderlinePosition;
-
- mPosition = character.mPosition;
- mOffset = character.mOffset;
-
- mGlyphActor = character.mGlyphActor;
-
- mColorAlpha = character.mColorAlpha;
-
- // Copies the gradient info.
- if( NULL == character.mGradientInfo )
- {
- // The source doesn't have. Deletes the current one.
- delete mGradientInfo;
- mGradientInfo = NULL;
- }
- else
- {
- // The source has gradient info.
- if( NULL != mGradientInfo )
- {
- // It it has, copy to it.
- *mGradientInfo = *character.mGradientInfo;
- }
- else
- {
- // If it doesn't have, create a new one.
- mGradientInfo = new GradientInfo( *character.mGradientInfo );
- }
- }
-
- mIsVisible = character.mIsVisible;
- mSetText = character.mSetText;
- mSetStyle = character.mSetStyle;
- mIsColorGlyph = character.mIsColorGlyph;
-
- return *this;
-}
-
-} //namespace TextViewProcessor
-
-} //namespace Internal
-
-} //namespace Toolkit
-
-} //namespace Dali
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/common/stage.h>
-#include <dali/public-api/object/type-registry.h>
-#include <dali/public-api/render-tasks/render-task-list.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/split-by-new-line-char-policies.h>
-#include <dali-toolkit/internal/controls/text-view/split-by-word-policies.h>
-#include <dali-toolkit/internal/controls/text-view/split-by-char-policies.h>
-#include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
-#include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-const Property::Index TextView::PROPERTY_MARKUP_ENABLED( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX );
-const Property::Index TextView::PROPERTY_TEXT( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 1 );
-const Property::Index TextView::PROPERTY_MULTILINE_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 2 );
-const Property::Index TextView::PROPERTY_WIDTH_EXCEED_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 3 );
-const Property::Index TextView::PROPERTY_HEIGHT_EXCEED_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 4 );
-const Property::Index TextView::PROPERTY_LINE_JUSTIFICATION( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 5 );
-const Property::Index TextView::PROPERTY_FADE_BOUNDARY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 6 );
-const Property::Index TextView::PROPERTY_LINE_HEIGHT_OFFSET( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 7 );
-const Property::Index TextView::PROPERTY_HORIZONTAL_ALIGNMENT( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 8 );
-const Property::Index TextView::PROPERTY_VERTICAL_ALIGNMENT( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 9 );
-
-namespace Internal
-{
-
-namespace
-{
-
-// Signals
-
-const char* const SIGNAL_TEXT_SCROLLED = "scrolled";
-
-const char* MULTILINE_POLICY_NAME[] = {"SplitByNewLineChar", "SplitByWord", "SplitByChar"};
-const char* EXCEED_POLICY_NAME[] = {"Original", "Truncate", "Fade", "Split","ShrinkToFit","EllipsizeEnd"};
-const char* LINE_JUSTIFICATION_NAME[] = {"Left","Center","Right","Justified"};
-
-// Currently on desktop machines 2k x 2k is the maximum frame buffer size, on target is 4k x 4k.
-const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f;
-
-//Type Registration
-BaseHandle Create()
-{
- return Toolkit::TextView::New();
-}
-
-TypeRegistration typeRegistration( typeid( Toolkit::TextView ), typeid( Toolkit::Control ), Create );
-
-SignalConnectorType signalConnector1( typeRegistration, SIGNAL_TEXT_SCROLLED , &TextView::DoConnectSignal );
-
-PropertyRegistration property1( typeRegistration, "markup-enabled", Toolkit::TextView::PROPERTY_MARKUP_ENABLED, Property::BOOLEAN, &TextView::SetProperty, &TextView::GetProperty );
-PropertyRegistration property2( typeRegistration, "text", Toolkit::TextView::PROPERTY_TEXT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
-PropertyRegistration property3( typeRegistration, "multiline-policy", Toolkit::TextView::PROPERTY_MULTILINE_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
-PropertyRegistration property4( typeRegistration, "width-exceed-policy", Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
-PropertyRegistration property5( typeRegistration, "height-exceed-policy", Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
-PropertyRegistration property6( typeRegistration, "line-justification", Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
-PropertyRegistration property7( typeRegistration, "fade-boundary", Toolkit::TextView::PROPERTY_FADE_BOUNDARY, Property::VECTOR4, &TextView::SetProperty, &TextView::GetProperty );
-PropertyRegistration property8( typeRegistration, "line-height-offset", Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET, Property::FLOAT, &TextView::SetProperty, &TextView::GetProperty );
-PropertyRegistration property9( typeRegistration, "horizontal-alignment", Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
-PropertyRegistration property10( typeRegistration, "vertical-alignment", Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
-
-/**
- * Whether the text-view-processor operation sets, inserts, replaces, removes text.
- *
- * @param[in] metadata The text-view-processor operation.
- *
- * @return \e true if the given text-view-processor operation is modifying the text.
- */
-bool IsTextViewProcessorRelayoutOperation( const TextView::TextViewProcessorMetadata& metadata )
-{
- return ( ( metadata.mType == TextView::TextSet ) ||
- ( metadata.mType == TextView::TextInserted ) ||
- ( metadata.mType == TextView::TextReplaced ) ||
- ( metadata.mType == TextView::TextRemoved ) ||
- ( metadata.mType == TextView::NewStyle ));
-}
-
-/**
- * Whether the text-view-processor operation sets a new line height offset.
- *
- * @param[in] metadata The text-view-processor operation.
- *
- * @return \e true if the given text-view-processor operation sets a new line height offset.
- */
-bool IsTextViewProcessorLineHeightOffsetOperation( const TextView::TextViewProcessorMetadata& metadata )
-{
- return ( metadata.mType == TextView::NewLineHeight );
-}
-
-/**
- * Whether the text-view-processor operation sets a new style.
- *
- * @param[in] metadata The text-view-processor operation.
- *
- * @return \e true if the given text-view-processor operation sets a new style.
- */
-bool IsTextViewProcessorNewStyleOperation( const TextView::TextViewProcessorMetadata& metadata )
-{
- return ( metadata.mType == TextView::NewStyle );
-}
-
-} // namespace
-
-TextView::TextViewProcessorMetadata::TextViewProcessorMetadata()
-: mType( TextView::TextSet ),
- mPosition( 0u ),
- mNumberOfCharacters( 0u ),
- mText(),
- mStyleMask(TextStyle::NONE)
-{
-}
-
-Toolkit::TextView TextView::New()
-{
- // Create the implementation, temporarily owned on stack
- IntrusivePtr<TextView> textView = new TextView();
-
- // Pass ownership to CustomActor
- Toolkit::TextView handle( *textView );
-
- // Second-phase init of the implementation
- // This can only be done after the CustomActor connection has been made...
- textView->Initialize();
-
- // Disables by default the offscreen rendering.
- textView->SetSnapshotModeEnabled( false );
-
- return handle;
-}
-
-void TextView::SetText( const std::string& text )
-{
- // Creates a styled text with the markup or plain string.
- MarkupProcessor::StyledTextArray styledText;
- MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
-
- // Calls SetText() with the styled text array.
- SetText( styledText );
-}
-
-void TextView::SetText( const MarkupProcessor::StyledTextArray& text )
-{
- // mTextViewProcessorOperations stores the InsertTextAt and RemoveTextFrom operations to transform the initial text to mCurrentStyledText.
- // Once again, if a new text is set, any previous call to InsertTextAt or RemoveTextFrom can be discarted.
-
- std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorRelayoutOperation );
- mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
-
- // Creates metadata with the Set operation.
- TextViewProcessorMetadata metadata;
- metadata.mType = TextView::TextSet;
- metadata.mText = text;
-
- // Store metadata.
- mTextViewProcessorOperations.push_back( metadata );
-
- // Updates current styled text.
- mCurrentStyledText = text;
-
- // Request to be relaid out
- RelayoutRequest();
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
- mRelayoutOperations = RELAYOUT_ALL;
-}
-
-void TextView::InsertTextAt( std::size_t position, const std::string& text )
-{
- // Creates a styled text with the markup or plain string.
- MarkupProcessor::StyledTextArray styledText;
- MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
-
- // Calls InsertTextAt() with the styled text array.
- InsertTextAt( position, styledText );
-}
-
-void TextView::InsertTextAt( std::size_t position, const MarkupProcessor::StyledTextArray& text )
-{
- std::string textStr;
- MarkupProcessor::GetPlainString( text, textStr );
-
- if( TextProcessor::ContainsRightToLeftCharacter( Text( textStr ) ) ||
- TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) )
- {
- // Temporary fix. Creates the whole layout if there is rtl text.
-
- MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText;
- textToSet.insert( textToSet.begin() + position, text.begin(), text.end() );
- SetText( textToSet );
- }
- else
- {
- // Creates metadata with the Insert operation.
- TextViewProcessorMetadata metadata;
- metadata.mType = TextView::TextInserted;
- metadata.mPosition = position;
- metadata.mText = text;
-
- // Store metadata.
- mTextViewProcessorOperations.push_back( metadata );
-
- // Updates current styled text.
- mCurrentStyledText.insert( mCurrentStyledText.begin() + position, text.begin(), text.end() );
-
- // Request to be relaid out
- RelayoutRequest();
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
- mRelayoutOperations = RELAYOUT_ALL;
- }
-}
-
-void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text )
-{
- // Creates a styled text with the markup or plain string.
- MarkupProcessor::StyledTextArray styledText;
- MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
-
- // Calls ReplaceTextFromTo() with the styled text array.
- ReplaceTextFromTo( position, numberOfCharacters, styledText );
-}
-
-void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text )
-{
- std::string textStr;
- MarkupProcessor::GetPlainString( text, textStr );
-
- if( TextProcessor::ContainsRightToLeftCharacter( Text( textStr ) ) ||
- TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) )
- {
- // Temporary fix. Creates the whole layout if there is rtl text.
-
- // Updates current styled text.
- MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText;
-
- MarkupProcessor::StyledTextArray::iterator it = textToSet.begin() + position;
- textToSet.erase( it, it + numberOfCharacters );
- it = textToSet.begin() + position;
- textToSet.insert( it, text.begin(), text.end() );
-
- SetText( textToSet );
- }
- else
- {
- // Creates metadata with the Insert operation.
- TextViewProcessorMetadata metadata;
- metadata.mType = TextView::TextReplaced;
- metadata.mPosition = position;
- metadata.mNumberOfCharacters = numberOfCharacters;
- metadata.mText = text;
-
- // Store metadata.
- mTextViewProcessorOperations.push_back( metadata );
-
- // Updates current styled text.
- MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
- mCurrentStyledText.erase( it, it + numberOfCharacters );
- it = mCurrentStyledText.begin() + position;
- mCurrentStyledText.insert( it, text.begin(), text.end() );
-
- // Request to be relaid out
- RelayoutRequest();
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
- mRelayoutOperations = RELAYOUT_ALL;
- }
-}
-
-void TextView::RemoveTextFrom( std::size_t position, std::size_t numberOfCharacters )
-{
- if( TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) )
- {
- // Temporary fix. Creates the whole layout if there is rtl text.
-
- // Updates current styled text.
- MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText;
- MarkupProcessor::StyledTextArray::iterator it = textToSet.begin() + position;
- textToSet.erase( it, it + numberOfCharacters );
-
- SetText( textToSet );
- }
- else
- {
- // Creates metadata with the Remove operation.
- TextViewProcessorMetadata metadata;
- metadata.mType = TextView::TextRemoved;
- metadata.mPosition = position;
- metadata.mNumberOfCharacters = numberOfCharacters;
-
- // Store metadata.
- mTextViewProcessorOperations.push_back( metadata );
-
- // Updates current styled text.
- MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
- mCurrentStyledText.erase( it, it + numberOfCharacters );
-
- // Request to be relaid out
- RelayoutRequest();
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
- mRelayoutOperations = RELAYOUT_ALL;
- }
-}
-
-std::string TextView::GetText() const
-{
- // Traverses the styled text array getting only the text.
- // Note that for some languages a 'character' could be represented by more than one 'char'
-
- std::string text;
- for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); it != endIt; ++it )
- {
- text.append( (*it).mText.GetText() );
- }
-
- return text;
-}
-
-void TextView::SetLineHeightOffset( PointSize offset )
-{
- if( fabsf( mLayoutParameters.mLineHeightOffset - offset ) > Math::MACHINE_EPSILON_1000 )
- {
- // Removes any previous operation which modifies the line height offset.
- std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorLineHeightOffsetOperation );
- mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
-
- // Creates metadata with the new line height operation.
- TextViewProcessorMetadata metadata;
- metadata.mType = TextView::NewLineHeight;
-
- mTextViewProcessorOperations.push_back( metadata );
-
- // Updates line height offset.
- mLayoutParameters.mLineHeightOffset = offset;
-
- RelayoutRequest();
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
- if( RELAYOUT_ALL != mRelayoutOperations )
- {
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
- RELAYOUT_REMOVE_TEXT_ACTORS |
- RELAYOUT_SIZE_POSITION |
- RELAYOUT_ALIGNMENT |
- RELAYOUT_VISIBILITY |
- RELAYOUT_TEXT_ACTOR_UPDATE |
- RELAYOUT_INSERT_TO_TEXT_VIEW );
- }
- }
-}
-
-PointSize TextView::GetLineHeightOffset() const
-{
- return PointSize( mLayoutParameters.mLineHeightOffset );
-}
-
-void TextView::SetStyleToCurrentText( const TextStyle& style, TextStyle::Mask mask )
-{
- if( !mCurrentStyledText.empty() )
- {
- const bool checkFontName = mask & TextStyle::FONT;
- const bool checkFontSize = mask & TextStyle::SIZE;
- const bool checkFontStyle = mask & TextStyle::STYLE;
-
- // Check first if metrics have changed.
- bool metricsChanged = false;
- for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); ( it != endIt ) && !metricsChanged; ++it )
- {
- const MarkupProcessor::StyledText& styledText( *it );
-
- metricsChanged = ( checkFontName && ( styledText.mStyle.GetFontName() != style.GetFontName() ) ) ||
- ( checkFontStyle && ( styledText.mStyle.GetFontStyle() != style.GetFontStyle() ) ) ||
- ( checkFontSize && ( fabsf( styledText.mStyle.GetFontPointSize() - style.GetFontPointSize() ) > Math::MACHINE_EPSILON_1000 ) );
- }
-
- if( metricsChanged )
- {
- MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
-
- // If metrics change, new text measurements are needed.
- SetText( mCurrentStyledText );
- }
- else
- {
- // Deletes any previous operation which sets a new style.
- std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorNewStyleOperation );
- mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
-
- // Creates metadata with the new style operation.
- TextViewProcessorMetadata metadata;
- metadata.mType = TextView::NewStyle;
-
- MarkupProcessor::StyledText text;
- text.mStyle = style;
- metadata.mText.push_back( text );
- metadata.mStyleMask = mask;
-
- mTextViewProcessorOperations.push_back( metadata );
-
- MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
-
- RelayoutRequest();
-
- if( RELAYOUT_ALL != mRelayoutOperations )
- {
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
- RELAYOUT_TEXT_ACTOR_UPDATE );
- }
- }
- }
-
- // Sets the new style to the ellipsize text
- // TODO: fix this as a call to SetEllipsizeText will trigger the creation of new text actors.
- if( 0u < mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.Count() )
- {
- for( Vector<TextStyle*>::Iterator it = mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.Begin(),
- endIt = mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.End();
- it != endIt;
- ++it )
- {
- (*it)->Copy( style, mask );
- }
-
- SetEllipsizeText( mRelayoutData.mTextLayoutInfo.mEllipsisText, mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles );
- }
-}
-
-void TextView::SetTextAlignment( Toolkit::Alignment::Type align )
-{
- if( align != ( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment ) )
- {
- Toolkit::Alignment::Type horizontalAlignment( ( align & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
- ( align & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
- ( align & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
- Toolkit::Alignment::Type verticalAlignment( ( align & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
- ( align & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
- ( align & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
-
- mLayoutParameters.mHorizontalAlignment = horizontalAlignment;
- mLayoutParameters.mVerticalAlignment = verticalAlignment;
-
- RelayoutRequest();
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
- if( RELAYOUT_ALL != mRelayoutOperations )
- {
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
- RELAYOUT_TEXT_ACTOR_UPDATE |
- RELAYOUT_ALIGNMENT |
- RELAYOUT_VISIBILITY );
- }
- }
-}
-
-Toolkit::Alignment::Type TextView::GetTextAlignment() const
-{
- return static_cast<Toolkit::Alignment::Type>( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment );
-}
-
-void TextView::SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy )
-{
- if( policy != mLayoutParameters.mMultilinePolicy )
- {
- mLayoutParameters.mMultilinePolicy = policy;
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
- mRelayoutOperations = RELAYOUT_ALL;
-
- RelayoutRequest();
- }
-}
-
-Toolkit::TextView::MultilinePolicy TextView::GetMultilinePolicy() const
-{
- return mLayoutParameters.mMultilinePolicy;
-}
-
-void TextView::SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
-{
- // The layout info could be invalid depending on the current exceed policy and the new one.
- // i.e. if the current policy is Split and the new one is ShrinkToFit then
- // the layout info generated for each char is not needed.
- if( policy != mLayoutParameters.mWidthExceedPolicy )
- {
- mLayoutParameters.mWidthExceedPolicy = policy;
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
- mRelayoutOperations = RELAYOUT_ALL;
-
- RelayoutRequest();
- }
-}
-
-Toolkit::TextView::ExceedPolicy TextView::GetWidthExceedPolicy() const
-{
- return mLayoutParameters.mWidthExceedPolicy;
-}
-
-void TextView::SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
-{
- if( policy != mLayoutParameters.mHeightExceedPolicy )
- {
- mLayoutParameters.mHeightExceedPolicy = policy;
-
- RelayoutRequest();
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
- if( RELAYOUT_ALL != mRelayoutOperations )
- {
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
- RELAYOUT_REMOVE_TEXT_ACTORS |
- RELAYOUT_SIZE_POSITION |
- RELAYOUT_ALIGNMENT |
- RELAYOUT_VISIBILITY |
- RELAYOUT_TEXT_ACTOR_UPDATE |
- RELAYOUT_INSERT_TO_TEXT_VIEW );
- }
- }
-}
-
-Toolkit::TextView::ExceedPolicy TextView::GetHeightExceedPolicy() const
-{
- return mLayoutParameters.mHeightExceedPolicy;
-}
-
-void TextView::SetLineJustification( Toolkit::TextView::LineJustification justification )
-{
- if( justification != mLayoutParameters.mLineJustification )
- {
- mLayoutParameters.mLineJustification = justification;
-
- RelayoutRequest();
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
- if( RELAYOUT_ALL != mRelayoutOperations )
- {
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
- RELAYOUT_REMOVE_TEXT_ACTORS |
- RELAYOUT_SIZE_POSITION |
- RELAYOUT_ALIGNMENT |
- RELAYOUT_VISIBILITY |
- RELAYOUT_TEXT_ACTOR_UPDATE |
- RELAYOUT_INSERT_TO_TEXT_VIEW );
- }
- }
-}
-
-Toolkit::TextView::LineJustification TextView::GetLineJustification() const
-{
- return mLayoutParameters.mLineJustification;
-}
-
-void TextView::SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary )
-{
- if( ( fadeBoundary.mLeft != mVisualParameters.mFadeBoundary.mLeft ) ||
- ( fadeBoundary.mRight != mVisualParameters.mFadeBoundary.mRight ) ||
- ( fadeBoundary.mTop != mVisualParameters.mFadeBoundary.mTop ) ||
- ( fadeBoundary.mBottom != mVisualParameters.mFadeBoundary.mBottom ) )
- {
- mVisualParameters.mFadeBoundary = fadeBoundary;
-
- RelayoutRequest();
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
- if( RELAYOUT_ALL != mRelayoutOperations )
- {
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
- RELAYOUT_REMOVE_TEXT_ACTORS |
- RELAYOUT_VISIBILITY |
- RELAYOUT_TEXT_ACTOR_UPDATE |
- RELAYOUT_INSERT_TO_TEXT_VIEW );
- }
- }
-}
-
-const Toolkit::TextView::FadeBoundary& TextView::GetFadeBoundary() const
-{
- return mVisualParameters.mFadeBoundary;
-}
-
-void TextView::SetEllipsizeText( const std::string& ellipsizeText )
-{
- // Creates a styled text with the markup or plain string.
- MarkupProcessor::StyledTextArray styledText;
- MarkupProcessor::GetStyledTextArray( ellipsizeText, styledText, IsMarkupProcessingEnabled() );
-
- // Creates the ellipsis layout info and sets the text and styles.
- SetEllipsizeText( styledText );
-}
-
-void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText )
-{
- // Converts the styled text array into a Text and a vector of TextStyles.
- Text text;
- Vector<TextStyle*> styles;
- for( MarkupProcessor::StyledTextArray::const_iterator it = ellipsizeText.begin(), endIt = ellipsizeText.end(); it != endIt; ++it )
- {
- const MarkupProcessor::StyledText& styledText( *it );
-
- text.Append( styledText.mText );
- styles.PushBack( new TextStyle( styledText.mStyle ) );
- }
-
- // Creates the ellipsis layout info and sets the text and styles.
- SetEllipsizeText( text, styles );
-}
-
-void TextView::SetEllipsizeText( const Text& ellipsizeText, const Vector<TextStyle*>& ellipsizeStyles )
-{
- // Sets the text and styles for the ellipsis text.
- mRelayoutData.mTextLayoutInfo.mEllipsisText = ellipsizeText;
- mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles = ellipsizeStyles;
-
- // Creates the ellipsis layout info.
- CreateEllipsizeLayout();
-
- // Request to be relaid out
- RelayoutRequest();
-
- mRelayoutOperations = RELAYOUT_ALL;
-}
-
-std::string TextView::GetEllipsizeText() const
-{
- return mRelayoutData.mTextLayoutInfo.mEllipsisText.GetText();
-}
-
-void TextView::GetTextLayoutInfo()
-{
- const bool relayoutSizeAndPositionNeeded = mRelayoutOperations & RELAYOUT_SIZE_POSITION;
- const bool relayoutAlignmentNeeded = mRelayoutOperations & RELAYOUT_ALIGNMENT;
- const bool relayoutVisibilityNeeded = mRelayoutOperations & RELAYOUT_VISIBILITY;
-
- if( relayoutSizeAndPositionNeeded || relayoutAlignmentNeeded || relayoutVisibilityNeeded )
- {
- Vector3 textViewSize = GetControlSize();
-
- if( ( ( textViewSize.width < Math::MACHINE_EPSILON_1000 ) ||
- ( textViewSize.height < Math::MACHINE_EPSILON_1000 ) ) &&
- ( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
- ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
- ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) ) )
- {
- // In case the control size is not set but the layout settings are the default (split by new line character and original exceed policies)
- // the text natural size can be used.
- textViewSize = GetNaturalSize();
- }
-
- if( ( textViewSize.width > Math::MACHINE_EPSILON_1000 ) &&
- ( textViewSize.height > Math::MACHINE_EPSILON_1000 ) )
- {
- // Check if the text-view has glyph-actors.
- const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
-
- RelayoutOperationMask mask = NO_RELAYOUT;
- if( relayoutSizeAndPositionNeeded )
- {
- mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_SIZE_POSITION );
- }
- if( relayoutAlignmentNeeded )
- {
- mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_ALIGNMENT );
- }
- if( relayoutVisibilityNeeded )
- {
- mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_VISIBILITY );
- }
-
- if( hasGlyphActors )
- {
- // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
- // add them to the text-actor cache.
- TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
- mRelayoutData.mGlyphActors.clear();
- }
-
- // Relays-out but doesn't add glyph-actors to the text-view.
- DoRelayOut( textViewSize.GetVectorXY(), mask );
-
- if( hasGlyphActors )
- {
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
- }
- }
- }
-}
-
-void TextView::GetTextLayoutInfo( Toolkit::TextView::TextLayoutInfo& textLayoutInfo )
-{
- GetTextLayoutInfo();
-
- textLayoutInfo.mCharacterLayoutInfoTable = mRelayoutData.mCharacterLayoutInfoTable;
- textLayoutInfo.mLines = mRelayoutData.mLines;
-
- textLayoutInfo.mCharacterLogicalToVisualMap = mRelayoutData.mCharacterLogicalToVisualMap;
- textLayoutInfo.mCharacterVisualToLogicalMap = mRelayoutData.mCharacterVisualToLogicalMap;
-
- textLayoutInfo.mTextSize = mRelayoutData.mTextSizeForRelayoutOption;
-
- textLayoutInfo.mScrollOffset = mVisualParameters.mCameraScrollPosition;
-}
-
-void TextView::SetSortModifier( float depthOffset )
-{
- mVisualParameters.mSortModifier = depthOffset;
-
- for( std::vector<RenderableActor>::iterator it = mRelayoutData.mGlyphActors.begin(), endIt = mRelayoutData.mGlyphActors.end();
- it != endIt;
- ++it )
- {
- ( *it ).SetSortModifier( depthOffset );
- }
-
- if( mOffscreenImageActor )
- {
- mOffscreenImageActor.SetSortModifier( depthOffset );
- }
-}
-
-void TextView::SetSnapshotModeEnabled( bool enable )
-{
- if( enable != mVisualParameters.mSnapshotModeEnabled )
- {
- // Remove first all glyph-actors
- if( !mRelayoutData.mGlyphActors.empty() )
- {
- TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
- }
-
- mVisualParameters.mSnapshotModeEnabled = enable;
- if( !mLockPreviousSnapshotMode )
- {
- // mPreviousSnapshotModeEnabled stores the snapshot mode value before SetScrollEnabled( true ) is
- // called. However, if SetSnapshotModeEnabled() is called after SetScrollEnabled() then the stored value
- // is updated.
- // As SetSnapshotModeEnabled() is also called from SetScrollEnabled(), the mLockPreviousSnapshotMode prevents
- // to smash the stored value.
- mPreviousSnapshotModeEnabled = enable;
- }
-
- if( mVisualParameters.mSnapshotModeEnabled )
- {
- // Create a root actor and an image actor for offscreen rendering.
- mOffscreenRootActor = Layer::New();
- mOffscreenImageActor = ImageActor::New();
-
- mOffscreenRootActor.SetColorMode( USE_OWN_COLOR );
- mOffscreenRootActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
- mOffscreenRootActor.SetInheritRotation( false );
- mOffscreenRootActor.SetInheritScale( false );
- mOffscreenRootActor.SetDepthTestDisabled( true );
-
- mOffscreenRootActor.SetPosition( 0.f, 0.f, 0.f );
-
- mOffscreenImageActor.SetAnchorPoint( ParentOrigin::CENTER );
- mOffscreenImageActor.SetParentOrigin( ParentOrigin::CENTER );
- mOffscreenImageActor.SetBlendFunc( BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA,
- BlendingFactor::ONE, BlendingFactor::ONE );
-
- Actor self = Self();
- self.Add( mOffscreenRootActor );
- self.Add( mOffscreenImageActor );
- mOffscreenImageActor.SetScale( Vector3( 1.f, -1.f, 1.f ) );
- }
- else
- {
- Actor self = Self();
-
- if( mOffscreenRootActor )
- {
- self.Remove( mOffscreenRootActor );
- }
-
- if( mOffscreenImageActor )
- {
- self.Remove( mOffscreenImageActor );
- }
-
- DestroyOffscreenRenderingResources();
- }
-
- if( RELAYOUT_ALL != mRelayoutOperations )
- {
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
- RELAYOUT_REMOVE_TEXT_ACTORS |
- RELAYOUT_TEXT_ACTOR_UPDATE |
- RELAYOUT_INSERT_TO_TEXT_VIEW );
- }
- RelayoutRequest();
- }
-}
-
-bool TextView::IsSnapshotModeEnabled() const
-{
- return mVisualParameters.mSnapshotModeEnabled;
-}
-
-void TextView::SetMarkupProcessingEnabled( bool enable )
-{
- mMarkUpEnabled = enable;
-}
-
-bool TextView::IsMarkupProcessingEnabled() const
-{
- return mMarkUpEnabled;
-}
-
-void TextView::SetScrollEnabled( bool enable )
-{
- if( enable != mVisualParameters.mScrollEnabled )
- {
- mVisualParameters.mScrollEnabled = enable;
-
- if( mVisualParameters.mScrollEnabled )
- {
- // Offscreen rendering is needed to enable text scroll.
-
- // Stores previous value of the snapshot mode.
- mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
-
- {
- // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
- // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
- Lock lock( mLockPreviousSnapshotMode );
- SetSnapshotModeEnabled( true );
- }
-
- // Creates the pan gesture detector and attach the text-view.
- mPanGestureDetector = PanGestureDetector::New();
- mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
- mPanGestureDetector.Attach( Self() );
- }
- else
- {
- // Removes the pan gesture detector.
- if( mPanGestureDetector )
- {
- mPanGestureDetector.Detach( Self() );
- mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
- mPanGestureDetector.Reset();
- }
-
- // Restores the previous state for snapshot mode.
- SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
- }
- }
-}
-
-bool TextView::IsScrollEnabled() const
-{
- return mVisualParameters.mScrollEnabled;
-}
-
-void TextView::SetScrollPosition( const Vector2& position )
-{
- if( position != mVisualParameters.mCameraScrollPosition )
- {
- // Guard against destruction during signal emission
- // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
- Toolkit::TextView handle( GetOwner() );
-
- DoSetScrollPosition( position );
-
- // Check if the new scroll position has been trimmed.
- mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
- }
-}
-
-const Vector2& TextView::GetScrollPosition() const
-{
- return mVisualParameters.mCameraScrollPosition;
-}
-
-bool TextView::IsScrollPositionTrimmed() const
-{
- return mVisualParameters.mScrollPositionTrimmed;
-}
-
-Toolkit::TextView::ScrolledSignalType& TextView::ScrolledSignal()
-{
- return mScrolledSignal;
-}
-
-bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
-{
- Dali::BaseHandle handle( object );
-
- bool connected( true );
- Toolkit::TextView textView = Toolkit::TextView::DownCast( handle );
-
- if( 0 == strcmp( signalName.c_str(), SIGNAL_TEXT_SCROLLED ) )
- {
- textView.ScrolledSignal().Connect( tracker, functor );
- }
- else
- {
- // signalName does not match any signal
- connected = false;
- }
-
- return connected;
-}
-
-TextView::LayoutParameters::LayoutParameters()
-: mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
- mExceedPolicy( TextView::Original ),
- mWidthExceedPolicy( Toolkit::TextView::Original ),
- mHeightExceedPolicy( Toolkit::TextView::Original ),
- mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
- mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
- mLineJustification( Toolkit::TextView::Left ),
- mLineHeightOffset( 0.f ),
- mMarkUpEnabled( false )
-{
-}
-
-TextView::LayoutParameters::~LayoutParameters()
-{
-}
-
-TextView::LayoutParameters::LayoutParameters( Toolkit::TextView::MultilinePolicy multilinePolicy,
- Toolkit::TextView::ExceedPolicy widthExceedPolicy,
- Toolkit::TextView::ExceedPolicy heightExceedPolicy,
- Toolkit::Alignment::Type alignmentType,
- Toolkit::TextView::LineJustification lineJustification,
- float lineHeightOffset,
- bool markUpEnabled )
-: mMultilinePolicy( multilinePolicy ),
- mExceedPolicy( TextView::Original ),
- mWidthExceedPolicy( widthExceedPolicy ),
- mHeightExceedPolicy( heightExceedPolicy ),
- mHorizontalAlignment(),
- mVerticalAlignment(),
- mLineJustification( lineJustification ),
- mLineHeightOffset( lineHeightOffset ),
- mMarkUpEnabled( markUpEnabled )
-{
- // Sets alignment
- Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
- ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
- ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
- Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
- ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
- ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
-
- mHorizontalAlignment = horizontalAlignment;
- mVerticalAlignment = verticalAlignment;
-}
-
-TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
-: mMultilinePolicy( layoutParameters.mMultilinePolicy ),
- mExceedPolicy( TextView::Original ),
- mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ),
- mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ),
- mHorizontalAlignment( layoutParameters.mHorizontalAlignment ),
- mVerticalAlignment( layoutParameters.mVerticalAlignment ),
- mLineJustification( layoutParameters.mLineJustification ),
- mLineHeightOffset( layoutParameters.mLineHeightOffset ),
- mMarkUpEnabled( layoutParameters.mMarkUpEnabled )
-{
-}
-
-TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
-{
- mMultilinePolicy = layoutParameters.mMultilinePolicy;
- mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
- mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
- mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
- mVerticalAlignment = layoutParameters.mVerticalAlignment;
- mLineJustification = layoutParameters.mLineJustification;
- mLineHeightOffset = layoutParameters.mLineHeightOffset;
- mMarkUpEnabled = layoutParameters.mMarkUpEnabled;
-
- return *this;
-}
-
-TextView::VisualParameters::VisualParameters()
-: mFadeBoundary(),
- mSortModifier( 0.f ),
- mCameraScrollPosition( 0.f, 0.f ),
- mSnapshotModeEnabled( false ),
- mScrollEnabled( false ),
- mScrollPositionTrimmed( false )
-{
-}
-
-TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
-: mFadeBoundary( visualParameters.mFadeBoundary ),
- mSortModifier( visualParameters.mSortModifier ),
- mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
- mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
- mScrollEnabled( visualParameters.mScrollEnabled ),
- mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
-{
-}
-
-TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
-{
- mFadeBoundary = visualParameters.mFadeBoundary;
- mSortModifier = visualParameters.mSortModifier;
- mCameraScrollPosition = visualParameters.mCameraScrollPosition;
- mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
- mScrollEnabled = visualParameters.mScrollEnabled;
- mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
-
- return *this;
-}
-
-TextView::RelayoutData::RelayoutData()
-: mTextViewSize(),
- mShrinkFactor( 1.f ),
- mTextLayoutInfo(),
- mCharacterLogicalToVisualMap(),
- mCharacterVisualToLogicalMap(),
- mGlyphActors(),
- mCharacterLayoutInfoTable(),
- mLines(),
- mTextSizeForRelayoutOption()
-{
-}
-
-TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
-: mTextViewSize( relayoutData.mTextViewSize ),
- mShrinkFactor( relayoutData.mShrinkFactor ),
- mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
- mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
- mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
- mGlyphActors( relayoutData.mGlyphActors ),
- mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
- mLines( relayoutData.mLines ),
- mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
-{
-}
-
-TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
-{
- mTextViewSize = relayoutData.mTextViewSize;
- mShrinkFactor = relayoutData.mShrinkFactor;
- mTextLayoutInfo = relayoutData.mTextLayoutInfo;
- mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
- mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
- mGlyphActors = relayoutData.mGlyphActors;
- mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
- mLines = relayoutData.mLines;
- mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
-
- return *this;
-}
-
-TextView::TextView()
-: Control( REQUIRES_STYLE_CHANGE_SIGNALS ),
- mCurrentStyledText(),
- mTextViewProcessorOperations(),
- mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
- Toolkit::TextView::Original,
- Toolkit::TextView::Original,
- static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
- Toolkit::TextView::Left,
- PointSize( 0.f ),
- false ),
- mVisualParameters(),
- mRelayoutData(),
- mRelayoutOperations( NO_RELAYOUT ),
- mOffscreenRootActor(),
- mOffscreenImageActor(),
- mOffscreenCameraActor(),
- mCurrentOffscreenSize(),
- mFrameBufferImage(),
- mRenderTask(),
- mPanGestureDetector(),
- mLockPreviousSnapshotMode( false ),
- mPreviousSnapshotModeEnabled( false ),
- mMarkUpEnabled( false )
-{
- // Creates the ellipsis layout info.
- CreateEllipsizeLayout();
-}
-
-TextView::~TextView()
-{
- // Destroys offscreen rendering resources.
- DestroyOffscreenRenderingResources();
-
- // Destroys scroll pan gesture detector.
- if( mPanGestureDetector )
- {
- mPanGestureDetector.Reset();
- }
-}
-
-Vector3 TextView::GetNaturalSize()
-{
- if( !mTextViewProcessorOperations.empty() )
- {
- // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
-
- if( !mRelayoutData.mGlyphActors.empty() )
- {
- // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
- // add them to the text-actor cache.
- TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
- mRelayoutData.mGlyphActors.clear();
-
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
- }
-
- PerformTextViewProcessorOperations();
- }
-
- return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
-}
-
-float TextView::GetHeightForWidth( float width )
-{
- float height = 0.f;
-
- if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
- ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
- ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
- {
- // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
- // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
- height = GetNaturalSize().height;
- }
- else
- {
- // Check if the given width is different than the current one.
- const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
-
- // Check if the text-view has glyph-actors.
- const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
-
- // Check which layout operations need to be done.
- const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
-
- if( relayoutSizeAndPositionNeeded )
- {
- if( hasGlyphActors )
- {
- // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
- // add them to the text-actor cache.
- TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
- mRelayoutData.mGlyphActors.clear();
- }
-
- // Use the given width.
- const Vector2 textViewSize( width, GetControlSize().height );
-
- // Relays-out but doesn't add glyph-actors to the text-view.
- DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
- }
-
- // Retrieve the text height after relayout the text.
- height = mRelayoutData.mTextSizeForRelayoutOption.height;
-
- if( differentWidth )
- {
- // Revert the relayout operation mask
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
- }
-
- if( hasGlyphActors )
- {
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
- }
-
- if( differentWidth || hasGlyphActors )
- {
- RelayoutRequest();
- }
- }
-
- return height;
-}
-
-float TextView::GetWidthForHeight( float height )
-{
- // TODO: Needs implementing properly, for now just return the natural width.
- return GetNaturalSize().width;
-}
-
-
-void TextView::OnInitialize()
-{
-}
-
-
-void TextView::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
-{
- // Creates the ellipsis layout info.
- CreateEllipsizeLayout();
-
- SetText( mCurrentStyledText );
-}
-
-void TextView::OnControlSizeSet( const Vector3& size )
-{
- if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
- {
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
- mRelayoutOperations = RELAYOUT_ALL;
-
- // Request to be relaid out
- RelayoutRequest();
- }
-}
-
-void TextView::OnRelayout( const Vector2& size, ActorSizeContainer& container )
-{
- if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
- {
- // Not worth to relayout if width or height is equal to zero.
- return;
- }
-
- if( size != mRelayoutData.mTextViewSize )
- {
- // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed.
- if( RELAYOUT_ALL != mRelayoutOperations )
- {
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
- RELAYOUT_REMOVE_TEXT_ACTORS |
- RELAYOUT_SIZE_POSITION |
- RELAYOUT_ALIGNMENT |
- RELAYOUT_VISIBILITY |
- RELAYOUT_TEXT_ACTOR_UPDATE |
- RELAYOUT_INSERT_TO_TEXT_VIEW );
- }
- }
-
- if( ( Toolkit::TextView::Fade == mLayoutParameters.mWidthExceedPolicy ) ||
- ( Toolkit::TextView::Fade == mLayoutParameters.mHeightExceedPolicy ) )
- {
- if( mRelayoutOperations & RELAYOUT_ALIGNMENT )
- {
- // If the text of the alignment changes and a fade exceed policy is set,
- // some characters may need new TextActor.
- mRelayoutOperations = RELAYOUT_ALL;
- }
- }
-
- // Remove glyph-actors from text-view
- if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
- {
- TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
- mRelayoutData.mGlyphActors.clear();
- }
-
- if( NO_RELAYOUT != mRelayoutOperations )
- {
- // Relays-out and add glyph-actors to the text-view.
- DoRelayOut( size, mRelayoutOperations );
- ProcessSnapshot( size );
- }
-
- // Quite likely the texts of the text-actors are not going to be reused, so clear them.
- mRelayoutData.mTextActorCache.ClearTexts();
-}
-
-void TextView::PerformTextViewProcessorOperations()
-{
- // Traverse the relayout operation vector ...
-
- // Optimizes some operations.
- OptimizeTextViewProcessorOperations();
-
- for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
- {
- const TextViewProcessorMetadata& relayoutMetadata( *it );
-
- switch( relayoutMetadata.mType )
- {
- case TextView::TextSet:
- {
- TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
- mLayoutParameters,
- mRelayoutData );
- break;
- }
- case TextView::TextInserted:
- {
- TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
- relayoutMetadata.mText,
- mLayoutParameters,
- mRelayoutData );
- break;
- }
- case TextView::TextReplaced:
- {
- TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
- relayoutMetadata.mNumberOfCharacters,
- relayoutMetadata.mText,
- mLayoutParameters,
- mRelayoutData );
- break;
- }
- case TextView::TextRemoved:
- {
- TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
- relayoutMetadata.mNumberOfCharacters,
- mLayoutParameters,
- mRelayoutData,
- TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
- break;
- }
- case TextView::NewLineHeight:
- {
- TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
- mRelayoutData.mTextLayoutInfo );
- break;
- }
- case TextView::NewStyle:
- {
- TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
- relayoutMetadata.mStyleMask,
- mRelayoutData );
- break;
- }
- }
- }
-
- // Clear all operations when they are done.
- mTextViewProcessorOperations.clear();
-}
-
-void TextView::OptimizeTextViewProcessorOperations()
-{
- // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
-
- // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
- // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
- // use the cache without clearing the text-actors.
-
- std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
-
- for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
- {
- const TextViewProcessorMetadata& relayoutMetadata( *it );
-
- switch( relayoutMetadata.mType )
- {
- case TextView::TextRemoved:
- {
- bool optimizationDone = false;
-
- if( it + 1u != endIt )
- {
- const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1u ) );
- if( TextView::TextInserted == nextRelayoutMetadata.mType )
- {
- if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
- {
- optimizationDone = true;
- TextViewProcessorMetadata newRelayoutMetadata;
- newRelayoutMetadata.mType = TextView::TextReplaced;
- newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
- newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
- newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
- textViewProcessorOperations.push_back( newRelayoutMetadata );
-
- // do not access the TextInserted operation in next iteration.
- ++it;
- }
- }
- }
-
- if( !optimizationDone )
- {
- textViewProcessorOperations.push_back( relayoutMetadata );
- }
- break;
- }
- default:
- {
- textViewProcessorOperations.push_back( relayoutMetadata );
- }
- }
- }
-
- mTextViewProcessorOperations = textViewProcessorOperations;
-}
-
-void TextView::DoRelayOut( const Size& textViewSize, RelayoutOperationMask relayoutOperationMask )
-{
- // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures.
- if( !mTextViewProcessorOperations.empty() )
- {
- PerformTextViewProcessorOperations();
- }
-
- CombineExceedPolicies();
-
- Actor rootActor;
- if( mVisualParameters.mSnapshotModeEnabled )
- {
- rootActor = mOffscreenRootActor;
- }
- else
- {
- rootActor = Self();
- }
-
- mRelayoutData.mTextViewSize = textViewSize;
- switch( mLayoutParameters.mMultilinePolicy )
- {
- case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
- {
- SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
- break;
- } // SplitByNewLineChar
-
- case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
- {
- SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
- break;
- } // SplitByWord
-
- case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
- {
- SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
- break;
- } // SplitByChar
- } // switch( mMultilinePolicy )
-
- // Remove done operations from the mask.
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
-}
-
-void TextView::ProcessSnapshot( const Size& textViewSize )
-{
- if( mVisualParameters.mSnapshotModeEnabled )
- {
- // If layout options change, it's needed generate a new image.
-
- if( mOffscreenRootActor )
- {
- // Set the root actor visible.
- // The root actor is set to non visible after the render task is processed.
- mOffscreenRootActor.SetVisible( true );
-
- // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
- mOffscreenRootActor.SetSize( textViewSize );
- }
-
- if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
- ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
- {
- // Set the image actor visible.
- // The image actor is set to non visible if there is no text to render.
- mOffscreenImageActor.SetVisible( true );
-
- // Calculates the offscreen image's size. It takes into account different points:
- // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
- // * There is a maximum texture size the graphic subsystem can load on the memory.
- // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
-
- const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
- mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
- std::min( MAX_OFFSCREEN_RENDERING_SIZE,
- mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
-
- const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
-
- if( sizeChanged )
- {
- // Creates a frame buffer for offscreen rendering when the size is negotiated.
- mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
- offscreenSize.height,
- Pixel::RGBA8888 );
-
- // Stores current text-view size to avoid create new Dali resources if text changes.
- mCurrentOffscreenSize = offscreenSize;
-
- if( !mOffscreenCameraActor )
- {
- // Creates a new camera actor.
- mOffscreenCameraActor = CameraActor::New();
- mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
- mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
- mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
-
- mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
-
- mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
- }
-
- // Calculate camera parameters for current text size.
- mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
- }
-
- if( mVisualParameters.mScrollEnabled )
- {
- // Updates the offscreen camera position with the new scroll offset.
- mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
- mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
- }
- else
- {
- // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
- AlignOffscreenCameraActor( textViewSize, offscreenSize );
- }
-
- if( !mRenderTask )
- {
- // Creates a new render task.
- mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
-
- mRenderTask.SetSourceActor( mOffscreenRootActor );
- mRenderTask.SetInputEnabled( false );
- mRenderTask.SetClearColor( Color::TRANSPARENT );
- mRenderTask.SetClearEnabled( true );
- mRenderTask.SetExclusive( true );
-
- // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
- mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
- }
-
- if( sizeChanged )
- {
- mRenderTask.SetCameraActor( mOffscreenCameraActor );
- mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
- }
-
- // Process the render task only once every time the text changes or the text-view's size canges.
- mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
- }
- else
- {
- // If there is no text just make any previous generated image invisible instead to process a render task with no text.
- mOffscreenImageActor.SetVisible( false );
- }
- }
-}
-
-void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
-{
- float xPosition = 0.f;
- float yPosition = 0.f;
- Vector3 parentOrigin = ParentOrigin::CENTER;
- Vector3 anchorPoint = AnchorPoint::CENTER;
-
- switch( mLayoutParameters.mHorizontalAlignment )
- {
- case Toolkit::Alignment::HorizontalLeft:
- {
- xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
- parentOrigin.x = 0.f;
- anchorPoint.x = 0.f;
- break;
- }
- case Toolkit::Alignment::HorizontalCenter:
- {
- // nothing to do.
- break;
- }
- case Toolkit::Alignment::HorizontalRight:
- {
- xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
- parentOrigin.x = 1.f;
- anchorPoint.x = 1.f;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
- }
- }
-
- switch( mLayoutParameters.mVerticalAlignment )
- {
- case Toolkit::Alignment::VerticalTop:
- {
- yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
- parentOrigin.y = 0.f;
- anchorPoint.y = 0.f;
- break;
- }
- case Toolkit::Alignment::VerticalCenter:
- {
- // nothing to do.
- break;
- }
- case Toolkit::Alignment::VerticalBottom:
- {
- yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
- parentOrigin.y = 1.f;
- anchorPoint.y = 1.f;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
- }
- }
-
- mOffscreenCameraActor.SetX( xPosition );
- mOffscreenCameraActor.SetY( yPosition );
-
- mOffscreenImageActor.SetParentOrigin( parentOrigin );
- mOffscreenImageActor.SetAnchorPoint( anchorPoint );
-}
-
-void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
-{
- // not to process the offscreen root actor by setting its visibility to false.
- mOffscreenRootActor.SetVisible( false );
-
- // Sets the new size and the new frame buffer to the image actor.
- // Image actor must have same size as text. Otherwise text can be truncated.
- mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
- mOffscreenImageActor.SetImage( mFrameBufferImage );
-}
-
-void TextView::DestroyOffscreenRenderingResources()
-{
- if( mRenderTask )
- {
- mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
-
- if( Stage::IsInstalled() )
- {
- Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
- }
-
- mRenderTask.Reset();
- }
-
- // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
- if( mOffscreenCameraActor )
- {
- mOffscreenRootActor.Remove( mOffscreenCameraActor );
-
- mOffscreenCameraActor.Reset();
- }
-
- if( mOffscreenRootActor )
- {
- mOffscreenRootActor.Reset();
- }
-
- if( mOffscreenImageActor )
- {
- mOffscreenImageActor.Reset();
- }
-
- mCurrentOffscreenSize = Size( 0.f, 0.f );
-
- if( mFrameBufferImage )
- {
- mFrameBufferImage.Reset();
- }
-}
-
-void TextView::OnTextPan( Actor actor, const PanGesture& gesture )
-{
- if( 1u == gesture.numberOfTouches )
- {
- DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
- }
-}
-
-void TextView::TrimScrollPosition()
-{
- const Vector3& textViewSize = GetControlSize();
-
- // Before use the text's size, relayout the text is needed to get the actual text size.
- GetTextLayoutInfo();
-
- // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
- float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
- float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
- float minHorizontalDisplacement = -maxHorizontalDisplacement;
- float minVerticalDisplacement = -maxVerticalDisplacement;
-
- // Updates the range if the text is aligned on the right or left.
- switch( mLayoutParameters.mHorizontalAlignment )
- {
- case Toolkit::Alignment::HorizontalLeft:
- {
- maxHorizontalDisplacement *= 2.f;
- minHorizontalDisplacement = 0.f;
- break;
- }
- case Toolkit::Alignment::HorizontalCenter:
- {
- // nothing to do.
- break;
- }
- case Toolkit::Alignment::HorizontalRight:
- {
- maxHorizontalDisplacement = 0.f;
- minHorizontalDisplacement *= 2.f;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
- }
- }
-
- // Updates the range if the text is aligned on the top or bottom.
- switch( mLayoutParameters.mVerticalAlignment )
- {
- case Toolkit::Alignment::VerticalTop:
- {
- maxVerticalDisplacement *= 2.f;
- minVerticalDisplacement = 0.f;
- break;
- }
- case Toolkit::Alignment::VerticalCenter:
- {
- //nothing to do
- break;
- }
- case Toolkit::Alignment::VerticalBottom:
- {
- maxVerticalDisplacement = 0.f;
- minVerticalDisplacement *= 2.f;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
- }
- }
-
- // Trims the scroll position to be within the range.
- mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
- mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
-
- mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
- mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
-}
-
-void TextView::DoSetScrollPosition( const Vector2& position )
-{
- // Stores old scroll position.
- Vector2 delta( mVisualParameters.mCameraScrollPosition );
-
- // Updates the scroll position
- mVisualParameters.mCameraScrollPosition = position;
-
- // Ensures the text-view is covered with text.
- TrimScrollPosition();
-
- // Calculate the difference with the previous scroll position
- delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
- delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
-
- if( mOffscreenRootActor )
- {
- // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be
- // set to visible.
- mOffscreenRootActor.SetVisible( true );
- }
-
- if( mOffscreenCameraActor )
- {
- // Update the offscreen camera with the new scroll position.
- mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
- mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
- }
-
- if( mRenderTask )
- {
- // Refresh the render-task.
- mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
- }
-
- // Emit the signal.
- Toolkit::TextView handle( GetOwner() );
- mScrolledSignal.Emit( handle, delta );
-}
-
-void TextView::CombineExceedPolicies()
-{
- // Calculates the combination of exceed policies.
-
- switch( mLayoutParameters.mWidthExceedPolicy )
- {
- case Toolkit::TextView::Original:
- {
- switch( mLayoutParameters.mHeightExceedPolicy )
- {
- case Toolkit::TextView::Original:
- {
- mLayoutParameters.mExceedPolicy = Original;
- break;
- }
- case Toolkit::TextView::Fade:
- {
- mLayoutParameters.mExceedPolicy = OriginalFade;
- break;
- }
- case Toolkit::TextView::ShrinkToFit:
- {
- mLayoutParameters.mExceedPolicy = OriginalShrink;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
- }
- }
- break;
- }
- case Toolkit::TextView::Split:
- {
- switch( mLayoutParameters.mHeightExceedPolicy )
- {
- case Toolkit::TextView::Original:
- {
- mLayoutParameters.mExceedPolicy = SplitOriginal;
- break;
- }
- case Toolkit::TextView::Fade:
- {
- mLayoutParameters.mExceedPolicy = SplitFade;
- break;
- }
- case Toolkit::TextView::ShrinkToFit:
- {
- mLayoutParameters.mExceedPolicy = SplitShrink;
- break;
- }
- case Toolkit::TextView::EllipsizeEnd:
- {
- mLayoutParameters.mExceedPolicy = SplitEllipsizeEnd;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
- }
- }
- break;
- }
- case Toolkit::TextView::Fade:
- {
- switch( mLayoutParameters.mHeightExceedPolicy )
- {
- case Toolkit::TextView::Original:
- {
- mLayoutParameters.mExceedPolicy = FadeOriginal;
- break;
- }
- case Toolkit::TextView::Fade:
- {
- mLayoutParameters.mExceedPolicy = Fade;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
- }
- }
- break;
- }
- case Toolkit::TextView::ShrinkToFit:
- {
- switch( mLayoutParameters.mHeightExceedPolicy )
- {
- case Toolkit::TextView::Original:
- {
- mLayoutParameters.mExceedPolicy = ShrinkOriginal;
- break;
- }
- case Toolkit::TextView::Fade:
- {
- mLayoutParameters.mExceedPolicy = ShrinkFade;
- break;
- }
- case Toolkit::TextView::ShrinkToFit:
- {
- mLayoutParameters.mExceedPolicy = Shrink;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
- }
- }
- break;
- }
- case Toolkit::TextView::EllipsizeEnd:
- {
- switch( mLayoutParameters.mHeightExceedPolicy )
- {
- case Toolkit::TextView::Original:
- {
- mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
- break;
- }
- case Toolkit::TextView::EllipsizeEnd:
- {
- mLayoutParameters.mExceedPolicy = EllipsizeEnd;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
- }
- }
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
- }
- }
-}
-
-Actor TextView::GetRootActor() const
-{
- // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
-
- Actor rootActor;
-
- if( mVisualParameters.mSnapshotModeEnabled )
- {
- rootActor = mOffscreenRootActor;
- }
- else
- {
- rootActor = Self();
- }
-
- return rootActor;
-}
-
-void TextView::CreateEllipsizeLayout()
-{
- // Creates the ellipsis layout info for the ellipsis text and styles.
- mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
- mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo.mCharactersLayoutInfo.resize( mRelayoutData.mTextLayoutInfo.mEllipsisText.GetLength(), TextViewProcessor::CharacterLayoutInfo() );
- TextViewProcessor::CreateWordTextInfo( mRelayoutData.mTextLayoutInfo.mEllipsisText,
- mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles,
- mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
-}
-
-void TextView::OnMarkupEnabledPeopertySet( Property::Value propertyValue )
-{
- bool newValue( propertyValue.Get<bool>() );
- if( newValue != IsMarkupProcessingEnabled() )
- {
- SetMarkupProcessingEnabled( newValue );
- if( newValue )
- {
- // If markup processing has been enabled, Ensure current text is reprocessed.
- const std::string& currentText( GetText() );
- if( ! currentText.empty() )
- {
- SetText( currentText );
- }
- }
- }
-}
-
-void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
-{
- std::string policyName( propertyValue.Get<std::string>() );
- if(policyName == "SplitByNewLineChar")
- {
- SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
- }
- else if(policyName == "SplitByWord")
- {
- SetMultilinePolicy(Toolkit::TextView::SplitByWord);
- }
- else if(policyName == "SplitByChar")
- {
- SetMultilinePolicy(Toolkit::TextView::SplitByChar);
- }
- else
- {
- DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
- }
-}
-
-void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
-{
- std::string policyName( propertyValue.Get<std::string>() );
- if(policyName == "Original")
- {
- SetWidthExceedPolicy(Toolkit::TextView::Original);
- }
- else if(policyName == "Fade")
- {
- SetWidthExceedPolicy(Toolkit::TextView::Fade);
- }
- else if(policyName == "Split")
- {
- SetWidthExceedPolicy(Toolkit::TextView::Split);
- }
- else if(policyName == "ShrinkToFit")
- {
- SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
- }
- else if(policyName == "EllipsizeEnd")
- {
- SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
- }
- else
- {
- DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
- }
-}
-
-void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
-{
- std::string policyName( propertyValue.Get<std::string>() );
- if(policyName == "Original")
- {
- SetHeightExceedPolicy(Toolkit::TextView::Original);
- }
- else if(policyName == "Fade")
- {
- SetHeightExceedPolicy(Toolkit::TextView::Fade);
- }
- else if(policyName == "Split")
- {
- SetHeightExceedPolicy(Toolkit::TextView::Split);
- }
- else if(policyName == "ShrinkToFit")
- {
- SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
- }
- else
- {
- DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
- }
-}
-
-void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
-{
- std::string policyName( propertyValue.Get<std::string>() );
- if(policyName == "Left")
- {
- SetLineJustification(Toolkit::TextView::Left);
- }
- else if(policyName == "Center")
- {
- SetLineJustification(Toolkit::TextView::Center);
- }
- else if(policyName == "Right")
- {
- SetLineJustification(Toolkit::TextView::Right);
- }
- else if(policyName == "Justified")
- {
- SetLineJustification(Toolkit::TextView::Justified);
- }
- else
- {
- DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
- }
-}
-
-void TextView::OnFadeBoundaryPropertySet( Property::Value propertyValue )
-{
- Vector4 value( propertyValue.Get<Vector4>() );
- DALI_ASSERT_ALWAYS( ( value.x >= 0.f ) && ( value.y >= 0.f ) && ( value.z >= 0.f ) && ( value.w >= 0.f )
- && "TextView::OnFadeBoundaryPropertySet(). Negative value is invalid. " );
-
- Toolkit::TextView::FadeBoundary fadeBoundary( PixelSize( static_cast<unsigned int>( value.x ) ),
- PixelSize( static_cast<unsigned int>( value.y ) ),
- PixelSize( static_cast<unsigned int>( value.z ) ),
- PixelSize( static_cast<unsigned int>( value.w ) ) );
-
- SetFadeBoundary( fadeBoundary );
-}
-
-void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
-{
- std::string value( propertyValue.Get<std::string>() );
-
- if( propertyIndex == Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT )
- {
- if(value == "HorizontalLeft")
- {
- mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
- }
- else if( value == "HorizontalCenter")
- {
- mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
- }
- else if( value == "HorizontalRight")
- {
- mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
- }
- else
- {
- DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
- }
- }
- else if( propertyIndex == Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT )
- {
- if( value == "VerticalTop" )
- {
- mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
- }
- else if( value == "VerticalCenter")
- {
- mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
- }
- else if( value == "VerticalBottom")
- {
- mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
- }
- else
- {
- DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
- }
- }
-
- RelayoutRequest();
-
- // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
- if( RELAYOUT_ALL != mRelayoutOperations )
- {
- mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
- RELAYOUT_TEXT_ACTOR_UPDATE |
- RELAYOUT_ALIGNMENT |
- RELAYOUT_VISIBILITY );
- }
-}
-
-std::string TextView::OnHorizontalAlignmentPropertyGet()
-{
- if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalLeft )
- {
- return "HorizontalLeft";
- }
- else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalCenter )
- {
- return "HorizontalCenter";
- }
- else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalRight )
- {
- return "HorizontalRight";
- }
- else
- {
- DALI_ASSERT_ALWAYS( !"TextView::OnHorizontalAlignmentPropertyGet(). Invalid value." );
- }
-}
-
-std::string TextView::OnVerticalAlignmentPropertyGet()
-{
- if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalTop )
- {
- return "VerticalTop";
- }
- else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalCenter )
- {
- return "VerticalCenter";
- }
- else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalBottom )
- {
- return "VerticalBottom";
- }
- else
- {
- DALI_ASSERT_ALWAYS( !"TextView::OnVerticalAlignmentPropertyGet(). Invalid value." );
- }
-}
-
-void TextView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
-{
- Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
-
- if( textView )
- {
- TextView& textViewImpl( GetImpl( textView ) );
- switch( index )
- {
- case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
- {
- textViewImpl.OnMarkupEnabledPeopertySet( value );
- break;
- }
- case Toolkit::TextView::PROPERTY_TEXT:
- {
- textViewImpl.SetText( value.Get<std::string>() );
- break;
- }
- case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
- {
- textViewImpl.OnMultilinePolicyPropertySet( value );
- break;
- }
- case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
- {
- textViewImpl.OnWidthExceedPolicyPropertySet( value );
- break;
- }
- case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
- {
- textViewImpl.OnHeightExceedPolicyPropertySet( value );
- break;
- }
- case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
- {
- textViewImpl.OnLineJustificationPropertySet( value );
- break;
- }
- case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
- {
- textViewImpl.OnFadeBoundaryPropertySet( value );
- break;
- }
- case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
- {
- Dali::PointSize pointSize( value.Get<float>() );
- textViewImpl.SetLineHeightOffset(pointSize);
- break;
- }
- case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
- case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
- {
- textViewImpl.OnAlignmentPropertySet( index, value );
- break;
- }
- }
- }
-}
-
-Property::Value TextView::GetProperty( BaseObject* object, Property::Index index )
-{
- Property::Value value;
-
- Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
-
- if( textView )
- {
- TextView& textViewImpl( GetImpl( textView ) );
- switch( index )
- {
- case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
- {
- value = textViewImpl.IsMarkupProcessingEnabled();
- break;
- }
- case Toolkit::TextView::PROPERTY_TEXT:
- {
- value = textViewImpl.GetText();
- break;
- }
- case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
- {
- value = MULTILINE_POLICY_NAME[ textViewImpl.GetMultilinePolicy() ];
- break;
- }
- case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
- {
- value = EXCEED_POLICY_NAME[ textViewImpl.GetWidthExceedPolicy() ];
- break;
- }
- case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
- {
- value = EXCEED_POLICY_NAME[ textViewImpl.GetHeightExceedPolicy() ];
- break;
- }
- case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
- {
- value = LINE_JUSTIFICATION_NAME[ textViewImpl.GetLineJustification() ];
- break;
- }
- case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
- {
- Toolkit::TextView::FadeBoundary boundary = textViewImpl.GetFadeBoundary();
- value = Vector4( static_cast<float>( boundary.mLeft.value ),
- static_cast<float>( boundary.mRight.value ),
- static_cast<float>( boundary.mTop.value ),
- static_cast<float>( boundary.mBottom.value ) );
- break;
- }
- case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
- {
- value = textViewImpl.GetLineHeightOffset().value;
- break;
- }
- case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
- {
- value = textViewImpl.OnHorizontalAlignmentPropertyGet();
- break;
- }
- case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
- {
- value = textViewImpl.OnVerticalAlignmentPropertyGet();
- break;
- }
- }
- }
- return value;
-}
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/actors/camera-actor.h>
-#include <dali/public-api/actors/image-actor.h>
-#include <dali/public-api/actors/layer.h>
-#include <dali/public-api/images/glyph-image.h>
-#include <dali/public-api/render-tasks/render-task.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/control-impl.h>
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
-#include <dali-toolkit/internal/controls/text-view/text-actor-cache.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-types.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-/**
- * TextView is a custom control for text aligning and multiline support
- */
-class TextView : public Control
-{
-public:
-
- // Properties
- enum
- {
- TEXTVIEW_PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
- TEXTVIEW_PROPERTY_END_INDEX = TEXTVIEW_PROPERTY_START_INDEX + 1000 ///< Reserving 1000 property indices
- };
-
- /**
- * Internal exceed policy with the valid combinations.
- */
- enum ExceedPolicy
- {
- Original, ///< Original size (even if it exceeds the witdh or the height).
- OriginalFade, ///< Original size if it exceeds the width but faded if it exceeds the height.
- OriginalShrink, ///< Shrunk if it exceeds the height.
- SplitOriginal, ///< Split if it exceeds the width but no action if it exceeds the height.
- SplitFade, ///< Split if it exceeds the width and faded if it exceeds the height.
- SplitShrink, ///< Split if it exceeds the width and shrunk if it exceeds the height.
- SplitEllipsizeEnd, ///< Split if it exceeds the width and ellipsize if it exceeds the height.
- Fade, ///< Faded if it exceeds any boundary.
- FadeOriginal, ///< Faded if it exceeds the width but no action if it exceeds the height.
- ShrinkOriginal, ///< Shrunk if it exceeds the width but no action if it exceeds the height.
- ShrinkFade, ///< Shrunk if it exceeds the width and faded if it exceeds the height.
- Shrink, ///< Shrunk if it exceeds any boundary.
- EllipsizeEndOriginal, ///< Ellipsized by the end if it exceeds the width but no action if it exceeds the height.
- EllipsizeEnd ///< Ellipsized by the end if it exceeds the width and/or the height.
- };
-
- // Between two OnRelayout methods, several calls to InsertTextAt, RemoveTextFrom or SetText can happen.
- // TextViewProcessorMetadata stores the type of operation. A vector stores all operations between two OnRelayout calls.
-
- enum TextViewProcessorMetadataType
- {
- TextSet, ///< Sets new text.
- TextInserted, ///< Inserts text into current text.
- TextReplaced, ///< Replaces some text from current text.
- TextRemoved, ///< Removes some text from current text.
- NewLineHeight, ///< Sets a new line height offset.
- NewStyle ///< Sets a new style to the whole text.
- };
-
- /**
- * Stores info about which data structures need to be modified when the OnRelayout() method is called
- */
- struct TextViewProcessorMetadata
- {
- TextViewProcessorMetadata();
-
- TextViewProcessorMetadataType mType; ///< Stores the type of operation.
- std::size_t mPosition; ///< Character position within the text.
- std::size_t mNumberOfCharacters; ///< Number of characters to be removed/replaced.
- MarkupProcessor::StyledTextArray mText; ///< The new text.
- TextStyle::Mask mStyleMask; ///< The style mask.
- };
-
- /**
- * Defines which operations have to be done in the relayout process.
- */
- enum RelayoutOperationMask
- {
- NO_RELAYOUT = 0x0, ///< Does nothing.
- RELAYOUT_REMOVE_TEXT_ACTORS = 0x1, ///< Removes current text-actors from the text-view.
- RELAYOUT_SIZE_POSITION = 0x2, ///< Calculates size and position of the text but it doesn't calculate alignment.
- RELAYOUT_ALIGNMENT = 0x4, ///< Aligns the whole text.
- RELAYOUT_VISIBILITY = 0x8, ///< Calculates the visibility.
- RELAYOUT_INITIALIZE_TEXT_ACTORS = 0x10, ///< Initialize text-actors (create handles).
- RELAYOUT_TEXT_ACTOR_UPDATE = 0x20, ///< Updates text-actors (set size, position, style, ...)
- RELAYOUT_INSERT_TO_TEXT_VIEW = 0x40, ///< Adds the text-actors to the text-view.
- RELAYOUT_ALL = 0xFF ///< Does all operations.
- };
-
- //////////////////////////////////////////////
-
- /**
- * Create a new TextView.
- * @return A smart-pointer to the newly allocated TextView.
- */
- static Toolkit::TextView New();
-
- /**
- * @copydoc SetText( const std::string& text )
- */
- void SetText( const std::string& text );
-
- /**
- * @copydoc SetText( const StyledTextArray& text )
- */
- void SetText( const MarkupProcessor::StyledTextArray& text );
-
- /**
- * @copydoc InsertTextAt( std::size_t position, const std::string& text )
- */
- void InsertTextAt( std::size_t position, const std::string& text );
-
- /**
- * @copydoc InsertTextAt( std::size_t position, const std::string& text )
- */
- void InsertTextAt( std::size_t position, const MarkupProcessor::StyledTextArray& text );
-
- /**
- * @copydoc RemoveTextFrom( std::size_t position, std::size_t numberOfCharacters )
- */
- void RemoveTextFrom( std::size_t position, std::size_t numberOfCharacters );
-
- /**
- * @copydoc ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text )
- */
- void ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text );
-
- /**
- * @copydoc ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text )
- */
- void ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text );
-
- /**
- * @copydoc GetText()
- */
- std::string GetText() const;
-
- /**
- * @copydoc SetLineHeightOffset()
- */
- void SetLineHeightOffset( PointSize offset );
-
- /**
- * @copydoc GetLineHeightOffset()
- */
- PointSize GetLineHeightOffset() const;
-
- /**
- * @copydoc SetStyleToCurrentText()
- */
- void SetStyleToCurrentText( const TextStyle& style, TextStyle::Mask mask );
-
- /**
- * @copydoc SetTextAlignment( Toolkit::Alignment::Type align )
- */
- void SetTextAlignment( Toolkit::Alignment::Type align );
-
- /**
- * @copydoc GetTextAlignment()
- */
- Toolkit::Alignment::Type GetTextAlignment() const;
-
- /**
- * @copydoc SetMultilinePolicy()
- */
- void SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy );
-
- /**
- * @copydoc GetMultilinePolicy()
- */
- Toolkit::TextView::MultilinePolicy GetMultilinePolicy() const;
-
- /**
- * @copydoc SetWidthExceedPolicy()
- */
- void SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy );
-
- /**
- * @copydoc GetWidthExceedPolicy()
- */
- Toolkit::TextView::ExceedPolicy GetWidthExceedPolicy() const;
-
- /**
- * @copydoc SetHeightExceedPolicy()
- */
- void SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy );
-
- /**
- * @copydoc GetHeightExceedPolicy()
- */
- Toolkit::TextView::ExceedPolicy GetHeightExceedPolicy() const;
-
- /**
- * @copydoc SetLineJustification()
- */
- void SetLineJustification( Toolkit::TextView::LineJustification justification );
-
- /**
- * @copydoc GetLineJustification()
- */
- Toolkit::TextView::LineJustification GetLineJustification() const;
-
- /**
- * @copydoc SetFadeBoundary()
- */
- void SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary );
-
- /**
- * @copydoc GetFadeBoundary()
- */
- const Toolkit::TextView::FadeBoundary& GetFadeBoundary() const;
-
- /**
- * @copydoc SetEllipsizeText()
- */
- void SetEllipsizeText( const std::string& ellipsizeText );
-
- /**
- * @copydoc SetEllipsizeText()
- */
- void SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText );
-
- /**
- * @copydoc SetEllipsizeText()
- */
- void SetEllipsizeText( const Text& ellipsizeText, const Vector<TextStyle*>& ellipsizeStyles );
-
- /**
- * @copydoc GetEllipsizeText()
- */
- std::string GetEllipsizeText() const;
-
- /**
- * Checks if relayout the text is needed. If it is, it relais out the text
- * by calling DoRelayOut().
- */
- void GetTextLayoutInfo();
-
- /**
- * Calls GetTextLayoutInfo() and fills the given data structure.
- *
- * @see GetTextLayoutInfo()
- */
- void GetTextLayoutInfo( Toolkit::TextView::TextLayoutInfo& textLayoutInfo );
-
- /**
- * @copydoc SetSortModifier()
- */
- void SetSortModifier( float depthOffset );
-
- /**
- * @copydoc SetSnapshotModeEnabled()
- */
- void SetSnapshotModeEnabled( bool enable );
-
- /**
- * @copydoc IsSnapshotModeEnabled()
- */
- bool IsSnapshotModeEnabled() const;
-
- /**
- * @brief Sets whether markup processing should be carried out.
- *
- * @param[in] enable whether markup processing is carried out or not.
- */
- void SetMarkupProcessingEnabled( bool enable );
-
- /**
- * @brief Returns whether markup processing is enabled or not
- *
- * @return true is markup processing is enabled
- */
- bool IsMarkupProcessingEnabled() const;
-
- /**
- * @copydoc SetScrollEnabled()
- */
- void SetScrollEnabled( bool enable );
-
- /**
- * @copydoc IsScrollEnabled()
- */
- bool IsScrollEnabled() const;
-
- /**
- * @copydoc SetScrollPosition()
- * @see DoSetScrollPosition()
- */
- void SetScrollPosition( const Vector2& position );
-
- /**
- * @copydoc GetScrollPosition()
- */
- const Vector2& GetScrollPosition() const;
-
- /**
- * @copydoc IsScrollPositionTrimmed()
- */
- bool IsScrollPositionTrimmed() const;
-
- /**
- * @copydoc ScrolledSignal()
- */
- Toolkit::TextView::ScrolledSignalType& ScrolledSignal();
-
- /**
- * Connects a callback function with the object's signals.
- * @param[in] object The object providing the signal.
- * @param[in] tracker Used to disconnect the signal.
- * @param[in] signalName The signal to connect to.
- * @param[in] functor A newly allocated FunctorDelegate.
- * @return True if the signal was connected.
- * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
- */
- static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
-
- // Properties
-
- /**
- * Called when a property of an object of this type is set.
- * @param[in] object The object whose property is set.
- * @param[in] index The property index.
- * @param[in] value The new property value.
- */
- static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
-
- /**
- * Called to retrieve a property of an object of this type.
- * @param[in] object The object whose property is to be retrieved.
- * @param[in] index The property index.
- * @return The current value of the property.
- */
- static Property::Value GetProperty( BaseObject* object, Property::Index index );
-
-
-private: // From Control
-
- /**
- * @copydoc Toolkit::Control::OnInitialize()
- */
- virtual void OnInitialize();
-
- /**
- * @copydoc Toolkit::Control::OnFontChange( )
- */
- virtual void OnFontChange( bool defaultFontChange, bool defaultFontSizeChange );
-
- /**
- * @copydoc Toolkit::Control::OnControlSizeSet()
- */
- virtual void OnControlSizeSet( const Vector3& size );
-
- /**
- * @copydoc Toolkit::Control::OnRelayout()
- */
- virtual void OnRelayout( const Vector2& size, ActorSizeContainer& container );
-
- /**
- * Retrieves the text-view's natural size.
- *
- * @return The natural size.
- */
- virtual Vector3 GetNaturalSize();
-
- /**
- * Retrieves the text-view's \e height for a given \e width.
- *
- * @param[in] width The given \e width.
- *
- * @return The \e height for the given \e width.
- */
- virtual float GetHeightForWidth( float width );
-
- /**
- * Retrieves the text-view's \e width for a given \e height.
- *
- * @param[in] height The given \e height.
- *
- * @return The \e width for the given \e height.
- */
- virtual float GetWidthForHeight( float height );
-
-protected:
-
- /**
- * Construct a new TextView.
- */
- TextView();
-
- /**
- * A reference counted object may only be deleted by calling Unreference()
- */
- virtual ~TextView();
-
-private:
-
- // Undefined
- TextView( const TextView& );
-
- // Undefined
- TextView& operator=( const TextView& rhs );
-
- /**
- * Executes synchronously relayout operations such as set, insert, remove or replace text, etc.
- */
- void PerformTextViewProcessorOperations();
-
- /**
- * Optimizes some text-view processor operations.
- */
- void OptimizeTextViewProcessorOperations();
-
- /**
- * Synchronously relays-out all text-actors.
- *
- * Perform text-view-processor operations, sets the new size and position of text-actors and adds them to the text-view.
- *
- * @param[in] textViewSize The new text-view's size.
- * @param[in] relayoutOperationMask Defines which operations need to be done in the relayout process.
- */
- void DoRelayOut( const Size& textViewSize, RelayoutOperationMask relayoutOperationMask );
-
- /**
- * Process Snapshot. It refresh the render-task in order to generate a new snapshot image.
- *
- * ProcessSnapshot is called from OnRelayout() only if text has been relaid out.
- * It creates a new image buffer only if the size of the text has changed.
- *
- * @param[in] textViewSize The new text-view's size.
- */
- void ProcessSnapshot( const Size& textViewSize );
-
- /**
- * Aligns the offscreen rendering camera actor to cover the whole text and the resulting image actor accordingly with the text view's alignment.
- *
- * @param[in] textViewSize The text view's size.
- * @param[in] offscreenSize The offscreen's frame buffer's size.
- */
- void AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize );
-
- /**
- * Callback called when the render task has processed.
- *
- * It makes the root actor invisible.
- *
- * @param[in] renderTask The processed render task.
- */
- void RenderTaskFinished( Dali::RenderTask& renderTask );
-
- /**
- * Destroys offscreen rendering resources.
- *
- * It disconects the render task finished signal from the TextView::RenderTaskFinished() method,
- * removes the render task from the render task list and resets the offscreen camera actor, root actor,
- * image actor and the frame buffer.
- */
- void DestroyOffscreenRenderingResources();
-
- /**
- * Called when text-view is scrolled.
- *
- * Sets the new scroll position. @see DoSetScrollPosition()
- *
- * @param[in] actor Handle of the text-view.
- * @param[in] gesture Data structure with the parameters of the gesture.
- */
- void OnTextPan( Actor actor, const PanGesture& gesture );
-
- /**
- * Ensures the text-view's boundaries are fully covered of text.
- *
- * i.e. if the text-view's size is 100x100 and the text's size is 150x100, the scroll position
- * can be in the range -50,0 and 50,0.
- */
- void TrimScrollPosition();
-
- /**
- * Called from SetScrollPosition() and OnTextPan()
- *
- * Updates the stored scroll position ensuring the text-view is always covered with text by calling
- * TrimScrollPosition(), calculates the difference with the previous one and emits the Toolkit::TextView::SignalScrolled() signal.
- *
- * @param[in] position The new scroll position.
- */
- void DoSetScrollPosition( const Vector2& position );
-
- /**
- * Combines width and height exceed policies.
- *
- * This method is a big switch() which combines two exceed policies into one.
- * The aim is avoid this switch inside the relayout code.
- *
- * i.e. Width policy = Split. Height policy = Original. Internally the policy is SplitOriginal.
- */
- void CombineExceedPolicies();
-
- /**
- * Retrieves the text-view's root actor which stores all text-actors.
- * It could be the text-view itself or an actor used in the snapshot mode.
- *
- * @return the root actor.
- */
- Actor GetRootActor() const;
-
- /**
- * Creates the ellipsize text layout.
- */
- void CreateEllipsizeLayout();
-
- /**
- * Handle SetProperty for markup processing.
- * @param[in] propertyValue The new property value.
- */
- void OnMarkupEnabledPeopertySet( Property::Value propertyValue );
-
- /**
- * Handles SetProperty for multiline policy.
- * @param[in] propertyValue The new property value.
- */
- void OnMultilinePolicyPropertySet( Property::Value propertyValue );
-
- /**
- * Handles SetProperty for width exceed policy.
- * @param[in] propertyValue The new property value.
- */
- void OnWidthExceedPolicyPropertySet( Property::Value propertyValue );
-
- /**
- * Handles SetProperty for height exceed policy.
- * @param[in] propertyValue The new property value.
- */
- void OnHeightExceedPolicyPropertySet( Property::Value propertyValue );
-
- /**
- * Handles SetProperty for line justification.
- * @param[in] propertyValue The new property value.
- */
- void OnLineJustificationPropertySet( Property::Value propertyValue );
-
- /**
- * Handles SetProperty for fade boundary.
- * @param[in] propertyValue The new property value.
- */
- void OnFadeBoundaryPropertySet( Property::Value propertyValue );
-
- /**
- * Handles SetProperty for alignment property.
- * @param[in] propertyIndex The property index.
- * @param[in] propertyValue The new property value.
- */
- void OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue );
-
- /**
- * Handles GetProperty for horizontal alignment property.
- * @return The property value of horizontal alignment.
- */
- std::string OnHorizontalAlignmentPropertyGet();
-
- /**
- * Handles GetProperty for vertical alignment property.
- * @return The property value of vertical alignment.
- */
- std::string OnVerticalAlignmentPropertyGet();
-
-public:
-
- /**
- * The parameters which affects the layout of the text.
- */
- struct LayoutParameters
- {
- /**
- * Default constructor.
- */
- LayoutParameters();
-
- /**
- * Default destructor.
- */
- ~LayoutParameters();
-
- /**
- * Constructor
- */
- LayoutParameters( Toolkit::TextView::MultilinePolicy multilinePolicy,
- Toolkit::TextView::ExceedPolicy widthExceedPolicy,
- Toolkit::TextView::ExceedPolicy heightExceedPolicy,
- Toolkit::Alignment::Type alignment,
- Toolkit::TextView::LineJustification lineJustification,
- float lineHeightOffset,
- bool markUpEnabled );
-
- /**
- * Copy constructor
- */
- LayoutParameters( const LayoutParameters& layoutParameters );
-
- /**
- * Assignment operator.
- */
- LayoutParameters& operator=( const LayoutParameters& layoutParameters );
-
- Toolkit::TextView::MultilinePolicy mMultilinePolicy; ///< Stores the multiline policy.
- TextView::ExceedPolicy mExceedPolicy; ///< Stores a combination of both policies.
- Toolkit::TextView::ExceedPolicy mWidthExceedPolicy; ///< Stores the text width exceed policy.
- Toolkit::TextView::ExceedPolicy mHeightExceedPolicy; ///< Stores the text height exceed policy.
- Toolkit::Alignment::Type mHorizontalAlignment; ///< Stores the horizontal alignment for the whole text.
- Toolkit::Alignment::Type mVerticalAlignment; ///< Stores the vertical alignment for the whole text.
- Toolkit::TextView::LineJustification mLineJustification; ///< Stores the line justification.
- float mLineHeightOffset; ///< Line height offset to be addded to the font line height (measured in PointSize).
- bool mMarkUpEnabled:1; ///< Is markup string scanning enabled.
- };
-
- /**
- * Some parameters which affects the text view visualization.
- */
- struct VisualParameters
- {
- /**
- * Default constructor.
- */
- VisualParameters();
-
- /**
- * Copy constructor.
- */
- VisualParameters( const VisualParameters& visualParameters );
-
- /**
- * Assignment operator.
- */
- VisualParameters& operator=( const VisualParameters& visualParameters );
-
- Toolkit::TextView::FadeBoundary mFadeBoundary; ///< Fade boundary used in fade mode.
- float mSortModifier; ///< Stores the sort modifier for all text-actors.
- Vector2 mCameraScrollPosition; ///< The scroll offset.
- bool mSnapshotModeEnabled:1; ///< Whether text-view is rendered offscreen.
- bool mScrollEnabled:1; ///< Whether the text scroll is enabled.
- bool mScrollPositionTrimmed:1; ///< Whether the last scroll position set was trimmed.
- };
-
- /**
- * The results of the relayout process.
- */
- struct RelayoutData
- {
- /**
- * Default constructor.
- */
- RelayoutData();
-
- /**
- * Copy constructor
- */
- RelayoutData( const RelayoutData& relayoutData );
-
- /**
- * Assignment operator.
- */
- RelayoutData& operator=( const RelayoutData& relayoutData );
-
- Size mTextViewSize; ///< The text-view's size used to relaid-out the text.
- float mShrinkFactor; ///< Shrink factor used when the exceed policy contains ShrinkToFit.
- TextViewProcessor::TextLayoutInfo mTextLayoutInfo; ///< Stores metrics, layout info (size, direction, type of word) and text-actor info for the whole text.
- std::vector<int> mCharacterLogicalToVisualMap; ///< Reorder map that stores each character's visual (output) index according to its logical (input) index
- std::vector<int> mCharacterVisualToLogicalMap; ///< Reorder map that stores each character's logical (input) index according to its visual (output) index
- std::vector<RenderableActor> mGlyphActors; ///< Stores handles of those text-actors which are currently added to the text-view.
- std::vector<RenderableActor> mEllipsizedGlyphActors; ///< Stores handles of those text-actors which are used to ellipsize the text.
- Toolkit::TextView::CharacterLayoutInfoContainer mCharacterLayoutInfoTable; ///< Stores layout info per character sorted by the character's visual index.
- Toolkit::TextView::LineLayoutInfoContainer mLines; ///< Stores an index to the first character of each line.
- Size mTextSizeForRelayoutOption; ///< Stores the text size after relayout.
- TextActorCache mTextActorCache; ///< Stores previously created text-actors to be reused.
- };
-
-private:
-
- MarkupProcessor::StyledTextArray mCurrentStyledText; ///< text currently displayed by the view
- std::vector<TextViewProcessorMetadata> mTextViewProcessorOperations; ///< Stores all relayout operations which arrive between two consecutive OnRelayout() calls.
-
- LayoutParameters mLayoutParameters; ///< Stores some layout parameters in a struct. To be passed in layout functions.
- VisualParameters mVisualParameters; ///< Some parameters which afects text-view visualization.
- RelayoutData mRelayoutData; ///< struct with text-view's data structures used to pass all of them in one parameter.
- RelayoutOperationMask mRelayoutOperations; ///< Which relayout operations have to be done.
-
- Layer mOffscreenRootActor; ///< Root actor for offscreen rendering.
- ImageActor mOffscreenImageActor; ///< Image actor for offscreen rendering.
- CameraActor mOffscreenCameraActor; ///< Camera actor for offscreen rendering.
- Size mCurrentOffscreenSize; ///< Current used ofscreen size.
- FrameBufferImage mFrameBufferImage; ///< Frame buffer used for offscreen rendering.
- RenderTask mRenderTask; ///< Used to generate an offscreen rendering.
-
- PanGestureDetector mPanGestureDetector; ///< Pan gesture for text scrolling.
-
- /**
- * Helper class used to prevent the modification of some members.
- */
- struct Lock
- {
- Lock( bool& lock )
- : mLock( lock )
- {
- mLock = true;
- }
-
- ~Lock()
- {
- mLock = false;
- }
-
- bool& mLock;
- };
-
- bool mLockPreviousSnapshotMode; ///< Whether previous stored snapshot mode should be modified.
- bool mPreviousSnapshotModeEnabled:1; ///< Stores the previous snapshot mode value.
- bool mMarkUpEnabled:1; ///< enable to scan for mark-up
-
- Toolkit::TextView::ScrolledSignalType mScrolledSignal; ///< Signal emitted when text is scrolled.
-};
-
-} // namespace Internal
-
-// Helpers for public-api forwarding methods
-
-inline Internal::TextView& GetImpl( TextView& textView )
-{
- DALI_ASSERT_ALWAYS( textView );
-
- RefObject& handle = textView.GetImplementation();
-
- return static_cast< Internal::TextView& >( handle );
-}
-
-inline const Internal::TextView& GetImpl( const TextView& textView )
-{
- DALI_ASSERT_ALWAYS( textView );
-
- const RefObject& handle = textView.GetImplementation();
-
- return static_cast< const Internal::TextView& >( handle );
-}
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_ITEM_VIEW_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-view/text-view-paragraph-processor.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-helper-functions.h>
-#include <dali-toolkit/internal/controls/text-view/text-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewProcessor
-{
-
-/////////////////////
-// Layout info.
-/////////////////////
-
-void RightToLeftParagraphLayout::Clear()
-{
- mWordsLayoutInfo.clear();
- mText = Text();
- mTextStyles.Clear();
-}
-
-ParagraphLayoutInfo::ParagraphLayoutInfo()
-: mSize(),
- mAscender( 0.f ),
- mLineHeightOffset( 0.f ),
- mFirstCharacter( 0u ),
- mNumberOfCharacters( 0u ),
- mWordsLayoutInfo(),
- mText(),
- mTextStyles(),
- mRightToLeftLayout( NULL ),
- mBidirectionalParagraphInfo( NULL ),
- mBidirectionalLinesInfo()
-{
-}
-
-ParagraphLayoutInfo::~ParagraphLayoutInfo()
-{
- if( NULL != mRightToLeftLayout )
- {
- // TextStyle pointers are the same than the ones stored at ParagraphLayoutInfo::mTextStyles.
- // Do not delete them, just clear the vector.
- mRightToLeftLayout->mTextStyles.Clear();
-
- delete mRightToLeftLayout;
- }
-
- // Clears text styles. It destroys TextStyle objects.
- ClearStyles();
-
- // Deletes the bidirectional info for the whole paragraph.
- delete mBidirectionalParagraphInfo;
-
- // Clears the bidirectional info for all lines. Destroys the BidirectionalLineInfo objects.
- ClearBidirectionalInfo();
-}
-
-ParagraphLayoutInfo::ParagraphLayoutInfo( const ParagraphLayoutInfo& paragraph )
-: mSize( paragraph.mSize ),
- mAscender( paragraph.mAscender ),
- mLineHeightOffset( paragraph.mLineHeightOffset ),
- mFirstCharacter( paragraph.mFirstCharacter ),
- mNumberOfCharacters( paragraph.mNumberOfCharacters ),
- mWordsLayoutInfo( paragraph.mWordsLayoutInfo ),
- mText( paragraph.mText ),
- mTextStyles(),
- mRightToLeftLayout( NULL ),
- // Copies bidirectional info for the whole paragraph.
- mBidirectionalParagraphInfo( ( NULL == paragraph.mBidirectionalParagraphInfo ) ? NULL : new TextProcessor::BidirectionalParagraphInfo( *paragraph.mBidirectionalParagraphInfo ) ),
- mBidirectionalLinesInfo()
-{
- // Copies styles.
- for( Vector<TextStyle*>::ConstIterator it = paragraph.mTextStyles.Begin(), endIt = paragraph.mTextStyles.End(); it != endIt; ++it )
- {
- mTextStyles.PushBack( new TextStyle( *(*it) ) );
- }
-
- // Copies bidirectional info for each line.
- for( Vector<TextProcessor::BidirectionalLineInfo*>::ConstIterator it = mBidirectionalLinesInfo.Begin(), endIt = mBidirectionalLinesInfo.End(); it != endIt; ++it )
- {
- mBidirectionalLinesInfo.PushBack( new TextProcessor::BidirectionalLineInfo( *( *it ) ) );
- }
-}
-
-ParagraphLayoutInfo& ParagraphLayoutInfo::operator=( const ParagraphLayoutInfo& paragraph )
-{
- mSize = paragraph.mSize;
- mAscender = paragraph.mAscender;
- mLineHeightOffset = paragraph.mLineHeightOffset;
- mFirstCharacter = paragraph.mFirstCharacter;
- mNumberOfCharacters = paragraph.mNumberOfCharacters;
- mWordsLayoutInfo = paragraph.mWordsLayoutInfo;
- mText = paragraph.mText;
-
- // If it has styles, destroy them.
- ClearStyles();
-
- // Copies styles.
- for( Vector<TextStyle*>::ConstIterator it = paragraph.mTextStyles.Begin(), endIt = paragraph.mTextStyles.End(); it != endIt; ++it )
- {
- mTextStyles.PushBack( new TextStyle( *(*it) ) );
- }
-
- // Copies the paragraph's bidirectiona info.
- if( NULL == paragraph.mBidirectionalParagraphInfo )
- {
- // The source doesn't have bidirectiona info. Deletes the current one.
- delete mBidirectionalParagraphInfo;
- mBidirectionalParagraphInfo = NULL;
- }
- else
- {
- // The source has bidirectional info.
- if( NULL != mBidirectionalParagraphInfo )
- {
- // It it has, copy to it.
- *mBidirectionalParagraphInfo = *paragraph.mBidirectionalParagraphInfo;
- }
- else
- {
- // If it doesn't have, create a new one.
- mBidirectionalParagraphInfo = new TextProcessor::BidirectionalParagraphInfo( *paragraph.mBidirectionalParagraphInfo );
- }
- }
-
- // If it has bidirectiona info per line, destroy them.
- ClearBidirectionalInfo();
-
- // Copies bidirectional info per line.
- for( Vector<TextProcessor::BidirectionalLineInfo*>::ConstIterator it = mBidirectionalLinesInfo.Begin(), endIt = mBidirectionalLinesInfo.End(); it != endIt; ++it )
- {
- mBidirectionalLinesInfo.PushBack( new TextProcessor::BidirectionalLineInfo( *( *it ) ) );
- }
-
- return *this;
-}
-
-void ParagraphLayoutInfo::ClearBidirectionalInfo()
-{
- // Destroys the bidirectional infor per line.
- for( Vector<TextProcessor::BidirectionalLineInfo*>::Iterator it = mBidirectionalLinesInfo.Begin(), endIt = mBidirectionalLinesInfo.End(); it != endIt; ++it )
- {
- delete *it;
- }
- mBidirectionalLinesInfo.Clear();
-}
-
-void ParagraphLayoutInfo::ClearStyles()
-{
- // Destroys the styles.
- for( Vector<TextStyle*>::Iterator it = mTextStyles.Begin(), endIt = mTextStyles.End(); it != endIt; ++it )
- {
- delete *it;
- }
- mTextStyles.Clear();
-}
-
-void CreateParagraphInfo( TextView::RelayoutData& relayoutData,
- ParagraphLayoutInfo& paragraphLayoutInfo )
-{
- if( TextProcessor::ContainsRightToLeftCharacter( paragraphLayoutInfo.mText ) )
- {
- // If the text is bidirectional, the characters will be converted and reordered
- // as specified by the Unicode Bidirectional Algorithm.
-
- paragraphLayoutInfo.mBidirectionalParagraphInfo = new TextProcessor::BidirectionalParagraphInfo();
-
- TextProcessor::ProcessBidirectionalText( paragraphLayoutInfo.mText, paragraphLayoutInfo.mBidirectionalParagraphInfo );
- }
-
- // Split the paragraph in words. It retrieves the positions of white spaces and the last '\n' if there is one.
- Vector<std::size_t> positions;
- TextProcessor::SplitInWords( paragraphLayoutInfo.mText, positions );
-
- const std::size_t lastCharacterIndex = paragraphLayoutInfo.mText.GetLength() - 1u;
- const bool isLastCharacterParagraphSeparator = paragraphLayoutInfo.mText.IsNewLine( lastCharacterIndex );
-
- // The number of words is ~the number of white spaces found + 1u.
- // White spaces are also words.
- // New line characters are also white spaces. If the last character is a white space the +1 is not needed.
- const std::size_t numberOfWords = 2u * positions.Count() + ( isLastCharacterParagraphSeparator ? 0u : 1u );
-
- // Reserve space for all the words.
- paragraphLayoutInfo.mWordsLayoutInfo.resize( numberOfWords, WordLayoutInfo() );
-
- // Traverses all positions creating and setting all character layout info objects to every word.
- std::size_t wordIndex = 0u;
- Vector<std::size_t>::ConstIterator positionIt = positions.Begin();
- Vector<std::size_t>::ConstIterator positionEndIt = positions.End();
- std::size_t from = 0u;
- for( std::size_t positionIndex = 0u, size = positions.Count() + 1u; positionIndex < size; ++positionIndex )
- {
- const bool isEndPosition = positionIt == positionEndIt;
- const std::size_t to = isEndPosition ? lastCharacterIndex + 1u : *positionIt;
-
- if( from < to )
- {
- // The word is not a white space.
- WordLayoutInfo& wordLayoutInfo = *( paragraphLayoutInfo.mWordsLayoutInfo.begin() + wordIndex );
- ++wordIndex;
- // Sets the index within the paragraph to the first character of the word.
- wordLayoutInfo.mFirstCharacter = from;
- // Creates character layout info objects.
- wordLayoutInfo.mCharactersLayoutInfo.resize( ( to - from ), CharacterLayoutInfo() );
- }
-
- if( !isEndPosition )
- {
- // Create a word for the white space.
- WordLayoutInfo& wordLayoutInfo = *( paragraphLayoutInfo.mWordsLayoutInfo.begin() + wordIndex );
- ++wordIndex;
- // Sets the index within the paragraph to the white space.
- wordLayoutInfo.mFirstCharacter = to;
- wordLayoutInfo.mType = WordSeparator;
-
- CharacterLayoutInfo characterLayoutInfo;
- wordLayoutInfo.mCharactersLayoutInfo.push_back( characterLayoutInfo );
- }
-
- from = to + 1u;
-
- if( !isEndPosition )
- {
- // next white space position.
- ++positionIt;
- }
- else
- {
- // All white space positiona have been traversed.
- // It may be some extra words. i.e if the text is \n.
- // Erase them.
- paragraphLayoutInfo.mWordsLayoutInfo.erase( paragraphLayoutInfo.mWordsLayoutInfo.begin() + wordIndex, paragraphLayoutInfo.mWordsLayoutInfo.end() );
-
- // Check if the last character is a new paragraph character.
- if( isLastCharacterParagraphSeparator )
- {
- ( *( paragraphLayoutInfo.mWordsLayoutInfo.end() - 1u ) ).mType = ParagraphSeparator;
- }
- }
- }
-
- // Traverse all words and fill the layout info.
- for( WordLayoutInfoContainer::iterator it = paragraphLayoutInfo.mWordsLayoutInfo.begin(), endIt = paragraphLayoutInfo.mWordsLayoutInfo.end(); it != endIt; ++it )
- {
- WordLayoutInfo& wordLayoutInfo( *it );
-
- CreateWordTextInfo( paragraphLayoutInfo.mText,
- paragraphLayoutInfo.mTextStyles,
- wordLayoutInfo );
-
- // Update layout info for the current paragraph.
- UpdateSize( paragraphLayoutInfo.mSize, wordLayoutInfo.mSize );
- paragraphLayoutInfo.mAscender = std::max( paragraphLayoutInfo.mAscender, wordLayoutInfo.mAscender );
- paragraphLayoutInfo.mNumberOfCharacters += wordLayoutInfo.mCharactersLayoutInfo.size();
-
- // Update the max word width figure.
- relayoutData.mTextLayoutInfo.mMaxWordWidth = std::max( relayoutData.mTextLayoutInfo.mMaxWordWidth, wordLayoutInfo.mSize.width );
- } // end of words
-}
-
-void UpdateLayoutInfo( ParagraphLayoutInfo& paragraphLayoutInfo, float lineHeightOffset )
-{
- // Update layout info.
-
- // Initialize members to be updated.
- paragraphLayoutInfo.mSize = Size::ZERO;
- paragraphLayoutInfo.mAscender = 0.f;
- paragraphLayoutInfo.mNumberOfCharacters = 0u;
-
- // Traverses all words.
- for( WordLayoutInfoContainer::iterator it = paragraphLayoutInfo.mWordsLayoutInfo.begin(), endIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
- it != endIt;
- ++it )
- {
- WordLayoutInfo& word( *it );
-
- // Sets the index within the paragraph to the first character of the word.
- word.mFirstCharacter = paragraphLayoutInfo.mNumberOfCharacters;
-
- // Updates the paragraph's size.
- UpdateSize( paragraphLayoutInfo.mSize, word.mSize );
-
- // Updates the paragraph's max asender.
- paragraphLayoutInfo.mAscender = std::max( paragraphLayoutInfo.mAscender, word.mAscender );
-
- // Updates the paragraph's number of characters.
- paragraphLayoutInfo.mNumberOfCharacters += word.mCharactersLayoutInfo.size();
- }
-
- // Sets the line height offset.
- paragraphLayoutInfo.mSize.height += lineHeightOffset;
- paragraphLayoutInfo.mLineHeightOffset = lineHeightOffset;
-}
-
-void RemoveWordsFromParagraph( std::size_t wordIndex,
- std::size_t numberOfWords,
- float lineHeightOffset,
- ParagraphLayoutInfo& paragraphLayout )
-{
- // Removes words from a paragraph.
-
- // * Check if words or paragraphs can be merged after removing a number of words or a paragraph separator needs to be done outside this method.
-
- // Remove words from layout info.
- paragraphLayout.mWordsLayoutInfo.erase( paragraphLayout.mWordsLayoutInfo.begin() + wordIndex,
- paragraphLayout.mWordsLayoutInfo.begin() + ( wordIndex + numberOfWords ) );
-
- UpdateLayoutInfo( paragraphLayout, lineHeightOffset );
-}
-
-void RemoveCharactersFromParagraphInfo( TextView::RelayoutData& relayoutData,
- const std::size_t numberOfCharacters,
- bool& mergeWords,
- bool& mergeParagraphs,
- TextInfoIndices& textInfoIndicesBegin,
- TextInfoIndices& textInfoIndicesEnd,
- TextInfoIndices& textInfoMergeIndicesBegin,
- TextInfoIndices& textInfoMergeIndicesEnd,
- ParagraphLayoutInfo& paragraphLayout,
- std::vector<TextActor>& removedTextActorsFromFirstWord,
- std::vector<TextActor>& removedTextActorsFromLastWord )
-{
- const TextLayoutInfo& textLayoutInfo = relayoutData.mTextLayoutInfo;
-
- if( textInfoIndicesBegin.mWordIndex < textInfoIndicesEnd.mWordIndex )
- {
- // Deleted text is from different words. The two different words may be merged.
-
- // Get first word.
- WordLayoutInfo& firstWordLayout( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesBegin.mWordIndex ) );
-
- // Get last word.
- WordLayoutInfo& lastWordLayout( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesEnd.mWordIndex ) );
-
- // whether first or last word need to be split and merged.
- bool mergeFromBegin = false;
- bool mergeToEnd = false;
-
- if( textInfoIndicesBegin.mCharacterIndex > 0u )
- {
- // First word is going to be split. It could be merged with the last word.
- mergeFromBegin = true;
- textInfoMergeIndicesBegin.mWordIndex = textInfoIndicesBegin.mWordIndex;
- }
- else if( ( textInfoIndicesBegin.mCharacterIndex == 0u ) && ( textInfoIndicesBegin.mWordIndex > 0u ) )
- {
- // First word is going to be removed completely.
- // Check if previous word could be merged.
-
- // Get word before.
- WordLayoutInfo& previousWordLayout( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesBegin.mWordIndex - 1u ) );
- if( WordSeparator != previousWordLayout.mType )
- {
- // Previous word is not a word separator, so could be merged.
- mergeFromBegin = true;
- textInfoMergeIndicesBegin.mWordIndex = textInfoIndicesBegin.mWordIndex - 1u;
- }
- }
-
- if( mergeFromBegin )
- {
- // First word (or previous one) could be merged. Check if last one could be merged as well.
-
- if( textInfoIndicesEnd.mCharacterIndex + 1u < lastWordLayout.mCharactersLayoutInfo.size() )
- {
- // Last word is going to be split. It could be merged with the first word.
- mergeToEnd = true;
- textInfoMergeIndicesEnd.mWordIndex = textInfoIndicesEnd.mWordIndex;
- }
- else if( ( textInfoIndicesEnd.mCharacterIndex + 1u == lastWordLayout.mCharactersLayoutInfo.size() ) && ( textInfoIndicesEnd.mWordIndex + 1u < paragraphLayout.mWordsLayoutInfo.size() ) )
- {
- // Last word is going to be removed completely.
- // Check if the word after could be merged.
-
- // Get word after.
- WordLayoutInfo& afterWordLayout( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesEnd.mWordIndex + 1u ) );
- if( WordSeparator != afterWordLayout.mType )
- {
- // The word after is not a word separator, so could be merged.
- mergeToEnd = true;
- textInfoMergeIndicesEnd.mWordIndex = textInfoIndicesEnd.mWordIndex + 1u;
- }
- }
-
- // Merge words only if both words could be merged.
- mergeWords = mergeFromBegin && mergeToEnd;
- }
-
- if( ( textInfoIndicesEnd.mCharacterIndex + 1u == lastWordLayout.mCharactersLayoutInfo.size() ) && ( textInfoIndicesEnd.mWordIndex + 1u == paragraphLayout.mWordsLayoutInfo.size() ) )
- {
- // Last word of the paragraph is going to be removed completely.
- // Check if it's a paragraph separator.
-
- if( ParagraphSeparator == lastWordLayout.mType )
- {
- // The paragraph separator is going to be removed.
- if( textInfoIndicesBegin.mParagraphIndex + 1u < textLayoutInfo.mParagraphsLayoutInfo.size() )
- {
- // Paragraph need to be merged.
- textInfoMergeIndicesBegin.mParagraphIndex = textInfoIndicesBegin.mParagraphIndex;
- textInfoMergeIndicesEnd.mParagraphIndex = textInfoIndicesBegin.mParagraphIndex + 1u;
- mergeParagraphs= true;
-
- ++textInfoIndicesBegin.mParagraphIndex; // increase both indices,
- textInfoIndicesEnd.mParagraphIndex +=2u; // will delete last paragraph.
- }
- }
- }
-
- if( textInfoIndicesBegin.mCharacterIndex > 0u )
- {
- // First word needs to be split.
-
- // Store text-actors before removing them.
- CollectTextActors( removedTextActorsFromFirstWord, firstWordLayout, textInfoIndicesBegin.mCharacterIndex, firstWordLayout.mCharactersLayoutInfo.size() );
-
- RemoveCharactersFromWord( textInfoIndicesBegin.mCharacterIndex,
- firstWordLayout.mCharactersLayoutInfo.size() - textInfoIndicesBegin.mCharacterIndex,
- firstWordLayout );
-
- ++textInfoIndicesBegin.mWordIndex; // will delete from the word after.
- }
-
- if( textInfoIndicesEnd.mCharacterIndex + 1u < lastWordLayout.mCharactersLayoutInfo.size() )
- {
- // Last word needs to be split.
-
- // Store text-actors before removing them.
- CollectTextActors( removedTextActorsFromLastWord, lastWordLayout, 0u, textInfoIndicesEnd.mCharacterIndex + 1u );
-
- RemoveCharactersFromWord( 0u,
- textInfoIndicesEnd.mCharacterIndex + 1u,
- lastWordLayout );
-
- if( mergeWords )
- {
- // This word is going to be merged, so is not needed.
- ++textInfoIndicesEnd.mWordIndex; // will delete the last word.
- }
- }
- else if( textInfoIndicesEnd.mCharacterIndex + 1u == lastWordLayout.mCharactersLayoutInfo.size() )
- {
- // The whole last word is going to be removed.
- ++textInfoIndicesEnd.mWordIndex; // will delete the last word.
-
- if( ( WordSeparator == lastWordLayout.mType ) && mergeWords )
- {
- // The last word is a word separator and the word after is going to be merged so is not needed.
- ++textInfoIndicesEnd.mWordIndex; // will delete the word after the last one.
- }
- }
- }
- else
- {
- // Chraracters to be removed are from the same word.
-
- RemoveCharactersFromWordInfo( relayoutData,
- numberOfCharacters,
- mergeWords,
- mergeParagraphs,
- textInfoIndicesBegin,
- textInfoIndicesEnd,
- textInfoMergeIndicesBegin,
- textInfoMergeIndicesEnd,
- paragraphLayout,
- removedTextActorsFromFirstWord );
- } // word indices
-}
-
-void SplitParagraph( const TextInfoIndices& indices,
- float lineHeightOffset,
- ParagraphLayoutInfo& firstParagraphLayoutInfo,
- ParagraphLayoutInfo& lastParagraphLayoutInfo )
-{
- // Splits a paragraph in two.
- // A word may be split in two as well.
-
- // * Split the word within the paragraph.
- // * Add last part of the word to the new paragraph.
- // * Add words from wordPosition + 1 to the end.
- // * Update layout info of the last paragraph.
- // * Remove words added to the last part of the paragraph from the first paragraph.
-
- // early returns!!
- if( ( 0u == indices.mWordIndex ) && ( 0u == indices.mCharacterIndex ) )
- {
- // the whole paragraph goes to the last part.
- lastParagraphLayoutInfo = firstParagraphLayoutInfo;
-
- firstParagraphLayoutInfo = ParagraphLayoutInfo();
-
- return;
- }
-
- if( !firstParagraphLayoutInfo.mWordsLayoutInfo.empty() )
- {
- const std::size_t numberOfWords = firstParagraphLayoutInfo.mWordsLayoutInfo.size();
- if( indices.mWordIndex == numberOfWords - 1u )
- {
- const WordLayoutInfo& word( *( firstParagraphLayoutInfo.mWordsLayoutInfo.end() - 1u ) );
- if( indices.mCharacterIndex == word.mCharactersLayoutInfo.size() )
- {
- // the whole paragraph goes to the first part.
-
- // Just delete whatever there is in the last part of the paragraph.
- lastParagraphLayoutInfo = ParagraphLayoutInfo();
-
- return;
- }
- }
- }
-
- lastParagraphLayoutInfo = ParagraphLayoutInfo();
-
- // 1) Split the word whitin the paragraph.
- WordLayoutInfo& firstWordLayoutInfo( *( firstParagraphLayoutInfo.mWordsLayoutInfo.begin() + indices.mWordIndex ) );
- WordLayoutInfo lastWordLayoutInfo;
-
- SplitWord( indices.mCharacterIndex,
- firstWordLayoutInfo,
- lastWordLayoutInfo );
-
- // 2) Add last part of the word to the new paragraph.
- if( !lastWordLayoutInfo.mCharactersLayoutInfo.empty() )
- {
- lastParagraphLayoutInfo.mWordsLayoutInfo.push_back( lastWordLayoutInfo );
- }
-
- // 3) Add words from word-position + 1 to the end.
- lastParagraphLayoutInfo.mWordsLayoutInfo.insert( lastParagraphLayoutInfo.mWordsLayoutInfo.end(),
- firstParagraphLayoutInfo.mWordsLayoutInfo.begin() + indices.mWordIndex + 1u,
- firstParagraphLayoutInfo.mWordsLayoutInfo.end() );
-
- // 4) update layout info of the last paragraph.
- for( WordLayoutInfoContainer::iterator it = lastParagraphLayoutInfo.mWordsLayoutInfo.begin(), endIt = lastParagraphLayoutInfo.mWordsLayoutInfo.end();
- it != endIt;
- ++it )
- {
- WordLayoutInfo& layoutInfo( *it );
-
- UpdateSize( lastParagraphLayoutInfo.mSize, layoutInfo.mSize );
- lastParagraphLayoutInfo.mNumberOfCharacters += layoutInfo.mCharactersLayoutInfo.size();
- lastParagraphLayoutInfo.mAscender = std::max( lastParagraphLayoutInfo.mAscender, layoutInfo.mAscender );
- }
- lastParagraphLayoutInfo.mSize.height += lineHeightOffset;
- lastParagraphLayoutInfo.mLineHeightOffset = lineHeightOffset;
-
- // 5) Remove words added to the last part of the paragraph from the first paragraph.
-
- // if the number of characters of the last word of the first paragraph is zero, it should be removed.
- const std::size_t index = ( firstWordLayoutInfo.mCharactersLayoutInfo.empty() ? indices.mWordIndex : indices.mWordIndex + 1u );
-
- firstParagraphLayoutInfo.mWordsLayoutInfo.erase( firstParagraphLayoutInfo.mWordsLayoutInfo.begin() + index, firstParagraphLayoutInfo.mWordsLayoutInfo.end() );
-
- // 6) update layout info of the first paragraph.
- UpdateLayoutInfo( firstParagraphLayoutInfo, lineHeightOffset );
-
- // 7) Split text and styles.
-
- // Copies the whole text to the last part of the paragraph.
- lastParagraphLayoutInfo.mText = firstParagraphLayoutInfo.mText;
-
- // Removes from the first part of the paragraph the text that goes to the last part.
- firstParagraphLayoutInfo.mText.Remove( indices.mCharacterParagraphIndex, firstParagraphLayoutInfo.mText.GetLength() - indices.mCharacterParagraphIndex );
-
- // Removes from the last part of the paragraph the text that remains in the first part.
- lastParagraphLayoutInfo.mText.Remove( 0u, indices.mCharacterParagraphIndex );
-
- // Sets the character's styles for the last part of the paragraph.
- lastParagraphLayoutInfo.mTextStyles.Insert( lastParagraphLayoutInfo.mTextStyles.End(),
- firstParagraphLayoutInfo.mTextStyles.Begin() + indices.mCharacterParagraphIndex,
- firstParagraphLayoutInfo.mTextStyles.End() );
-
- // Removes the character's styles that go to the last part of the paragraph.
- firstParagraphLayoutInfo.mTextStyles.Erase( firstParagraphLayoutInfo.mTextStyles.Begin() + indices.mCharacterParagraphIndex,
- firstParagraphLayoutInfo.mTextStyles.End() );
-}
-
-void MergeParagraph( ParagraphLayoutInfo& firstParagraphLayoutInfo,
- const ParagraphLayoutInfo& lastParagraphLayoutInfo )
-{
- // Merges two given paragraphs.
- //
- // Can't merge two paragraphs if the last word of the first one is a paragraph separator (new paragraph character)
-
- // Early returns.
-
- if( lastParagraphLayoutInfo.mWordsLayoutInfo.empty() )
- {
- // Nothing to merge if last paragraph is empty.
- return;
- }
-
- if( firstParagraphLayoutInfo.mWordsLayoutInfo.empty() )
- {
- // If first paragraph is empty, just copy the last paragraph to the first one.
- firstParagraphLayoutInfo = lastParagraphLayoutInfo;
-
- return;
- }
-
- // Check the last word of the first paragraph doesn't finish with a new paragraph character.
- WordLayoutInfo& lastWordLayout( *( firstParagraphLayoutInfo.mWordsLayoutInfo.end() - 1u ) );
- if( ParagraphSeparator == lastWordLayout.mType )
- {
- DALI_ASSERT_ALWAYS( !"TextViewProcessor::MergeParagraph(). ERROR: A paragraph can't be merged to another paragraph which finishes with a new paragraph character." );
- }
-
- // If the las word of the first paragraph or the first word of the last paragraph is a white space, both paragraphs can be concatenated.
- // Otherwise both words need to be merged first.
- const WordLayoutInfo& firstWordLayout( *lastParagraphLayoutInfo.mWordsLayoutInfo.begin() );
-
- std::size_t index = 0u;
- if( ( WordSeparator != lastWordLayout.mType ) && ( WordSeparator != firstWordLayout.mType ) && ( ParagraphSeparator != firstWordLayout.mType ) )
- {
- // Last word of the first paragraph is not a word separator and first word of the last paragraph is not a word or paragraph separator.
- // Words need to be merged.
-
- MergeWord( lastWordLayout,
- firstWordLayout );
-
- // After merging two words, the rest of the words need to be added.
- ++index; // By increasing this index the word already merged won't be added again.
- }
-
- // Merge layout info
-
- // Insert the layout of the words.
- const std::size_t numberOfWords = firstParagraphLayoutInfo.mWordsLayoutInfo.size();
- firstParagraphLayoutInfo.mWordsLayoutInfo.insert( firstParagraphLayoutInfo.mWordsLayoutInfo.end(),
- lastParagraphLayoutInfo.mWordsLayoutInfo.begin() + index, lastParagraphLayoutInfo.mWordsLayoutInfo.end() );
-
- // Increase the index of the first character of each inserted word.
- for( WordLayoutInfoContainer::iterator it = firstParagraphLayoutInfo.mWordsLayoutInfo.begin() + numberOfWords, endIt = firstParagraphLayoutInfo.mWordsLayoutInfo.end(); it != endIt; ++it )
- {
- WordLayoutInfo& word( *it );
- word.mFirstCharacter += firstParagraphLayoutInfo.mNumberOfCharacters;
- }
-
- // Update the size and other layout parameters.
- UpdateSize( firstParagraphLayoutInfo.mSize, lastParagraphLayoutInfo.mSize );
- firstParagraphLayoutInfo.mAscender = std::max( firstParagraphLayoutInfo.mAscender, lastParagraphLayoutInfo.mAscender );
- firstParagraphLayoutInfo.mLineHeightOffset = std::max( firstParagraphLayoutInfo.mLineHeightOffset, lastParagraphLayoutInfo.mLineHeightOffset );
- firstParagraphLayoutInfo.mNumberOfCharacters += lastParagraphLayoutInfo.mNumberOfCharacters;
-
- // Merge text and styles.
- firstParagraphLayoutInfo.mText.Append( lastParagraphLayoutInfo.mText );
- for( Vector<TextStyle*>::ConstIterator it = lastParagraphLayoutInfo.mTextStyles.Begin(), endIt = lastParagraphLayoutInfo.mTextStyles.End(); it != endIt; ++it )
- {
- firstParagraphLayoutInfo.mTextStyles.PushBack( new TextStyle( *(*it) ) );
- }
-}
-
-WordLayoutInfo GetLastWordLayoutInfo( const ParagraphLayoutInfo& paragraphLayoutInfo )
-{
- WordLayoutInfo layoutInfo;
-
- if( !paragraphLayoutInfo.mWordsLayoutInfo.empty() )
- {
- layoutInfo = *( paragraphLayoutInfo.mWordsLayoutInfo.end() - 1u );
- }
-
- return layoutInfo;
-}
-
-CharacterLayoutInfo GetFirstCharacterLayoutInfo( const ParagraphLayoutInfo& paragraphLayoutInfo )
-{
- CharacterLayoutInfo layoutInfo;
-
- if( !paragraphLayoutInfo.mWordsLayoutInfo.empty() )
- {
- const WordLayoutInfo& wordInfo( *paragraphLayoutInfo.mWordsLayoutInfo.begin() );
-
- layoutInfo = GetFirstCharacterLayoutInfo( wordInfo );
- }
-
- return layoutInfo;
-}
-
-CharacterLayoutInfo GetLastCharacterLayoutInfo( const ParagraphLayoutInfo& paragraphLayoutInfo )
-{
- const WordLayoutInfo wordInfo = GetLastWordLayoutInfo( paragraphLayoutInfo );
-
- return GetLastCharacterLayoutInfo( wordInfo );
-}
-
-void CollectTextActorsFromParagraphs( std::vector<TextActor>& textActors, const TextLayoutInfo& textLayoutInfo, const std::size_t paragraphIndexBegin, const std::size_t paragraphIndexEnd )
-{
- for( ParagraphLayoutInfoContainer::const_iterator paragraphIt = textLayoutInfo.mParagraphsLayoutInfo.begin() + paragraphIndexBegin, paragraphEndIt = textLayoutInfo.mParagraphsLayoutInfo.begin() + paragraphIndexEnd;
- paragraphIt != paragraphEndIt;
- ++paragraphIt )
- {
- const ParagraphLayoutInfo& paragraph( *paragraphIt );
-
- CollectTextActorsFromWords( textActors, paragraph, 0u, paragraph.mWordsLayoutInfo.size() );
- }
-}
-
-} //namespace TextViewProcessor
-
-} //namespace Internal
-
-} //namespace Toolkit
-
-} //namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PARAGRAPH_PROCESSOR_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PARAGRAPH_PROCESSOR_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewProcessor
-{
-
-/**
- * Creates a data structure with info to layout the paragraph, and data structures with useful info to modify the layout data structure if characters are added or removed.
- *
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info and conversion from visual to logical order and vice versa (for RTL text).
- * @param[out] paragraphLayoutInfo Layout info for the whole paragraph.
- */
-void CreateParagraphInfo( TextView::RelayoutData& relayoutData,
- ParagraphLayoutInfo& paragraphLayoutInfo );
-
-/**
- * Updates the paragraph layout info.
- *
- * @param[in,out] paragraphLayoutInfo The paragraph layout info.
- * @param[in] lineHeightOffset The offset added to the line height.
- */
-void UpdateLayoutInfo( ParagraphLayoutInfo& paragraphLayoutInfo, float lineHeightOffset );
-
-/**
- * Removes a given number of words from the given paragraph.
- *
- * @pre \e wordIndex and \e wordIndex + \e numberOfWords can't exceed the bounds of the paragraph.
- *
- * @param[in] wordIndex Index to the word within the paragraph with the starting position to be deleted.
- * @param[in] numberOfWords The number of words to be deleted.
- * @param[in] lineHeightOffset The offset added to the line height. Needed to update the layout info.
- * @param[in,out] paragraphLayout The input is the layout info of the paragraph. The output is the layout info of the paragraph without the removed words.
- */
-void RemoveWordsFromParagraph( std::size_t wordIndex,
- std::size_t numberOfWords,
- float lineHeightOffset,
- ParagraphLayoutInfo& paragraphLayout );
-
-/**
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info.
- * @param[in] numberOfCharacters The number of characters to be deleted.
- * @param[out] mergeWords Whether words need to be merged after removing characters.
- * @param[out] mergeParagraphs Whether current paragraph need to be merged with the next one.
- * @param[in,out] textInfoIndicesBegin Indices to the paragraph, word and characters from where to delete characters. It returns from where words need to be removed.
- * @param[out] textInfoIndicesEnd If paragraphs or words need to be merged it returns info to delete them (If a word is merged, it has to be removed. Equal for paragraphs).
- * @param[out] textInfoMergeIndicesBegin The indices to the first part of the paragraph and word to be merged.
- * @param[out] textInfoMergeIndicesEnd The indices to the last part of the paragraph and word to be merged.
- * @param[in,out] paragraphLayout Layout info of the paragraph where the word is located.
- * @param[out] removedTextActorsFromFirstWord Stores removed text-actors of the word pointed by the 'begin' index.
- * @param[out] removedTextActorsFromLastWord Stores removed text-actors of the word pointed by the 'end' index.
- */
-void RemoveCharactersFromParagraphInfo( TextView::RelayoutData& relayoutData,
- std::size_t numberOfCharacters,
- bool& mergeWords,
- bool& mergeParagraphs,
- TextInfoIndices& textInfoIndicesBegin,
- TextInfoIndices& textInfoIndicesEnd,
- TextInfoIndices& textInfoMergeIndicesBegin,
- TextInfoIndices& textInfoMergeIndicesEnd,
- ParagraphLayoutInfo& paragraphLayout,
- std::vector<TextActor>& removedTextActorsFromFirstWord,
- std::vector<TextActor>& removedTextActorsFromLastWord );
-
-/**
- * Splits a given paragraph in two.
- *
- * @note It deletes whatever there is in the last part of the paragraph.
- *
- * @param[in] indices Index to the word within the paragraph and index to the character within the word to split the paragraph.
- * @param[in] lineHeightOffset Additional space between lines. Needed to update layout info.
- * @param[in,out] firstParagraphLayoutInfo The input is the layout info of the given paragraph. The output is the first part of the input paragraph.
- * @param[in,out] lastParagraphLayoutInfo Layout info of the last part of the given paragraph.
- */
-void SplitParagraph( const TextInfoIndices& indices,
- float lineHeightOffset,
- ParagraphLayoutInfo& firstParagraphLayoutInfo,
- ParagraphLayoutInfo& lastParagraphLayoutInfo );
-
-/**
- * Merges the two given paragraphs by adding words of the last paragraph to the firs one.
- *
- * @note Does nothing if last part of the paragraph is empty.
- * @note If the first part of the paragraph is empty it just copy the last part to it.
- * @note it asserts if the last word of the first paragraph is a paragraph separator (new paragraph character)
- *
- * @param[in,out] firstParagraphLayoutInfo The input is the layout info of the first paragraph. The output is the layout info of the merged paragraph.
- * @param[in] lastParagraphLayoutInfo Layout info of the last paragraph.
- *
- */
-void MergeParagraph( ParagraphLayoutInfo& firstParagraphLayoutInfo,
- const ParagraphLayoutInfo& lastParagraphLayoutInfo );
-
-/**
- * Retrieves the layout information of the last word of the given paragraph.
- *
- * @param[in] paragraphLayoutInfo The paragraph layout.
- *
- * @return Layout information of the last word of the paragraph.
- */
-WordLayoutInfo GetLastWordLayoutInfo( const ParagraphLayoutInfo& paragraphLayoutInfo );
-
-/**
- * Retrieves the layout information of the first character of the given paragraph.
- *
- * @param[in] paragraphLayoutInfo The paragraph layout.
- *
- * @return Layout information of the first character of the paragraph.
- */
-CharacterLayoutInfo GetFirstCharacterLayoutInfo( const ParagraphLayoutInfo& paragraphLayoutInfo );
-
-/**
- * Retrieves the layout information of the last character of the given paragraph.
- *
- * @param[in] paragraphLayoutInfo The paragraph layout.
- *
- * @return Layout information of the last character of the paragraph.
- */
-CharacterLayoutInfo GetLastCharacterLayoutInfo( const ParagraphLayoutInfo& paragraphLayoutInfo );
-
-/**
- * Collects text-actors from the given paragraphs and stores them into the text-actor vector.
- *
- * @param[out] textActors Stores the text-actors of the given paragraphs.
- * @param[in] textLayoutInfo Whole text with the given paragraphs.
- * @param[in] paragraphIndexBegin The first paragraph.
- * @param[in] paragraphIndexEnd The last paragraph.
- */
-void CollectTextActorsFromParagraphs( std::vector<TextActor>& textActors, const TextLayoutInfo& textLayoutInfo, std::size_t paragraphIndexBegin, std::size_t paragraphIndexEnd );
-
-} //namespace TextViewProcessor
-
-} //namespace Internal
-
-} //namespace Toolkit
-
-} //namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PARAGRAPH_PROCESSOR_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-dbg.h>
-
-// EXTERNAL INCLUDES
-#include <iostream>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-types.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewProcessor
-{
-
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gTextViewProcessorLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TEXT_VIEW_PROCESSOR");
-#endif
-
-void dbgPrint( const WordLayoutInfo& word )
-{
- std::cout << " size " << word.mSize << std::endl;
- std::cout << " ascender " << word.mAscender << std::endl;
- std::cout << " type ";
- switch( word.mType )
- {
- case NoSeparator:
- {
- std::cout << "NoSeparator" << std::endl;
- break;
- }
- case ParagraphSeparator:
- {
- std::cout << "ParagraphSeparator" << std::endl;
- break;
- }
- case WordSeparator:
- {
- std::cout << "WordSeparator" << std::endl;
- break;
- }
- }
- std::cout << " first char " << word.mFirstCharacter << std::endl;
- std::cout << " num char " << word.mCharactersLayoutInfo.size() << std::endl;
- for( CharacterLayoutInfoContainer::const_iterator characterIt = word.mCharactersLayoutInfo.begin(), endCharacterIt = word.mCharactersLayoutInfo.end();
- characterIt != endCharacterIt;
- ++characterIt )
- {
- const CharacterLayoutInfo& character( *characterIt );
-
- std::cout << "[" << character.mSize << std::endl;
- std::cout << " ascender " << character.mAscender << std::endl;
- }
-}
-
-void dbgPrint( const ParagraphLayoutInfo& paragraph )
-{
- std::cout << "< ";
- std::cout << " text : [" << paragraph.mText.GetText() << "]" << std::endl;
- std::cout << " number of styles : " << paragraph.mTextStyles.Count() << std::endl;
- std::cout << paragraph.mSize;
- for( WordLayoutInfoContainer::const_iterator wordIt = paragraph.mWordsLayoutInfo.begin(), endWordIt = paragraph.mWordsLayoutInfo.end();
- wordIt != endWordIt;
- ++wordIt )
- {
- dbgPrint( *wordIt );
- }
- std::cout << " >";
- std::cout << std::endl;
-}
-
-void dbgPrint( const TextLayoutInfo& textInfo )
-{
- std::cout << "||" << std::endl;
- std::cout << textInfo.mWholeTextSize;
- std::cout << textInfo.mNumberOfCharacters;
- for( ParagraphLayoutInfoContainer::const_iterator it = textInfo.mParagraphsLayoutInfo.begin(), endIt = textInfo.mParagraphsLayoutInfo.end();
- it != endIt;
- ++it )
- {
- dbgPrint( *it );
- }
- std::cout << "||" << std::endl;
-}
-
-void dbgPrint( const TextStyle& style )
-{
- std::cout << " font name : " << style.GetFontName() << std::endl;
- std::cout << " font style : " << style.GetFontStyle() << std::endl;
- std::cout << " font point size : " << style.GetFontPointSize() << std::endl;
- std::cout << " weight : " << style.GetWeight() << std::endl;
- std::cout << " text color : " << style.GetTextColor() << std::endl;
- std::cout << " italics : " << style.IsItalicsEnabled() << std::endl;
- std::cout << " italics angle : " << style.GetItalicsAngle() << std::endl;
- std::cout << " underline : " << style.IsUnderlineEnabled() << std::endl;
- std::cout << " underline thickness : " << style.GetUnderlineThickness() << std::endl;
- std::cout << " underline position : " << style.GetUnderlinePosition() << std::endl;
- std::cout << " shadow : " << style.IsShadowEnabled() << std::endl;
- std::cout << " shadow color : " << style.GetShadowColor() << std::endl;
- std::cout << " shadow offset : " << style.GetShadowOffset() << std::endl;
- std::cout << " shadow size : " << style.GetShadowSize() << std::endl;
- std::cout << " glow : " << style.IsGlowEnabled() << std::endl;
- std::cout << " glow color : " << style.GetGlowColor() << std::endl;
- std::cout << " glow intensity : " << style.GetGlowIntensity() << std::endl;
- std::cout << " smooth edge : " << style.GetSmoothEdge() << std::endl;
- std::cout << " outline : " << style.IsOutlineEnabled() << std::endl;
- std::cout << " outline color : " << style.GetOutlineColor() << std::endl;
- std::cout << " outline thickness : " << style.GetOutlineThickness() << std::endl;
- std::cout << " gradient : " << style.IsGradientEnabled() << std::endl;
- std::cout << " gradient color : " << style.GetGradientColor() << std::endl;
- std::cout << " gradient start point : " << style.GetGradientStartPoint() << std::endl;
- std::cout << " gradient end point : " << style.GetGradientEndPoint() << std::endl;
- std::cout << " is font name default : " << style.IsFontNameDefault() << std::endl;
- std::cout << " is font style default : " << style.IsFontStyleDefault() << std::endl;
- std::cout << " is font size default : " << style.IsFontSizeDefault() << std::endl;
- std::cout << " is text color default : " << style.IsTextColorDefault() << std::endl;
- std::cout << " is font weight default : " << style.IsFontWeightDefault() << std::endl;
- std::cout << " is smooth edge default : " << style.IsSmoothEdgeDefault() << std::endl;
- std::cout << " is italics default : " << style.IsItalicsDefault() << std::endl;
- std::cout << " is underline default : " << style.IsUnderlineDefault() << std::endl;
- std::cout << " is shadow default : " << style.IsShadowDefault() << std::endl;
- std::cout << " is glow default : " << style.IsGlowDefault() << std::endl;
- std::cout << " is outline default : " << style.IsOutlineDefault() << std::endl;
- std::cout << " is gradient default : " << style.IsGradientDefault() << std::endl;
-}
-
-void dbgPrint( const TextInfoIndices& indices )
-{
- std::cout << " paragraph : " << indices.mParagraphIndex << std::endl;
- std::cout << " word : " << indices.mWordIndex << std::endl;
- std::cout << " char : " << indices.mCharacterIndex << std::endl;
- std::cout << " char in paragraph : " << indices.mCharacterParagraphIndex << std::endl;
-}
-
-void dbgPrint( const MarkupProcessor::StyledTextArray& textArray )
-{
- for( MarkupProcessor::StyledTextArray::const_iterator it = textArray.begin(), endIt = textArray.end(); it != endIt; ++it )
- {
- const MarkupProcessor::StyledText& text( *it );
-
- std::cout << text.mText.GetText();
- }
-}
-
-} // namespace TextViewProcessor
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_DBG_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_DBG_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/markup-processor/markup-processor.h>
-#include <dali/integration-api/debug.h>
-
-namespace Dali
-{
-
-//Forward declarations.
-class TextStyle;
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewProcessor
-{
-
-//Forward declarations.
-struct WordLayoutInfo;
-struct ParagraphLayoutInfo;
-struct TextLayoutInfo;
-struct TextInfoIndices;
-
-#if defined(DEBUG_ENABLED)
-extern Debug::Filter* gTextViewProcessorLogFilter;
-#endif
-
-void dbgPrint( const WordLayoutInfo& word );
-void dbgPrint( const ParagraphLayoutInfo& paragraph );
-void dbgPrint( const TextLayoutInfo& textInfo );
-void dbgPrint( const TextStyle& style );
-void dbgPrint( const TextInfoIndices& indices );
-void dbgPrint( const MarkupProcessor::StyledTextArray& text );
-
-} // namespace TextViewProcessor
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_DBG_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-helper-functions.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-dbg.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewProcessor
-{
-
-void UpdateSize( Size& size1, const Size& size2, const SizeGrowType type )
-{
- switch( type )
- {
- case GrowWidth:
- {
- size1.width += size2.width;
- size1.height = std::max( size1.height, size2.height );
- break;
- }
- case GrowHeight:
- {
- size1.width = std::max( size1.width, size2.width );
- size1.height += size2.height;
- break;
- }
- }
-}
-
-TextSeparatorType GetTextSeparatorType( const Character& character )
-{
- // returns if the given character is a paragraph separator '\n', a word separator ' ' or if is not a separator (any other character).
- return ( character.IsNewLine() ? ParagraphSeparator : ( character.IsWhiteSpace() ? WordSeparator : NoSeparator ) );
-}
-
-void ChooseFontFamilyName( const Character& character, TextStyle& style )
-{
- DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "-->TextViewProcessor::ChooseFontFamilyName\n" );
- DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, " input font name: [%s]\n", style.GetFontName().c_str() );
-
- bool userDefinedFontFamilyName = false;
-
- // First check if there is a font defined in the style and it supports the given text.
- if( !style.GetFontName().empty() )
- {
- const FontParameters fontParams( style.GetFontName(), style.GetFontStyle() , style.GetFontPointSize() );
- const Font font = Font::New( fontParams );
-
- if( !font.IsDefaultSystemFont() && font.AllGlyphsSupported( character ) )
- {
- userDefinedFontFamilyName = true;
- }
- }
-
- if( !userDefinedFontFamilyName )
- {
- const Font defaultSystemFont = Font::New();
-
- // At this point no font is set or doesn't support the given text.
- if( !defaultSystemFont.AllGlyphsSupported( character ) )
- {
- // If the default system font doesn't support the given text,
- // an appropiate font is selected.
- style.SetFontName( Font::GetFamilyForText( character ) );
- // @TODO Font::GetFamilyForText() should return font family and font style.
- }
- else
- {
- // All characters are supported with default font, so use it
- style.SetFontName( "" );
- }
- }
- DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, " output font name: [%s]\n", style.GetFontName().c_str() );
- DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "<--TextViewProcessor::ChooseFontFamilyName\n" );
-}
-
-void GetIndicesFromGlobalCharacterIndex( const std::size_t index,
- const TextLayoutInfo& textLayoutInfo,
- TextInfoIndices& indices )
-{
- // clear all indices
- indices = TextInfoIndices();
-
- // Early return.
- if( textLayoutInfo.mParagraphsLayoutInfo.empty() )
- {
- // Text is empty. All indices are 0.
- return;
- }
-
- std::size_t currentIndex = 0u; // stores how many characters have been traversed (within the whole text).
-
- // Traverse all paragraphs and words until global index is found.
- bool found = false;
- for( ParagraphLayoutInfoContainer::const_iterator paragraphIt = textLayoutInfo.mParagraphsLayoutInfo.begin(),
- paragraphEndIt = textLayoutInfo.mParagraphsLayoutInfo.end();
- ( !found ) && ( paragraphIt != paragraphEndIt );
- ++paragraphIt, ++indices.mParagraphIndex )
- {
- const ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphIt );
- std::size_t currentCharactersTraversed = currentIndex; // stores how many characters have been traversed until this paragraph.
-
- if( currentIndex + paragraphLayoutInfo.mNumberOfCharacters > index )
- {
- // The character is in this paragraph
- for( WordLayoutInfoContainer::const_iterator wordIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
- wordEndIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
- ( !found ) && ( wordIt != wordEndIt );
- ++wordIt, ++indices.mWordIndex )
- {
- const WordLayoutInfo& wordLayoutInfo( *wordIt );
-
- if( currentIndex + wordLayoutInfo.mCharactersLayoutInfo.size() > index )
- {
- // The character is in this word
- indices.mCharacterIndex = index - currentIndex;
- indices.mCharacterParagraphIndex = index - currentCharactersTraversed;
- found = true;
- }
- else
- {
- // check in the next word.
- currentIndex += wordLayoutInfo.mCharactersLayoutInfo.size();
- }
- } // end words.
- if( !paragraphLayoutInfo.mWordsLayoutInfo.empty() )
- {
- --indices.mWordIndex;
- }
- }
- else
- {
- // check in the next paragraph
- currentIndex += paragraphLayoutInfo.mNumberOfCharacters;
- }
- } // end paragraphs.
-
- // Need to decrease indices as they have been increased in the last loop.
- if( !textLayoutInfo.mParagraphsLayoutInfo.empty() )
- {
- --indices.mParagraphIndex;
- }
-}
-
-void ClearText( std::vector<TextActor>& textActors )
-{
- for( std::vector<TextActor>::iterator it = textActors.begin(), endIt = textActors.end(); it != endIt; ++it )
- {
- (*it).SetText( std::string( "" ) );
- }
-}
-
-} //namespace TextViewProcessor
-
-} //namespace Internal
-
-} //namespace Toolkit
-
-} //namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_HELPER_FUNCTIONS_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_HELPER_FUNCTIONS_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/public-api/actors/text-actor.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-types.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewProcessor
-{
-
-/**
- * Enum type used to update a size adding other one.
- * If the grow type is \e GrowWidth, size's widths are added and size's height is the max of both.
- * Alternativelly if grow type is \e GrowHeight heights are added and width is the max of both.
- */
-enum SizeGrowType
-{
- GrowWidth,
- GrowHeight,
-};
-
-/**
- * Updates the size of a character, word, line or the whole text with a given size.
- *
- * For characters, words, and lines the new height will be the maximum of both sizes
- * and the new width will be the sum of both.
- *
- * For the whole text, the new height will be the sum of both and the new width the max of both.
- *
- * The \e type parameter speficies which type of update is required.
- *
- * @param[in,out] size1 The current size to be updated.
- * @param[in] size2 The size of a character, word, or a line.
- * @param[in] type Type of update.
- */
-void UpdateSize( Size& size1, const Size& size2, SizeGrowType type = GrowWidth );
-
-/**
- * Return the type of separator (white space, new line or no separator) for the given character.
- *
- * @param[in] character The given character.
- *
- * @return The type of separator.
- */
-TextSeparatorType GetTextSeparatorType( const Character& character );
-
-/**
- * Choose a suitable font family name for the given character.
- *
- * It may modify the text-style of the given character by setting a suitable font-family.
- *
- * @param[in] character The character.
- * @param[in,out] style The style of the character.
- */
-void ChooseFontFamilyName( const Character& character, TextStyle& style );
-
-/**
- * Retrieves the line, word and character indices for the given global character's index.
- *
- * i.e. The retrieved indices for the character 18 (j) for the following text would be: 2, 0, 2, 0
- *
- * a b c d
- * e f g h
- * i j k l
- * m n o p
- *
- * @param[in] index The global character index.
- * @param[in] textLayoutInfo Contains info about the number of characters per word, and line.
- * @param[out] indices Index to the line, word and character within the word where the given character is located.
- */
-void GetIndicesFromGlobalCharacterIndex( std::size_t index,
- const TextLayoutInfo& textLayoutInfo,
- TextInfoIndices& indices );
-
-/**
- * Clear the text of the given text-actors.
- *
- * @param[in] textActors The given text-actors.
- */
-void ClearText( std::vector<TextActor>& textActors );
-
-} //namespace TextViewProcessor
-
-} //namespace Internal
-
-} //namespace Toolkit
-
-} //namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_HELPER_FUNCTIONS_H__
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_TYPES_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_TYPES_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/public-api/actors/renderable-actor.h>
-#include <dali/public-api/text/text.h>
-
-namespace Dali
-{
-
-class TextStyle;
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextProcessor
-{
-// Forward declarations.
-struct BidirectionalParagraphInfo;
-struct BidirectionalLineInfo;
-} // namespace TextProcessor
-
-namespace TextViewProcessor
-{
-
-/**
- * Whether the text is a new paragraph character '\n', a white space or normal text.
- */
-enum TextSeparatorType
-{
- ParagraphSeparator,
- WordSeparator,
- NoSeparator
-};
-
-/**
- * Whether to clear the text of the text-actors when text is removed.
- */
-enum TextOperationOnRemove
-{
- CLEAR_TEXT,
- KEEP_TEXT
-};
-
-
-/**
- * Stores text info indices.
- */
-struct TextInfoIndices
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their default values.
- */
- TextInfoIndices();
-
- /**
- * Constructor.
- */
- TextInfoIndices( std::size_t paragraphIndex,
- std::size_t wordIndex,
- std::size_t characterIndex );
-
- /**
- * Equality operator.
- * @param [in] indices The text-info indices to be compared.
- *
- * @return \e true if both indices are equal.
- */
- bool operator==( const TextInfoIndices& indices ) const;
-
- std::size_t mParagraphIndex; ///< The paragraph index within the text.
- std::size_t mWordIndex; ///< The word index within the paragraph.
- std::size_t mCharacterIndex; ///< The character index within the word.
- std::size_t mCharacterParagraphIndex; ///< The character index within the paragraph.
-};
-
-/**
- * Stores gradient info.
- *
- * Used to fade in/out text-actors.
- */
-struct GradientInfo
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their default values.
- */
- GradientInfo();
-
- /**
- * Default destructor.
- */
- ~GradientInfo();
-
- /**
- * Copy constructor
- */
- GradientInfo( const GradientInfo& info );
-
- /**
- * Assignment operator.
- */
- GradientInfo& operator=( const GradientInfo& info );
-
- Vector4 mGradientColor; ///< Gradient color.
- Vector2 mStartPoint; ///< Gradient start point.
- Vector2 mEndPoint; ///< Gradient end point.
-};
-
-/**
- * Layout information for a character.
- * It stores the position, size and ascender of its respective text-actor.
- */
-struct CharacterLayoutInfo
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their default values.
- */
- CharacterLayoutInfo();
-
- /**
- * Default destructor.
- *
- * Deletes the gradient info.
- */
- ~CharacterLayoutInfo();
-
- /**
- * Copy constructor.
- */
- CharacterLayoutInfo( const CharacterLayoutInfo& character );
-
- /**
- * Assignment operator.
- */
- CharacterLayoutInfo& operator=( const CharacterLayoutInfo& character );
-
- // Metrics of the glyph.
- Size mSize; ///< Height of the font and advance (the horizontal distance from the origin of the current character and the next one).
- float mBearing; ///< Vertical distance from the baseline to the top of the glyph's boundary box.
- float mAscender; ///< Distance from the base line to the top of the line.
- float mUnderlineThickness; ///< The underline's thickness.
- float mUnderlinePosition; ///< The underline's position.
-
- // Position and alignment offset. It depends on the lay-out.
- Vector3 mPosition; ///< Position within the text-view
- Vector2 mOffset; ///< Alignment and justification offset.
-
- RenderableActor mGlyphActor; ///< Handle to a text-actor.
- float mColorAlpha; ///< Alpha component for the initial text color when text is faded.
- GradientInfo* mGradientInfo; ///< Stores gradient info.
-
- bool mIsVisible:1; ///< Whether the text-actor is visible.
- bool mSetText:1; ///< Whether a new text needs to be set in the text-actor.
- bool mSetStyle:1; ///< Whether a new style needs to be set in the text-actor.
- bool mIsColorGlyph:1; ///< Whether this character is an emoticon.
-};
-typedef std::vector<CharacterLayoutInfo> CharacterLayoutInfoContainer;
-
-/**
- * Layout information for a word.
- */
-struct WordLayoutInfo
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their default values.
- */
- WordLayoutInfo();
-
- /**
- * Default destructor.
- *
- * Clears all characters.
- */
- ~WordLayoutInfo();
-
- /**
- * Copy constructor.
- */
- WordLayoutInfo( const WordLayoutInfo& word );
-
- /**
- * Assignment operator.
- */
- WordLayoutInfo& operator=( const WordLayoutInfo& word );
-
- Size mSize; ///< Size of the word.
- float mAscender; ///< Max of all ascenders of all characters.
- TextSeparatorType mType; ///< Whether this word is a word separator, a line separator or is not a separator.
- std::size_t mFirstCharacter; ///< Index to the first character of the word within the paragraph.
- CharacterLayoutInfoContainer mCharactersLayoutInfo; ///< Layout info for all characters.
-};
-typedef std::vector<WordLayoutInfo> WordLayoutInfoContainer;
-
-/**
- * Stores the reordered layout for right to left text.
- */
-struct RightToLeftParagraphLayout
-{
- RightToLeftParagraphLayout()
- : mWordsLayoutInfo(),
- mText(),
- mTextStyles(),
- mPreviousLayoutCleared( false )
- {
- }
-
- WordLayoutInfoContainer mWordsLayoutInfo; ///< Layout info for all words.
- Text mText; ///< Stores the text.
- Vector<TextStyle*> mTextStyles; ///< Stores the style per each character.
- bool mPreviousLayoutCleared:1; ///< Whether the previous right to left layout has been cleared.
-
- /**
- * Clears the word layout vector, the text and the vector of styles.
- */
- void Clear();
-};
-
-/**
- * Layout information for a paragraph.
- */
-struct ParagraphLayoutInfo
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their default values.
- */
- ParagraphLayoutInfo();
-
- /**
- * Default destructor.
- *
- * Clears all words, deletes all text styles, the paragraph bidirectional info and all bidirectional infor for each line.
- */
- ~ParagraphLayoutInfo();
-
- /**
- * Copy constructor.
- */
- ParagraphLayoutInfo( const ParagraphLayoutInfo& paragraph );
-
- /**
- * Assignment operator.
- */
- ParagraphLayoutInfo& operator=( const ParagraphLayoutInfo& paragraph );
-
- /**
- * Deletes the bidirectional info for each line.
- */
- void ClearBidirectionalInfo();
-
-private:
-
- /**
- * Deletes all text styles.
- */
- void ClearStyles();
-
-public:
- Size mSize; ///< Size of the paragraph.
- float mAscender; ///< Max of all ascenders of all words.
- float mLineHeightOffset; ///< Line height offset.
- std::size_t mFirstCharacter; ///< Index to the first character of the paragraph.
- std::size_t mNumberOfCharacters; ///< Stores the number of characters.
- WordLayoutInfoContainer mWordsLayoutInfo; ///< Layout info for all words.
- Text mText; ///< Stores the text.
- Vector<TextStyle*> mTextStyles; ///< Stores the style per each character.
- RightToLeftParagraphLayout* mRightToLeftLayout; ///< Stores the reordered layout for the paragraph.
- TextProcessor::BidirectionalParagraphInfo* mBidirectionalParagraphInfo; ///< Contains bidirectional info for the whole paragraph. Set to NULL if the paragraph has left to right characters only.
- Vector<TextProcessor::BidirectionalLineInfo*> mBidirectionalLinesInfo; ///< Contains bidirectional info for each laid-out line.
-};
-typedef std::vector<ParagraphLayoutInfo> ParagraphLayoutInfoContainer;
-
-/**
- * Layout information for the whole text.
- */
-struct TextLayoutInfo
-{
- /**
- * Default constructor.
- *
- * Initializes all members to their default values.
- */
- TextLayoutInfo();
-
- /**
- * Defualt destructor.
- *
- * Clears the paragraph vector, the ellipsis text and deletes all ellipsis styles.
- */
- ~TextLayoutInfo();
-
- /**
- * Copy constructor.
- */
- TextLayoutInfo( const TextLayoutInfo& text );
-
- /**
- * Assignment operator.
- */
- TextLayoutInfo& operator=( const TextLayoutInfo& text );
-
-private:
- /**
- * Deletes all the ellipsis text styles.
- */
- void ClearStyles();
-
-public:
- Size mWholeTextSize; ///< width and height of the whole text.
- float mMaxWordWidth; ///< maximum width between all words.
- float mMaxItalicsOffset; ///< When rendering text-view in offscreen an extra width offset is needed to prevent italic characters to be cut if they are in the right edge.
- std::size_t mNumberOfCharacters; ///< Stores the number of characters.
- ParagraphLayoutInfoContainer mParagraphsLayoutInfo; ///< Layout information for all paragraphs.
- WordLayoutInfo mEllipsizeLayoutInfo; ///< Layout information for the ellipsize text.
- Dali::Text mEllipsisText; ///< The ellipsis text.
- Vector<TextStyle*> mEllipsisTextStyles; ///< Stores the style per each character of the ellipsis text.
-};
-
-} // namespace TextViewProcessor
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_TYPES_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
-
-// INTERNAL INCLUDES
-#include <dali/integration-api/debug.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-paragraph-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-helper-functions.h>
-#include <dali-toolkit/internal/controls/text-view/text-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewProcessor
-{
-
-namespace
-{
-/**
- * Update text layout info.
- *
- * Updates the size of the whole text, the maximum width of all words and the number of characters.
- *
- * @param[in,out] textLayoutInfo
- */
-void UpdateLayoutInfo( TextLayoutInfo& textLayoutInfo )
-{
- // Initialize members to be updated.
- textLayoutInfo.mWholeTextSize = Size::ZERO;
- textLayoutInfo.mMaxWordWidth = 0.f;
- textLayoutInfo.mNumberOfCharacters = 0u;
-
- // Traverse all text updating values.
- for( ParagraphLayoutInfoContainer::const_iterator paragraphIt = textLayoutInfo.mParagraphsLayoutInfo.begin(), paragraphEndIt = textLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphIt != paragraphEndIt;
- ++paragraphIt )
- {
- const ParagraphLayoutInfo& paragraph( *paragraphIt );
-
- // Updates text size with the size of all paragraphs.
- UpdateSize( textLayoutInfo.mWholeTextSize, paragraph.mSize, GrowHeight );
-
- // Updates number of characters.
- textLayoutInfo.mNumberOfCharacters += paragraph.mNumberOfCharacters;
-
- // Updates the max word's width.
- for( WordLayoutInfoContainer::const_iterator wordIt = paragraph.mWordsLayoutInfo.begin(), wordEndIt = paragraph.mWordsLayoutInfo.end();
- wordIt != wordEndIt;
- ++wordIt )
- {
- const WordLayoutInfo& word( *wordIt );
-
- textLayoutInfo.mMaxWordWidth = std::max( textLayoutInfo.mMaxWordWidth, word.mSize.width );
- }
- }
-}
-
-} // namespace
-
-// Constructors and assignment operators
-
-TextInfoIndices::TextInfoIndices()
-: mParagraphIndex( 0u ),
- mWordIndex( 0u ),
- mCharacterIndex( 0u ),
- mCharacterParagraphIndex( 0u )
-{
-}
-
-TextInfoIndices::TextInfoIndices( const std::size_t paragraphIndex,
- const std::size_t wordIndex,
- const std::size_t characterIndex )
-: mParagraphIndex( paragraphIndex ),
- mWordIndex( wordIndex ),
- mCharacterIndex( characterIndex ),
- mCharacterParagraphIndex( 0u )
-{
-}
-
-bool TextInfoIndices::operator==( const TextInfoIndices& indices ) const
-{
- return ( ( mParagraphIndex == indices.mParagraphIndex ) &&
- ( mWordIndex == indices.mWordIndex ) &&
- ( mCharacterIndex == indices.mCharacterIndex ) &&
- ( mCharacterParagraphIndex == indices.mCharacterParagraphIndex ) );
-}
-
-/////////////////////
-// Layout info.
-/////////////////////
-
-TextLayoutInfo::TextLayoutInfo()
-: mWholeTextSize(),
- mMaxWordWidth( 0.f ),
- mMaxItalicsOffset( 0.f ),
- mNumberOfCharacters( 0u ),
- mParagraphsLayoutInfo(),
- mEllipsizeLayoutInfo(),
- mEllipsisText( "..." ),
- mEllipsisTextStyles()
-{
- // Sets default styles for the default ellipsis text.
- mEllipsisTextStyles.PushBack( new TextStyle() );
- mEllipsisTextStyles.PushBack( new TextStyle() );
- mEllipsisTextStyles.PushBack( new TextStyle() );
-}
-
-TextLayoutInfo::~TextLayoutInfo()
-{
- ClearStyles();
-}
-
-TextLayoutInfo::TextLayoutInfo( const TextLayoutInfo& text )
-: mWholeTextSize( text.mWholeTextSize ),
- mMaxWordWidth( text.mMaxWordWidth ),
- mMaxItalicsOffset( text.mMaxItalicsOffset ),
- mNumberOfCharacters( text.mNumberOfCharacters ),
- mParagraphsLayoutInfo( text.mParagraphsLayoutInfo ),
- mEllipsizeLayoutInfo( text.mEllipsizeLayoutInfo ),
- mEllipsisText( text.mEllipsisText ),
- mEllipsisTextStyles()
-{
- for( Vector<TextStyle*>::ConstIterator it = text.mEllipsisTextStyles.Begin(), endIt = text.mEllipsisTextStyles.End(); it != endIt; ++it )
- {
- mEllipsisTextStyles.PushBack( new TextStyle( *(*it) ) );
- }
-}
-
-TextLayoutInfo& TextLayoutInfo::operator=( const TextLayoutInfo& text )
-{
- if( this != &text )
- {
- mWholeTextSize = text.mWholeTextSize;
- mMaxWordWidth = text.mMaxWordWidth;
- mMaxItalicsOffset = text.mMaxItalicsOffset;
- mNumberOfCharacters = text.mNumberOfCharacters;
- mParagraphsLayoutInfo = text.mParagraphsLayoutInfo;
- mEllipsizeLayoutInfo = text.mEllipsizeLayoutInfo;
- mEllipsisText = text.mEllipsisText;
-
- ClearStyles();
-
- for( Vector<TextStyle*>::ConstIterator it = text.mEllipsisTextStyles.Begin(), endIt = text.mEllipsisTextStyles.End(); it != endIt; ++it )
- {
- mEllipsisTextStyles.PushBack( new TextStyle( *(*it) ) );
- }
- }
- return *this;
-}
-
-void TextLayoutInfo::ClearStyles()
-{
- for( Vector<TextStyle*>::Iterator it = mEllipsisTextStyles.Begin(), endIt = mEllipsisTextStyles.End(); it != endIt; ++it )
- {
- delete *it;
- }
- mEllipsisTextStyles.Clear();
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-void CreateTextInfo( const MarkupProcessor::StyledTextArray& text,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- // * Traverse the given text spliting it in paragraphs and each paragraph in words.
- // * White spaces and new paragraph characters are alone in one word.
- // * Bidirectional text is processed in each paragraph.
- // It creates the conversion tables
- // It does the ligatures if there is arabic glyphs.
- // It doesn't reorder the text as it must be done for each line not for the paragraph.
- // * Generates a layout data structure to store layout information (size, position, ascender, text direction, etc) and metrics of all characters.
- // * Store text for each paragraph and the style for each character.
-
- // Collect previously created text-actors.
- std::vector<TextActor> textActors;
- CollectTextActorsFromParagraphs( textActors, relayoutData.mTextLayoutInfo, 0u, relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.size() );
-
- if( !textActors.empty() )
- {
- // Add text-actors to the cache.
- relayoutData.mTextActorCache.InsertTextActors( textActors );
- relayoutData.mTextActorCache.ClearTexts();
- }
-
- // Store the ellipsize layout info before clearing the previous created info.
- // TODO: fix this. Don't clear the ellipsis layout, store it somewhere else ...
- const WordLayoutInfo ellipsizeInfo = relayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo;
- Dali::Text ellipsisText = relayoutData.mTextLayoutInfo.mEllipsisText;
- Vector<TextStyle*> ellipsisTextStyles = relayoutData.mTextLayoutInfo.mEllipsisTextStyles;
- relayoutData.mTextLayoutInfo.mEllipsisTextStyles.Clear();
-
- // clear previously created info.
- relayoutData.mTextLayoutInfo = TextLayoutInfo();
- relayoutData.mCharacterLogicalToVisualMap.clear();
- relayoutData.mCharacterVisualToLogicalMap.clear();
-
- // Sets the ellipsize layout info.
- relayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = ellipsizeInfo;
- relayoutData.mTextLayoutInfo.mEllipsisText = ellipsisText;
- relayoutData.mTextLayoutInfo.mEllipsisTextStyles = ellipsisTextStyles;
-
- // Split the whole text in paragraphs.
- // It returns a vector of Text with all the paragraphs.
- // and for each paragraph a vector of styles per character. TODO: don't create a style per character.
- std::vector<Text> paragraphs;
- std::vector< Vector<TextStyle*> > styles;
- TextProcessor::SplitInParagraphs( text,
- paragraphs,
- styles );
-
- // Reserve space for the current number of paragraphs.
- relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.resize( paragraphs.size(), ParagraphLayoutInfo() );
-
- // Traverse all paragraphs
- std::size_t paragraphIndex = 0u;
- std::vector<Text>::iterator paragraphIt, paragraphEndIt;
- std::vector< Vector<TextStyle*> >::const_iterator styleIt, styleEndIt;
- for( paragraphIt = paragraphs.begin(), paragraphEndIt = paragraphs.end(),
- styleIt = styles.begin(), styleEndIt = styles.end();
- ( paragraphIt != paragraphEndIt ) && ( styleIt != styleEndIt );
- ++paragraphIndex,
- ++paragraphIt,
- ++styleIt )
- {
- // Gets the paragraph and the styles for each character.
- Text& paragraph( *paragraphIt );
- const Vector<TextStyle*>& textStyles( *styleIt );
-
- // Retrieve the data structure for the current paragraph.
- ParagraphLayoutInfo& paragraphLayoutInfo = *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + paragraphIndex );
-
- // Sets text and styles.
- paragraphLayoutInfo.mText = paragraph;
- paragraphLayoutInfo.mTextStyles = textStyles;
-
- // Fills the paragraph data structure with the layout info.
-
- if( !paragraph.IsEmpty() )
- {
- CreateParagraphInfo( relayoutData,
- paragraphLayoutInfo );
-
- // do not add the line offset if the paragraph has no characters.
- paragraphLayoutInfo.mSize.height += layoutParameters.mLineHeightOffset;
- paragraphLayoutInfo.mLineHeightOffset = layoutParameters.mLineHeightOffset;
- }
- else
- {
- // This paragraph has no text. i.e. the previous paragraph ends with '\n'.
- // Even though, line height needs to be set in order to align the whole text correctly.
-
- float lineHeight = 0.f;
- // Get the last character of the last paragraph.
- if( 0u < paragraphIndex )
- {
- const ParagraphLayoutInfo& paragraphInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + ( paragraphIndex - 1u ) ) );
-
- const CharacterLayoutInfo characterInfo = GetLastCharacterLayoutInfo( paragraphInfo );
-
- lineHeight = characterInfo.mSize.height;
- }
-
- paragraphLayoutInfo.mSize.height = lineHeight;
- }
-
- // Fills the conversion tables used to get the logical or visual position of a character is case there is right to left text.
- // If there is right to left text, it needs to be updated every time the text is relaid-out.
- for( std::size_t index = 0u; index < paragraphLayoutInfo.mNumberOfCharacters; ++index )
- {
- relayoutData.mCharacterLogicalToVisualMap.push_back( relayoutData.mTextLayoutInfo.mNumberOfCharacters + index );
- relayoutData.mCharacterVisualToLogicalMap.push_back( relayoutData.mTextLayoutInfo.mNumberOfCharacters + index );
- }
-
- // Update layout info for the whole text.
- UpdateSize( relayoutData.mTextLayoutInfo.mWholeTextSize, paragraphLayoutInfo.mSize, GrowHeight );
- relayoutData.mTextLayoutInfo.mNumberOfCharacters += paragraphLayoutInfo.mNumberOfCharacters;
- } // end of paragraphs
-}
-
-void UpdateTextInfo( std::size_t position,
- const MarkupProcessor::StyledTextArray& text,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- // Update current internal data structure with added text.
-
- // * Creates layout info for the given text.
- // * With the given position, find where to add the text.
- // * If the new text is not added at the end of current text, a paragraph need to be split.
- // * Merge the last paragraph of the new text to the last part or the split paragraph.
- // * Add paragraphs between first and last of the new text.
- // * Merge the first part of the split paragraph with the first paragraph of the new text.
- // * Update the layout info for the whole text.
-
- // Early returns:
-
- if( text.empty() )
- {
- // nothing to do if the input text is empty.
- return;
- }
-
- if( 0u == relayoutData.mTextLayoutInfo.mNumberOfCharacters )
- {
- // Current text is empty. There is no need to update current data structure,
- // just create a new one with the new input text.
- CreateTextInfo( text,
- layoutParameters,
- relayoutData );
- return;
- }
-
- // initial checks.
- if( position > relayoutData.mTextLayoutInfo.mNumberOfCharacters )
- {
- // Asserts if text is to be added out of bounds.
- DALI_ASSERT_ALWAYS( !"TextViewProcessor::UpdateTextInfo (insert). Trying to insert text out of bounds." );
- }
-
-
- // TODO
- // If in the insertion is involved right to left text,
- // check the neighbour characters is needed.
- // i.e. Arabic characters may have four different glyphs (isolated, end, middle, begin).
- // So check the neighbours on each side is needed in order to render
- // the correct ligatures.
-
-
- TextView::RelayoutData relayoutDataForNewText;
-
- // Creates layout info for the given text.
- // It doesn't create text-actors as text could be added to an existing one.
- CreateTextInfo( text,
- layoutParameters,
- relayoutDataForNewText );
-
- // Fills the conversion tables used to get the logical or visual position of a character is case there is right to left text.
- // If there is right to left text, it needs to be updated every time the text is relaid-out.
- std::size_t index = 0u;
- for( std::size_t i = 0u; i < relayoutDataForNewText.mTextLayoutInfo.mNumberOfCharacters; ++i )
- {
- relayoutData.mCharacterLogicalToVisualMap.push_back( relayoutData.mTextLayoutInfo.mNumberOfCharacters + index );
- relayoutData.mCharacterVisualToLogicalMap.push_back( relayoutData.mTextLayoutInfo.mNumberOfCharacters + index );
- ++index;
- }
-
- // If a paragraph is split, it stores the last part of the paragraph.
- ParagraphLayoutInfo lastParagraphLayoutInfo;
-
- // Stores indices to the paragraph, word and character of the given position.
- TextInfoIndices textInfoIndices;
-
- if( position < relayoutData.mTextLayoutInfo.mNumberOfCharacters )
- {
- // Get paragraph, word and character indices for given position.
- GetIndicesFromGlobalCharacterIndex( position,
- relayoutData.mTextLayoutInfo,
- textInfoIndices );
-
- // 1) Split the paragraph
-
- // Split a paragraph in two is needed, then merge the first part of the split paragraph
- // with the first paragraph of the new text, add subsequent paragraphs and merge the last paragraph
- // of the new text with the last part of the split paragraph.
-
- // Implementation notes!
- //
- // These references to the first paragraph are declared in this scope because if new paragraphs are inserted in step 2,
- // they become invalid, making the algorithm to crash if used again.
- // In the step 3, references to the first paragraph are needed and declared again.
-
- // Stores the first part of the split paragraph.
- ParagraphLayoutInfo& firstParagraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndices.mParagraphIndex ) );
-
- SplitParagraph( textInfoIndices,
- PointSize( layoutParameters.mLineHeightOffset ),
- firstParagraphLayoutInfo,
- lastParagraphLayoutInfo );
- }
- else
- {
- // Position is just after the last character.
- // Calculates indices for that position.
- if( !relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
- {
- textInfoIndices.mParagraphIndex = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.size() - 1u;
- const ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u ) );
-
- if( !paragraphLayoutInfo.mWordsLayoutInfo.empty() )
- {
- textInfoIndices.mWordIndex = paragraphLayoutInfo.mWordsLayoutInfo.size() - 1u;
-
- const WordLayoutInfo& wordLayoutInfo( *( paragraphLayoutInfo.mWordsLayoutInfo.end() - 1u ) );
- textInfoIndices.mCharacterIndex = wordLayoutInfo.mCharactersLayoutInfo.size();
-
- // Sets the character index within the paragraph.
- textInfoIndices.mCharacterParagraphIndex = 0u;
- for( WordLayoutInfoContainer::const_iterator it = paragraphLayoutInfo.mWordsLayoutInfo.begin(), endIt = paragraphLayoutInfo.mWordsLayoutInfo.end(); it != endIt; ++it )
- {
- textInfoIndices.mCharacterParagraphIndex += wordLayoutInfo.mCharactersLayoutInfo.size();
- }
- }
- }
- }
-
- // 2) If the new text has more than 1 paragraph, merge the last paragraph of the input text with the last part of the split paragraph.
- //TODO check this cases ( num paragraphs ==1, >1, >2 ) if it could be simplified.
- if( relayoutDataForNewText.mTextLayoutInfo.mParagraphsLayoutInfo.size() > 1u )
- {
- ParagraphLayoutInfo& lastInputParagraphLayoutInfo( *( relayoutDataForNewText.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u ) );
-
- MergeParagraph( lastInputParagraphLayoutInfo,
- lastParagraphLayoutInfo );
-
- if( relayoutDataForNewText.mTextLayoutInfo.mParagraphsLayoutInfo.size() > 2u )
- {
- // Insert all paragraphs except first and last in the text.
- relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.insert( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndices.mParagraphIndex + 1u,
- relayoutDataForNewText.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + 1u,
- relayoutDataForNewText.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u );
- }
-
- // Insert the last paragraph to the text
- relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.insert( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndices.mParagraphIndex + relayoutDataForNewText.mTextLayoutInfo.mParagraphsLayoutInfo.size() - 1u,
- lastInputParagraphLayoutInfo );
- }
- else
- {
- // Merge the new paragraph to the last part of the split paragraph.
- ParagraphLayoutInfo& inputParagraphLayoutInfo( *relayoutDataForNewText.mTextLayoutInfo.mParagraphsLayoutInfo.begin() );
-
- MergeParagraph( inputParagraphLayoutInfo,
- lastParagraphLayoutInfo );
- }
-
- // 3) Merge the first paragraph of the split text with the first paragraph of the input text.
- ParagraphLayoutInfo& firstParagraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndices.mParagraphIndex ) );
- ParagraphLayoutInfo& firstInputParagraphLayoutInfo( *relayoutDataForNewText.mTextLayoutInfo.mParagraphsLayoutInfo.begin() );
-
- MergeParagraph( firstParagraphLayoutInfo,
- firstInputParagraphLayoutInfo );
-
- // 4) Update text info.
-
- // Updates the whole text size, maximum word size, etc.
- UpdateLayoutInfo( relayoutData.mTextLayoutInfo );
-}
-
-void UpdateTextInfo( std::size_t position,
- std::size_t numberOfCharacters,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData,
- const TextOperationOnRemove clearText )
-{
- // Removes 'numberOfCharacters' starting from 'position'.
-
- // * It checks if text to be deleted is in the same paragraph or not:
- // * If it is not, check which paragraphs need to be split/merged or deleted.
- // * If it is but all characters of the paragraph are going to be deleted, just delete the paragraph (nothing needs to be split/merged)
- // * If only some characters of the same paragraph are going to be deleted, proceed similarly: check if text to be deleted is in the same word.
- // * If it is not, split/merge words.
- // * Check if the whole word needs to be deleted.
- // * Check if only some characters of the word need to be deleted.
- // * Updates layout info.
-
- // * The algorithm checks if a word separator is deleted (in that case, different words need to be merged) and if a new paragraph separator is deleted (two paragraphs need to be merged).
-
- // Early return
-
- if( 0u == numberOfCharacters )
- {
- DALI_ASSERT_DEBUG( !"TextViewProcessor::UpdateTextInfo. WARNING: trying to delete 0 characters!" );
-
- // nothing to do if no characters are deleted.
- return;
- }
-
- // Asserts if trying to delete text out of bounds.
- DALI_ASSERT_ALWAYS( position + numberOfCharacters <= relayoutData.mTextLayoutInfo.mNumberOfCharacters && "TextViewProcessor::UpdateTextInfo. ERROR: trying to delete characters out of boundary" );
-
- // Remove characters from character to visual map and vs.
- // If there is right to left text, it needs to be updated every time the text is relaid-out.
- relayoutData.mCharacterLogicalToVisualMap.erase( relayoutData.mCharacterLogicalToVisualMap.end() - numberOfCharacters, relayoutData.mCharacterLogicalToVisualMap.end() );
- relayoutData.mCharacterVisualToLogicalMap.erase( relayoutData.mCharacterVisualToLogicalMap.end() - numberOfCharacters, relayoutData.mCharacterVisualToLogicalMap.end() );
-
- // Get paragraph, word and character indices for the given start position.
- TextInfoIndices textInfoIndicesBegin;
- GetIndicesFromGlobalCharacterIndex( position,
- relayoutData.mTextLayoutInfo,
- textInfoIndicesBegin );
-
- // Get paragraph, word and character indices for the given end position (start position + number of characters to be deleted).
- TextInfoIndices textInfoIndicesEnd;
- GetIndicesFromGlobalCharacterIndex( position + numberOfCharacters - 1u,
- relayoutData.mTextLayoutInfo,
- textInfoIndicesEnd );
-
- // Vectors used to temporary store text-actors removed from text.
- // Three vectors are needed because text-actors are not removed in order
- // but insert them in order is required to reuse them later.
- std::vector<TextActor> removedTextActorsFromBegin;
- std::vector<TextActor> removedTextActorsFromMid;
- std::vector<TextActor> removedTextActorsFromEnd;
-
- // Whether paragraphs and words need to be merged.
- bool mergeParagraphs = false;
- bool mergeWords = false;
-
- // Indices of the paragraphs and words to be merged.
- TextInfoIndices textInfoMergeIndicesBegin;
- TextInfoIndices textInfoMergeIndicesEnd;
-
- const ParagraphLayoutInfo& paragraphLayout( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndicesBegin.mParagraphIndex ) ); // used to check the number of characters of the paragraph
- // if all characters to be deleted are in the same paragraph.
- if( textInfoIndicesBegin.mParagraphIndex < textInfoIndicesEnd.mParagraphIndex )
- {
- // Deleted text is from different paragraphs. It may need to split two paragraphs, and merge first part of the first one with last part of the last one.
-
- // whether first or last paragraph need to be split and merged with the last part.
- bool mergeFirstParagraph = false;
- bool mergeLastParagraph = true;
-
- textInfoMergeIndicesBegin.mParagraphIndex = textInfoIndicesBegin.mParagraphIndex;
- textInfoMergeIndicesEnd.mParagraphIndex = textInfoIndicesEnd.mParagraphIndex;
-
- if( ( textInfoIndicesBegin.mWordIndex > 0u ) || ( textInfoIndicesBegin.mCharacterIndex > 0u ) )
- {
- // first character to be deleted is not the first one of the current paragraph.
- ++textInfoIndicesBegin.mParagraphIndex; // won't delete current paragraph
-
- // As some characters remain, this paragraph could be merged with the last one.
- mergeFirstParagraph = true;
- }
-
- // Check if all characters of the last paragraph are going to be deleted.
- bool wholeParagraphDeleted = false;
- const ParagraphLayoutInfo& lastParagraphLayout( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndicesEnd.mParagraphIndex ) );
- if( textInfoIndicesEnd.mWordIndex + 1u == lastParagraphLayout.mWordsLayoutInfo.size() )
- {
- const WordLayoutInfo& lastWordLayout( *( lastParagraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesEnd.mWordIndex ) );
- if( textInfoIndicesEnd.mCharacterIndex + 1u == lastWordLayout.mCharactersLayoutInfo.size() )
- {
- // All characters of the last paragraph are going to be deleted.
- ++textInfoIndicesEnd.mParagraphIndex; // will delete the last paragraph.
-
- // the whole last paragraph is deleted. Need to check if the next paragraph could be merged.
- mergeLastParagraph = false;
- wholeParagraphDeleted = true;
- }
- }
-
- if( wholeParagraphDeleted )
- {
- // It means the whole last paragraph is deleted completely.
- // It's needed to check if there is another paragraph after that could be merged.
- if( textInfoIndicesEnd.mParagraphIndex < relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.size() )
- {
- mergeLastParagraph = true;
-
- // Point the first characters of the next paragraph.
- textInfoIndicesEnd.mWordIndex = 0u;
- textInfoIndicesEnd.mCharacterIndex = 0u;
- textInfoMergeIndicesEnd.mParagraphIndex = textInfoIndicesEnd.mParagraphIndex;
- }
- }
-
- // If some characters remain in the first and last paragraph, they need to be merged.
- mergeParagraphs = mergeFirstParagraph && mergeLastParagraph;
-
- if( mergeParagraphs )
- {
- // last paragraph is going to be merged with the first one, so is not needed.
- ++textInfoIndicesEnd.mParagraphIndex; // will delete the last paragraph.
- }
-
- if( mergeFirstParagraph )
- {
- // Remove characters from the first paragraph.
-
- // Vectors used to temporary store text-actors removed from the paragraph.
- // Three vectors are needed because text-actors are not removed in order
- // but insert them in order is required to reuse them later.
- std::vector<TextActor> removedTextActorsFromFirstWord;
- std::vector<TextActor> removedTextActorsFromFirstParagraph;
-
- // As paragraphIndexBegin has been increased just to not to remove the paragraph, decrease now is needed to access it.
- ParagraphLayoutInfo& paragraphLayout( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndicesBegin.mParagraphIndex - 1u ) );
-
- // Remove the characters from the text and the styles.
- paragraphLayout.mText.Remove( textInfoIndicesBegin.mCharacterParagraphIndex, paragraphLayout.mNumberOfCharacters - textInfoIndicesBegin.mCharacterParagraphIndex );
-
- for( Vector<TextStyle*>::Iterator it = paragraphLayout.mTextStyles.Begin() + textInfoIndicesBegin.mCharacterParagraphIndex,
- endIt = paragraphLayout.mTextStyles.End();
- it != endIt;
- ++it )
- {
- delete *it;
- }
- paragraphLayout.mTextStyles.Erase( paragraphLayout.mTextStyles.Begin() + textInfoIndicesBegin.mCharacterParagraphIndex,
- paragraphLayout.mTextStyles.End() );
-
- if( ( textInfoIndicesBegin.mWordIndex + 1u < paragraphLayout.mWordsLayoutInfo.size() ) || ( 0u == textInfoIndicesBegin.mCharacterIndex ) )
- {
- // Remove extra words within current paragraph. (and current word if whole characters are removed)
- // 0 == characterIndexBegin means the whole word is deleted.
- const std::size_t wordIndex = ( ( 0u == textInfoIndicesBegin.mCharacterIndex ) ? textInfoIndicesBegin.mWordIndex : textInfoIndicesBegin.mWordIndex + 1u );
-
- // Store text-actors before removing them.
- CollectTextActorsFromWords( removedTextActorsFromFirstParagraph, paragraphLayout, wordIndex, paragraphLayout.mWordsLayoutInfo.size() );
-
- RemoveWordsFromParagraph( wordIndex,
- paragraphLayout.mWordsLayoutInfo.size() - wordIndex,
- layoutParameters.mLineHeightOffset,
- paragraphLayout );
- }
-
- if( ( textInfoIndicesBegin.mWordIndex < paragraphLayout.mWordsLayoutInfo.size() ) && ( textInfoIndicesBegin.mCharacterIndex > 0u ) )
- {
- // Only some characters of the word need to be removed.
- WordLayoutInfo& wordLayout( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesBegin.mWordIndex ) );
-
- // Store text-actors before removing them.
- CollectTextActors( removedTextActorsFromFirstWord, wordLayout, textInfoIndicesBegin.mCharacterIndex, wordLayout.mCharactersLayoutInfo.size() );
-
- const std::size_t wordNumberCharacters = wordLayout.mCharactersLayoutInfo.size();
- RemoveCharactersFromWord( textInfoIndicesBegin.mCharacterIndex,
- wordLayout.mCharactersLayoutInfo.size() - textInfoIndicesBegin.mCharacterIndex,
- wordLayout );
-
- // discount the removed number of characters.
- const std::size_t removedNumberOfCharacters = ( wordNumberCharacters - wordLayout.mCharactersLayoutInfo.size() );
- paragraphLayout.mNumberOfCharacters -= removedNumberOfCharacters;
- }
- UpdateLayoutInfo( paragraphLayout, layoutParameters.mLineHeightOffset );
-
- // Insert the text-actors in order.
- removedTextActorsFromBegin.insert( removedTextActorsFromBegin.end(), removedTextActorsFromFirstWord.begin(), removedTextActorsFromFirstWord.end() );
- removedTextActorsFromBegin.insert( removedTextActorsFromBegin.end(), removedTextActorsFromFirstParagraph.begin(), removedTextActorsFromFirstParagraph.end() );
- }
-
- if( mergeLastParagraph && !wholeParagraphDeleted )
- {
- // Some characters from the last paragraph need to be removed.
-
- // Vectors used to temporary store text-actors removed from the paragraph.
- // Three vectors are needed because text-actors are not removed in order
- // but insert them in order is required to reuse them later.
- std::vector<TextActor> removedTextActorsFromFirstWord;
- std::vector<TextActor> removedTextActorsFromFirstParagraph;
-
- // paragraphIndexEnd was increased to delete the last paragraph if paragraphs need to be merged.
- // To access now the last paragraph we need to decrease the index.
- const std::size_t paragraphIndex = ( mergeParagraphs ? textInfoIndicesEnd.mParagraphIndex - 1u : textInfoIndicesEnd.mParagraphIndex );
-
- // Get the last paragraph.
- ParagraphLayoutInfo& paragraphLayout( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + paragraphIndex ) );
-
- // Remove the characters from the text and the styles.
- const std::size_t lastCharacterIndex = textInfoIndicesEnd.mCharacterParagraphIndex + 1u;
-
- paragraphLayout.mText.Remove( 0u, lastCharacterIndex );
-
- for( Vector<TextStyle*>::Iterator it = paragraphLayout.mTextStyles.Begin(),
- endIt = paragraphLayout.mTextStyles.Begin() + lastCharacterIndex;
- it != endIt;
- ++it )
- {
- delete *it;
- }
- paragraphLayout.mTextStyles.Erase( paragraphLayout.mTextStyles.Begin(),
- paragraphLayout.mTextStyles.Begin() + lastCharacterIndex );
-
- // Check if is needed remove the whole word. (If the character index is pointing just after the end of the word)
- const WordLayoutInfo& wordLayout( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesEnd.mWordIndex ) );
- bool removeWholeWord = wordLayout.mCharactersLayoutInfo.size() == textInfoIndicesEnd.mCharacterIndex + 1u;
-
- if( ( textInfoIndicesEnd.mWordIndex > 0u ) || ( removeWholeWord ) )
- {
- // Store text-actors before removing them.
- CollectTextActorsFromWords( removedTextActorsFromFirstParagraph,
- paragraphLayout,
- 0u,
- ( removeWholeWord ) ? textInfoIndicesEnd.mWordIndex + 1u : textInfoIndicesEnd.mWordIndex );
-
- // Remove extra words. (and current word if whole characters are removed)
- RemoveWordsFromParagraph( 0u,
- ( removeWholeWord ) ? textInfoIndicesEnd.mWordIndex + 1u : textInfoIndicesEnd.mWordIndex,
- layoutParameters.mLineHeightOffset,
- paragraphLayout );
- }
-
- if( !removeWholeWord )
- {
- // Only some characters of the word need to be deleted.
-
- // After removing all extra words. The word with the characters to be removed is the first one.
- WordLayoutInfo& wordLayout( *paragraphLayout.mWordsLayoutInfo.begin() );
-
- // Store text-actors before removing them.
- CollectTextActors( removedTextActorsFromFirstWord, wordLayout, 0u, textInfoIndicesEnd.mCharacterIndex + 1u );
-
- const std::size_t wordNumberCharacters = wordLayout.mCharactersLayoutInfo.size();
- RemoveCharactersFromWord( 0u,
- textInfoIndicesEnd.mCharacterIndex + 1u,
- wordLayout );
-
- // discount the removed number of characters.
- const std::size_t removedNumberOfCharacters = ( wordNumberCharacters - wordLayout.mCharactersLayoutInfo.size() );
- paragraphLayout.mNumberOfCharacters -= removedNumberOfCharacters;
- }
- UpdateLayoutInfo( paragraphLayout, layoutParameters.mLineHeightOffset );
-
- // Insert the text-actors in order.
- removedTextActorsFromEnd.insert( removedTextActorsFromEnd.end(), removedTextActorsFromFirstWord.begin(), removedTextActorsFromFirstWord.end() );
- removedTextActorsFromEnd.insert( removedTextActorsFromEnd.end(), removedTextActorsFromFirstParagraph.begin(), removedTextActorsFromFirstParagraph.end() );
- }
- } // end delete text from different paragraphs
- else if( ( textInfoIndicesBegin.mParagraphIndex == textInfoIndicesEnd.mParagraphIndex ) && ( paragraphLayout.mNumberOfCharacters == numberOfCharacters ) )
- {
- // the whole paragraph needs to be deleted.
- ++textInfoIndicesEnd.mParagraphIndex; // will delete current paragraph.
- }
- else
- {
- // deleted text is within the same paragraph. (merge paragraphs could be needed if the paragraph separator character is deleted)
-
- // Paragraph which contains the characters to be deleted.
- ParagraphLayoutInfo& paragraphLayout( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndicesBegin.mParagraphIndex ) );
-
- // Remove the characters from the text and the styles.
- const std::size_t firstCharacterIndex = textInfoIndicesBegin.mCharacterParagraphIndex;
- const std::size_t lastCharacterIndex = textInfoIndicesEnd.mCharacterParagraphIndex + 1u;
-
- paragraphLayout.mText.Remove( firstCharacterIndex, lastCharacterIndex - firstCharacterIndex );
-
- for( Vector<TextStyle*>::Iterator it = paragraphLayout.mTextStyles.Begin() + firstCharacterIndex,
- endIt = paragraphLayout.mTextStyles.Begin() + lastCharacterIndex;
- it != endIt;
- ++it )
- {
- delete *it;
- }
- paragraphLayout.mTextStyles.Erase( paragraphLayout.mTextStyles.Begin() + firstCharacterIndex,
- paragraphLayout.mTextStyles.Begin() + lastCharacterIndex );
-
- // Remove the characters from the paragraph layout info. It returns whether the current paragraph can be merged with the next one.
- RemoveCharactersFromParagraphInfo( relayoutData,
- numberOfCharacters,
- mergeWords,
- mergeParagraphs,
- textInfoIndicesBegin,
- textInfoIndicesEnd,
- textInfoMergeIndicesBegin,
- textInfoMergeIndicesEnd,
- paragraphLayout,
- removedTextActorsFromBegin,
- removedTextActorsFromEnd );
-
- if( mergeWords )
- {
- // Merges words pointed by textInfoMergeIndicesBegin.mWordIndex and textInfoMergeIndicesEnd.mWordIndex calculated previously.
- DALI_ASSERT_DEBUG( ( textInfoMergeIndicesBegin.mWordIndex < paragraphLayout.mWordsLayoutInfo.size() ) && "TextViewProcessor::UpdateTextInfo (delete). Word index (begin) out of bounds." );
- DALI_ASSERT_DEBUG( ( textInfoMergeIndicesEnd.mWordIndex < paragraphLayout.mWordsLayoutInfo.size() ) && "TextViewProcessor::UpdateTextInfo (delete). Word index (end) out of bounds." );
-
- WordLayoutInfo& firstWordLayout( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoMergeIndicesBegin.mWordIndex ) );
- WordLayoutInfo& lastWordLayout( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoMergeIndicesEnd.mWordIndex ) );
-
- MergeWord( firstWordLayout,
- lastWordLayout );
- }
-
- // Store text-actors before removing them.
- const std::size_t endIndex = ( mergeWords && ( textInfoIndicesEnd.mWordIndex > 0u ) ) ? textInfoIndicesEnd.mWordIndex - 1u : textInfoIndicesEnd.mWordIndex; // text-actors from the last word may have been added in the merge above.
- CollectTextActorsFromWords( removedTextActorsFromMid, paragraphLayout, textInfoIndicesBegin.mWordIndex, endIndex );
-
- // Remove unwanted words using previously calculated indices. (including the last part of the merged word)
- paragraphLayout.mWordsLayoutInfo.erase( paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesBegin.mWordIndex, paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesEnd.mWordIndex );
-
- // Update paragraph info.
- UpdateLayoutInfo( paragraphLayout, layoutParameters.mLineHeightOffset );
- }// end delete text from same paragraph.
-
- if( mergeParagraphs )
- {
- // Merges paragraphs pointed by textInfoMergeIndicesBegin.mParagraphIndex and textInfoMergeIndicesEnd.mParagraphIndex calculated previously.
-
- ParagraphLayoutInfo& firstParagraphLayout( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoMergeIndicesBegin.mParagraphIndex ) );
-
- const ParagraphLayoutInfo& lastParagraphLayout( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoMergeIndicesEnd.mParagraphIndex ) );
-
- MergeParagraph( firstParagraphLayout,
- lastParagraphLayout );
- }
-
- // Store text-actors before removing them.
- const std::size_t endIndex = ( mergeParagraphs && ( textInfoIndicesEnd.mParagraphIndex > 0u ) ) ? textInfoIndicesEnd.mParagraphIndex - 1u : textInfoIndicesEnd.mParagraphIndex; // text-actors from the last paragraph may have been added in the merge above.
- CollectTextActorsFromParagraphs( removedTextActorsFromMid,
- relayoutData.mTextLayoutInfo,
- textInfoIndicesBegin.mParagraphIndex,
- endIndex );
-
- // Remove unwanted paragraphs using previously calculated indices. (including the last part of the merged paragraph)
- relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.erase( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndicesBegin.mParagraphIndex,
- relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndicesEnd.mParagraphIndex );
-
- // Update text info.
- UpdateLayoutInfo( relayoutData.mTextLayoutInfo );
-
- // If the last character of the last paragraph is a new paragraph character, an empty paragraph need to be added.
- if( !relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
- {
- const WordLayoutInfo lastWordLayout = GetLastWordLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u ) );
-
- if( ParagraphSeparator == lastWordLayout.mType )
- {
- ParagraphLayoutInfo lastParagraphLayout;
-
- const CharacterLayoutInfo layoutInfo = GetLastCharacterLayoutInfo( lastWordLayout );
- lastParagraphLayout.mSize.height = layoutInfo.mSize.height;
-
- relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.push_back( lastParagraphLayout );
-
- relayoutData.mTextLayoutInfo.mWholeTextSize.height += layoutInfo.mSize.height;
- }
- }
-
- // Clear the text from the text-actors if required.
- if( CLEAR_TEXT == clearText )
- {
- ClearText( removedTextActorsFromEnd );
- ClearText( removedTextActorsFromMid );
- ClearText( removedTextActorsFromBegin );
- }
-
- // Insert text-actors into the cache.
- // Text-actors are inserted in reverse order to use first the first removed.
- relayoutData.mTextActorCache.InsertTextActors( removedTextActorsFromEnd );
- relayoutData.mTextActorCache.InsertTextActors( removedTextActorsFromMid );
- relayoutData.mTextActorCache.InsertTextActors( removedTextActorsFromBegin );
-}
-
-void UpdateTextInfo( std::size_t position,
- std::size_t numberOfCharacters,
- const MarkupProcessor::StyledTextArray& text,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData )
-{
- // Replaces 'numberOfCharacters' of text starting from 'position' with the given text.
-
- // TODO: Temporary implementation with remove and insert.
-
- // Remove.
- UpdateTextInfo( position,
- numberOfCharacters,
- layoutParameters,
- relayoutData,
- KEEP_TEXT ); // Do not clear the text from the text-actors.
-
- // Insert.
- UpdateTextInfo( position,
- text,
- layoutParameters,
- relayoutData );
-}
-
-void UpdateTextInfo( float lineHeightOffset,
- TextLayoutInfo& textLayoutInfo )
-{
- // Updates the space between lines with the new offset value.
-
- float newTextHeight = 0.f;
-
- for( ParagraphLayoutInfoContainer::iterator paragraphIt = textLayoutInfo.mParagraphsLayoutInfo.begin(), paragraphEndIt = textLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphIt != paragraphEndIt;
- ++paragraphIt )
- {
- ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphIt );
-
- paragraphLayoutInfo.mSize.height += ( lineHeightOffset - paragraphLayoutInfo.mLineHeightOffset );
- newTextHeight += paragraphLayoutInfo.mSize.height;
-
- paragraphLayoutInfo.mLineHeightOffset = lineHeightOffset;
- }
-
- textLayoutInfo.mWholeTextSize.height = newTextHeight;
-}
-
-void UpdateTextInfo( const TextStyle& style,
- const TextStyle::Mask mask,
- TextView::RelayoutData& relayoutData )
-{
- // Change text style for all text-actors.
-
- for( ParagraphLayoutInfoContainer::iterator paragraphIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(), paragraphEndIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
- paragraphIt != paragraphEndIt;
- ++paragraphIt )
- {
- ParagraphLayoutInfo& paragraph( *paragraphIt );
-
- std::size_t index = 0u;
- for( Vector<TextStyle*>::Iterator it = paragraph.mTextStyles.Begin(), endIt = paragraph.mTextStyles.End(); it != endIt; ++it )
- {
- (*it)->Copy( style, mask );
-
- // Checks if the font family supports all glyphs. If not, chooses a most suitable one.
- ChooseFontFamilyName( paragraph.mText[index], *(*it) );
-
- ++index;
- }
-
- for( WordLayoutInfoContainer::iterator wordIt = paragraph.mWordsLayoutInfo.begin(), wordEndIt = paragraph.mWordsLayoutInfo.end();
- wordIt != wordEndIt;
- ++wordIt )
- {
- WordLayoutInfo& word( *wordIt );
-
- for( CharacterLayoutInfoContainer::iterator characterIt = word.mCharactersLayoutInfo.begin(), characterEndIt = word.mCharactersLayoutInfo.end();
- characterIt != characterEndIt;
- ++characterIt )
- {
- CharacterLayoutInfo& characterLayout( *characterIt );
-
- // Mark the character to be set the new style into the text-actor.
- characterLayout.mSetStyle = true;
- } // end characters
- } // end words
- } // end paragraphs
-}
-
-} // namespace TextViewProcessor
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewProcessor
-{
-
-/**
- * Creates a data structure with info to layout the text, and data structures with useful info to modify the layout data structure if characters are added or removed.
- *
- * @param[in] text The given styled text.
- * @param[in] layoutParameters Layout configuration.
- * @param[out] relayoutData Natural size (metrics), layout, text-actor info and conversion from visual to logical order and vice versa (for RTL text).
- */
-void CreateTextInfo( const MarkupProcessor::StyledTextArray& text,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Updates the layout data structures with the new inserted text.
- *
- * @note Does nothing if text has no characters.
- * @note It asserts if position is bigger than the number of characters of the whole text.
- *
- * @param[in] position Where the text is going to be inserted.
- * @param[in] text New styled text to be inserted.
- * @param[in] layoutParameters Layout configuration.
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info and conversion from visual to logical order and vice versa (for RTL text).
- */
-void UpdateTextInfo( std::size_t position,
- const MarkupProcessor::StyledTextArray& text,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Updates the layout data structures by removing text.
- *
- * @note Does nothing if number of characters to be deleted is zero.
- * @note It asserts if trying to delete text out of bounds.
- *
- * @param[in] position Position of the first character to be removed.
- * @param[in] numberOfCharacters The number of characters to be removed.
- * @param[in] layoutParameters Layout configuration.
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info and conversion from visual to logical order and vice versa (for RTL text).
- * @param[in] clearText Whether to clear text-actor's text before insert the text-actors into the cache.
- */
-void UpdateTextInfo( std::size_t position,
- std::size_t numberOfCharacters,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData,
- TextOperationOnRemove clearText );
-
-/**
- * Updates the layout data structures by replacing text.
- *
- * @param[in] position Position of the first character to be replaced.
- * @param[in] numberOfCharacters The number of characters to be replaced.
- * @param[in] text The new styled text.
- * @param[in] layoutParameters Layout configuration.
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info and conversion from visual to logical order and vice versa (for RTL text).
- */
-void UpdateTextInfo( std::size_t position,
- std::size_t numberOfCharacters,
- const MarkupProcessor::StyledTextArray& text,
- const TextView::LayoutParameters& layoutParameters,
- TextView::RelayoutData& relayoutData );
-
-/**
- * Updates the layout data structure by modifying the space between lines.
- *
- * @param[in] lineHeightOffset The new space between lines.
- * @param[in,out] textLayoutInfo Layout info for all characters, words, lines and the whole text.
- */
-void UpdateTextInfo( float lineHeightOffset,
- TextLayoutInfo& textLayoutInfo );
-
-/**
- * Updates the text-actor data structures by replacing the style.
- *
- * @note This operation is called only if the new style doesn't modify the metrics. Consequently it doesn't modify any size info.
- *
- * @param[in] style The new style.
- * @param[in] mask The style mask.
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info.
- */
-void UpdateTextInfo( const TextStyle& style,
- TextStyle::Mask mask,
- TextView::RelayoutData& relayoutData );
-
-} // namespace TextViewProcessor
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_PROCESSOR_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-helper-functions.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-dbg.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewProcessor
-{
-
-namespace
-{
-
-const std::string EMOJI_FONT_NAME( "SamsungEmoji" ); // Emoticons font family name.
-
-} // namespace
-
-/////////////////////
-// Layout info.
-/////////////////////
-
-WordLayoutInfo::WordLayoutInfo()
-: mSize(),
- mAscender( 0.f ),
- mType( NoSeparator ),
- mFirstCharacter( 0u ),
- mCharactersLayoutInfo()
-{
-}
-
-WordLayoutInfo::~WordLayoutInfo()
-{
-}
-
-WordLayoutInfo::WordLayoutInfo( const WordLayoutInfo& word )
-: mSize( word.mSize ),
- mAscender( word.mAscender ),
- mType( word.mType ),
- mFirstCharacter( word.mFirstCharacter ),
- mCharactersLayoutInfo( word.mCharactersLayoutInfo )
-{
-}
-
-WordLayoutInfo& WordLayoutInfo::operator=( const WordLayoutInfo& word )
-{
- mSize = word.mSize;
- mAscender = word.mAscender;
- mType = word.mType;
- mFirstCharacter = word.mFirstCharacter;
- mCharactersLayoutInfo = word.mCharactersLayoutInfo;
-
- return *this;
-}
-
-void CreateWordTextInfo( const Text& paragraph,
- Vector<TextStyle*>& textStyles,
- WordLayoutInfo& wordLayoutInfo )
-{
- DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "-->TextViewProcessor::CreateWordTextInfo\n" );
- // Split in characters.
- std::size_t characterIndex = wordLayoutInfo.mFirstCharacter;
- for( CharacterLayoutInfoContainer::iterator it = wordLayoutInfo.mCharactersLayoutInfo.begin(),
- endIt = wordLayoutInfo.mCharactersLayoutInfo.end();
- it != endIt;
- ++it, ++characterIndex )
- {
- // Gets a reference of the character's layout info.
- CharacterLayoutInfo& characterLayoutInfo( *it );
-
- // Gets the character and the style for that character from the paragraph.
- Character character = paragraph[characterIndex];
- TextStyle* textStyle = *( textStyles.Begin() + characterIndex );
-
- // Checks whether the character is an emoticon.
- characterLayoutInfo.mIsColorGlyph = GlyphImage::IsColorGlyph( character );
- DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, " Is color glyph: %s\n", ( characterLayoutInfo.mIsColorGlyph ? "True" : "False" ) );
-
- if( characterLayoutInfo.mIsColorGlyph )
- {
- // If the character is an emoticon a predefined font is set.
- textStyle->SetFontName( EMOJI_FONT_NAME );
- }
- else
- {
- // Checks if the font family and the font style set in the text style supports the character.
- // If not, it chooses the right font for the given character and style.
- ChooseFontFamilyName( character, *textStyle );
- }
-
- // Gets the metrics of the font.
- const Font font = Font::New( FontParameters( textStyle->GetFontName(), textStyle->GetFontStyle(), textStyle->GetFontPointSize() ) );
- const Font::Metrics metrics = font.GetMetrics( character );
- const float ascender = font.GetAscender();
-
- // Fill Natural size info for current character.
-
- // The font line's height is used as character's height.
- characterLayoutInfo.mSize.height = font.GetLineHeight();
-
- // The character's advance is used as charcter's width.
- characterLayoutInfo.mSize.width = metrics.GetAdvance();
-
- // The ascender and bearing are used to position correctly glyphs of different font sizes.
- characterLayoutInfo.mAscender = ascender;
- characterLayoutInfo.mBearing = metrics.GetBearing();
-
- if( character.IsNewLine() && !characterLayoutInfo.mIsColorGlyph )
- {
- // A new paragraph character '\n' doesn't have any width.
- characterLayoutInfo.mSize.width = 0.f;
- }
-
- // Set's the underline thickness and position.
- // Both thickness and position includes the vertical pad adjust used in effects like glow or shadow.
- if( textStyle->IsUnderlineEnabled() )
- {
- characterLayoutInfo.mUnderlineThickness = font.GetUnderlineThickness();
- characterLayoutInfo.mUnderlinePosition = font.GetUnderlinePosition();
- }
-
- // Updates the word size and ascender.
- UpdateSize( wordLayoutInfo.mSize, characterLayoutInfo.mSize );
- wordLayoutInfo.mAscender = std::max( wordLayoutInfo.mAscender, characterLayoutInfo.mAscender );
- } // end of characters in the word.
- DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "<--TextViewProcessor::CreateWordTextInfo\n" );
-}
-
-void UpdateLayoutInfo( WordLayoutInfo& wordLayout )
-{
- // Initialize layout info for the whole word.
- wordLayout.mSize = Size::ZERO;
- wordLayout.mAscender = 0.f;
-
- // Traverse the character layout info to update the word layout.
- for( CharacterLayoutInfoContainer::iterator layoutIt = wordLayout.mCharactersLayoutInfo.begin(), layoutEndIt = wordLayout.mCharactersLayoutInfo.end();
- layoutIt != layoutEndIt;
- ++layoutIt )
- {
- // Layout info for the current character.
- CharacterLayoutInfo& layoutInfo( *layoutIt );
-
- // Update layout info for the current word.
- UpdateSize( wordLayout.mSize, layoutInfo.mSize );
- wordLayout.mAscender = std::max( wordLayout.mAscender, layoutInfo.mAscender );
- }
-}
-
-void RemoveCharactersFromWordInfo( TextView::RelayoutData& relayoutData,
- const std::size_t numberOfCharacters,
- bool& mergeWords,
- bool& mergeParagraphs,
- TextInfoIndices& textInfoIndicesBegin,
- TextInfoIndices& textInfoIndicesEnd,
- TextInfoIndices& textInfoMergeIndicesBegin,
- TextInfoIndices& textInfoMergeIndicesEnd,
- ParagraphLayoutInfo& paragraphLayout,
- std::vector<TextActor>& removedTextActors )
-{
- const TextLayoutInfo& textLayoutInfo = relayoutData.mTextLayoutInfo;
-
- // Get the word.
- WordLayoutInfo& wordLayout( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesBegin.mWordIndex ) );
-
- if( ParagraphSeparator == wordLayout.mType )
- {
- // If the word is a paragraph separator and there is more paragraphs, then current paragraph and the paragraph after need to be merged.
- if( textInfoIndicesBegin.mParagraphIndex + 1u < textLayoutInfo.mParagraphsLayoutInfo.size() )
- {
- // current paragraph is not the last one.
-
- // Update indices to merge paragraphs.
- textInfoMergeIndicesBegin.mParagraphIndex = textInfoIndicesBegin.mParagraphIndex;
- textInfoMergeIndicesEnd.mParagraphIndex = textInfoIndicesBegin.mParagraphIndex + 1u;
-
- mergeParagraphs = true;
-
- ++textInfoIndicesBegin.mParagraphIndex; // increase both indices,
- textInfoIndicesEnd.mParagraphIndex += 2u; // will delete last paragraph.
- }
-
- ++textInfoIndicesEnd.mWordIndex; //will delete the paragraph separator;
- }
- else if( WordSeparator == wordLayout.mType )
- {
- // If the word is a word separator. Check if the word before and the word after can be merged.
-
- if( ( 0u < textInfoIndicesBegin.mWordIndex ) && ( paragraphLayout.mWordsLayoutInfo.size() > textInfoIndicesBegin.mWordIndex + 1u ) )
- {
- const WordLayoutInfo& wordLayoutBefore( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesBegin.mWordIndex - 1u ) );
- const WordLayoutInfo& wordLayoutAfter( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesBegin.mWordIndex + 1u ) );
-
- if( ( NoSeparator == wordLayoutBefore.mType ) && ( NoSeparator == wordLayoutAfter.mType ) )
- {
- // This word is a word separator (white space) and is not the first word of the paragraph nor the last one.
- mergeWords = true;
-
- // Set indices to merge the words.
- textInfoMergeIndicesBegin.mWordIndex = textInfoIndicesBegin.mWordIndex - 1u; // word before word separator.
- textInfoMergeIndicesEnd.mWordIndex = textInfoIndicesBegin.mWordIndex + 1u; // word after word separator.
-
- textInfoIndicesEnd.mWordIndex += 2u; // will delete the word separator and the merged word.
- }
- else
- {
- ++textInfoIndicesEnd.mWordIndex; // will delete the word separator;
- }
- }
- else
- {
- ++textInfoIndicesEnd.mWordIndex; // will delete the word separator;
- }
- }
- else if( numberOfCharacters == wordLayout.mCharactersLayoutInfo.size() )
- {
- // The whole word needs to be removed.
- ++textInfoIndicesEnd.mWordIndex; // will delete the current word.
- }
- else
- {
- // Store text-actors before removing them.
- CollectTextActors( removedTextActors, wordLayout, textInfoIndicesBegin.mCharacterIndex, textInfoIndicesBegin.mCharacterIndex + numberOfCharacters );
-
- // just remove some characters from current word.
- RemoveCharactersFromWord( textInfoIndicesBegin.mCharacterIndex,
- numberOfCharacters,
- wordLayout );
- }
-}
-
-void RemoveCharactersFromWord( const std::size_t position,
- const std::size_t numberOfCharacters,
- WordLayoutInfo& wordLayout )
-{
- // Removes a given number of characters from the given word starting from the 'position' index.
-
- // Early return.
- if( 0u == numberOfCharacters )
- {
- // nothing to do if the number of characters is zero.
-
- return;
- }
-
- // Remove characters from layout and text-actor info.
- wordLayout.mCharactersLayoutInfo.erase( wordLayout.mCharactersLayoutInfo.begin() + position, wordLayout.mCharactersLayoutInfo.begin() + position + numberOfCharacters );
-
- // Some characters have been removed from the word. Update the layout info is needed.
- UpdateLayoutInfo( wordLayout );
-}
-
-void SplitWord( const std::size_t position,
- WordLayoutInfo& firstWordLayoutInfo,
- WordLayoutInfo& lastWordLayoutInfo )
-{
- // Splits a word in two.
- // It moves characters from the first part of the word to the last one.
-
- // early returns
- if( 0u == position )
- {
- // the whole word goes to the last part of the word.
- lastWordLayoutInfo = firstWordLayoutInfo;
-
- firstWordLayoutInfo = WordLayoutInfo();
-
- return;
- }
-
- if( position == firstWordLayoutInfo.mCharactersLayoutInfo.size() )
- {
- // the whole word goes to the first part of the word.
-
- // Just delete whatever there is in the last part of the word.
- lastWordLayoutInfo = WordLayoutInfo();
-
- return;
- }
-
- // Initialize output data structures.
-
- // Layout info
- lastWordLayoutInfo = WordLayoutInfo();
-
- // Split layout info.
-
- // Insert characters from the given index 'position' to the end.
- lastWordLayoutInfo.mCharactersLayoutInfo.insert( lastWordLayoutInfo.mCharactersLayoutInfo.end(),
- firstWordLayoutInfo.mCharactersLayoutInfo.begin() + position, firstWordLayoutInfo.mCharactersLayoutInfo.end() );
-
- // Delete characters from the first part of the word.
- firstWordLayoutInfo.mCharactersLayoutInfo.erase( firstWordLayoutInfo.mCharactersLayoutInfo.begin() + position, firstWordLayoutInfo.mCharactersLayoutInfo.end() );
-
- // Update the layout info of both new words.
- UpdateLayoutInfo( firstWordLayoutInfo );
- UpdateLayoutInfo( lastWordLayoutInfo );
-}
-
-void MergeWord( WordLayoutInfo& firstWordLayoutInfo,
- const WordLayoutInfo& lastWordLayoutInfo )
-{
- // Merges two given words.
-
- // Early returns.
- if( lastWordLayoutInfo.mCharactersLayoutInfo.empty() )
- {
- // nothing to do
- return;
- }
-
- if( firstWordLayoutInfo.mCharactersLayoutInfo.empty() )
- {
- // copy last to first
-
- firstWordLayoutInfo = lastWordLayoutInfo;
-
- return;
- }
-
- if( ( NoSeparator != firstWordLayoutInfo.mType ) || ( NoSeparator != lastWordLayoutInfo.mType ) )
- {
- // Do not merge white spaces or new paragraph characters.
- DALI_ASSERT_ALWAYS( !"TextViewProcessor::MergeWord(). ERROR: White spaces or new paragraph characters can't be merged with other words." );
- }
-
- // Merge layout info
- firstWordLayoutInfo.mCharactersLayoutInfo.insert( firstWordLayoutInfo.mCharactersLayoutInfo.end(),
- lastWordLayoutInfo.mCharactersLayoutInfo.begin(),
- lastWordLayoutInfo.mCharactersLayoutInfo.end() );
-
- // Update the word layout info.
- UpdateSize( firstWordLayoutInfo.mSize, lastWordLayoutInfo.mSize );
- firstWordLayoutInfo.mAscender = std::max( firstWordLayoutInfo.mAscender, lastWordLayoutInfo.mAscender );
-}
-
-CharacterLayoutInfo GetFirstCharacterLayoutInfo( const WordLayoutInfo& wordLayoutInfo )
-{
- CharacterLayoutInfo layoutInfo;
-
- if( !wordLayoutInfo.mCharactersLayoutInfo.empty() )
- {
- layoutInfo = *wordLayoutInfo.mCharactersLayoutInfo.begin();
- }
-
- return layoutInfo;
-}
-
-CharacterLayoutInfo GetLastCharacterLayoutInfo( const WordLayoutInfo& wordLayoutInfo )
-{
- CharacterLayoutInfo layoutInfo;
-
- if( !wordLayoutInfo.mCharactersLayoutInfo.empty() )
- {
- layoutInfo = *( wordLayoutInfo.mCharactersLayoutInfo.end() - 1u );
- }
-
- return layoutInfo;
-}
-
-void CollectTextActors( std::vector<TextActor>& textActors, const WordLayoutInfo& word, const std::size_t characterIndexBegin, const std::size_t characterIndexEnd )
-{
- for( CharacterLayoutInfoContainer::const_iterator characterIt = word.mCharactersLayoutInfo.begin() + characterIndexBegin,
- characterEndIt = word.mCharactersLayoutInfo.begin() + characterIndexEnd;
- characterIt != characterEndIt;
- ++characterIt )
- {
- const CharacterLayoutInfo& characterLayout( *characterIt );
-
- if( !characterLayout.mIsColorGlyph )
- {
- TextActor textActor = TextActor::DownCast( characterLayout.mGlyphActor );
- if( textActor )
- {
- textActors.push_back( textActor );
- }
- }
- }
-}
-
-void CollectTextActorsFromWords( std::vector<TextActor>& textActors, const ParagraphLayoutInfo& paragraph, const std::size_t wordIndexBegin, const std::size_t wordIndexEnd )
-{
- for( WordLayoutInfoContainer::const_iterator wordIt = paragraph.mWordsLayoutInfo.begin() + wordIndexBegin, wordEndIt = paragraph.mWordsLayoutInfo.begin() + wordIndexEnd;
- wordIt != wordEndIt;
- ++wordIt )
- {
- const WordLayoutInfo& word( *wordIt );
-
- for( CharacterLayoutInfoContainer::const_iterator characterIt = word.mCharactersLayoutInfo.begin(), characterEndIt = word.mCharactersLayoutInfo.end();
- characterIt != characterEndIt;
- ++characterIt )
- {
- const CharacterLayoutInfo& characterLayout( *characterIt );
-
- if( !characterLayout.mIsColorGlyph )
- {
- TextActor textActor = TextActor::DownCast( characterLayout.mGlyphActor );
- if( textActor )
- {
- textActors.push_back( textActor );
- }
- }
- }
- }
-}
-
-} //namespace TextViewProcessor
-
-} //namespace Internal
-
-} //namespace Toolkit
-
-} //namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_WORD_PROCESSOR_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_WORD_PROCESSOR_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace TextViewProcessor
-{
-
-/**
- * Creates a data structure with info to layout the word, and data structures with useful info to modify the layout data structure if characters are added or removed.
- *
- * @param[in] paragraphText The paragraph's text.
- * @param[in] textStyles The styles for each character of the paragraph.
- * @param[out] wordLayoutInfo Layout info for all characters of the word.
- */
-void CreateWordTextInfo( const Text& paragraphText,
- Vector<TextStyle*>& textStyles,
- WordLayoutInfo& wordLayoutInfo );
-
-/**
- * Updates the word size and ascender.
- *
- * It's called after deleting some characters, split a word in two,
- * or when a new word is created when right to left text is reordered.
- *
- * @param[in] wordLayout The word layout info.
- */
-void UpdateLayoutInfo( WordLayoutInfo& wordLayout );
-
-/**
- * Removes a given number of characters from the given word.
- *
- * It calls the RemoveCharactersFromWord() function to remove characters from the word.
- *
- * If the word is a white space \e mergeWords will return \e true and \e textInfoMergeIndicesBegin and \e textInfoMergeIndicesEnd will be set to merge the two adjacent words.
- * If the word is a new paragraph character \e mergeParagraphs will return \e true and \e textInfoMergeIndicesBegin and \e textInfoMergeIndicesEnd will be set to merge the two paragraphs.
- *
- * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info.
- * @param[in] numberOfCharacters The number of characters to be deleted.
- * @param[out] mergeWords Whether adjacent words need to be merged.
- * @param[out] mergeParagraphs Whether current paragraph need to be merged with the next one.
- * @param[in,out] textInfoIndicesBegin Indices to the paragraph, word and characters from where to delete characters. It returns from where words need to be removed.
- * @param[out] textInfoIndicesEnd If paragraphs or words need to be merged it returns info to delete them (If a word is merged, it has to be removed. Equal for paragraphs).
- * @param[out] textInfoMergeIndicesBegin The indices to the first part of the paragraph and word to be merged.
- * @param[out] textInfoMergeIndicesEnd The indices to the last part of the paragraph and word to be merged.
- * @param[in,out] paragraphLayout Layout info of the paragraph where the word is located.
- * @param[out] removedTextActors Stores handles of temoved text-actors.
- */
-void RemoveCharactersFromWordInfo( TextView::RelayoutData& relayoutData,
- std::size_t numberOfCharacters,
- bool& mergeWords,
- bool& mergeParagraphs,
- TextInfoIndices& textInfoIndicesBegin,
- TextInfoIndices& textInfoIndicesEnd,
- TextInfoIndices& textInfoMergeIndicesBegin,
- TextInfoIndices& textInfoMergeIndicesEnd,
- ParagraphLayoutInfo& paragraphLayout,
- std::vector<TextActor>& removedTextActors );
-/**
- * Removes a given number of characters from the given word.
- *
- * @pre \e positon and \e position + \e numberOfCharacters can't exceed the bounds of the word.
- *
- * @param[in] position Character index within the word with the starting position to be deleted.
- * @param[in] numberOfCharacters The number of characters to be deleted.
- * @param[in,out] wordLayout The input is the layout info of the word. The output is the layout info of the word without the removed characters.
- */
-void RemoveCharactersFromWord( std::size_t position,
- std::size_t numberOfCharacters,
- WordLayoutInfo& wordLayout );
-
-/**
- * Splits a word in two.
- *
- * Removes part of the text from the input word and creates a new word with the removed text.
- *
- * i.e. The result of split 'word' by the position 3 would be 'wor' and 'd'.
- *
- * @note It deletes whatever there is in the last part of the word.
- *
- * @param[in] position Character index where to split the word.
- * @param[in,out] firstWordLayoutInfo The input is the layout info of the given word. The output is the first part of the input word (from the character \e 0 to the character \e position - \e 1).
- * @param[out] lastWordLayoutInfo Layout info of the last part of the given word ( from the character \e position to the end of the word).
- */
-void SplitWord( std::size_t position,
- WordLayoutInfo& firstWordLayoutInfo,
- WordLayoutInfo& lastWordLayoutInfo );
-
-/**
- * Merges the two given words by adding characters of the last word to the firs one.
- *
- * @note Does nothing if last part of the word is empty.
- * @note If the first part of the word is empty it just copy the last part to it.
- * @note It asserts if the first or the last word is a word separator (white space) or a paragraph separator (new paragraph character)
- *
- * @param[in,out] firstWordLayoutInfo The input is the layout info of the first word. The output is the layout info of the merged word.
- * @param[in] lastWordLayoutInfo Layout info of the last word.
- */
-void MergeWord( WordLayoutInfo& firstWordLayoutInfo,
- const WordLayoutInfo& lastWordLayoutInfo );
-
-/**
- * Retrieves the layout information of the first character of the given word.
- *
- * @param[in] wordLayoutInfo The word layout.
- *
- * @return Layout information of the first character of the word.
- */
-CharacterLayoutInfo GetFirstCharacterLayoutInfo( const WordLayoutInfo& wordLayoutInfo );
-
-/**
- * Retrieves the layout information of the last character of the given word.
- *
- * @param[in] wordLayoutInfo The word layout.
- *
- * @return Layout information of the last character of the word.
- */
-CharacterLayoutInfo GetLastCharacterLayoutInfo( const WordLayoutInfo& wordLayoutInfo );
-
-/**
- * Collects text-actors from the given word, within the given indices, and stores them into the text-actor vector.
- *
- * @param[out] textActors Stores the text-actors of the given word.
- * @param[in] characterIndexBegin The first text-actor to be stored.
- * @param[in] characterIndexEnd The last text-actor to be stored.
- */
-void CollectTextActors( std::vector<TextActor>& textActors, const WordLayoutInfo& word, std::size_t characterIndexBegin, std::size_t characterIndexEnd );
-
-/**
- * Collects text-actors from the given paragraph, within the given indices, and stores them into the text-actor vector.
- *
- * @param[out] textActors Stores the text-actors of the given paragraph.
- * @param[in] paragraph The paragraph with the words.
- * @param[in] wordIndexBegin Index to the first word.
- * @param[in] wordIndexEnd Index to the last word.
- */
-void CollectTextActorsFromWords( std::vector<TextActor>& textActors, const ParagraphLayoutInfo& paragraph, std::size_t wordIndexBegin, std::size_t wordIndexEnd );
-
-} //namespace TextViewProcessor
-
-} //namespace Internal
-
-} //namespace Toolkit
-
-} //namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_VIEW_WORD_PROCESSOR_H__
$(toolkit_src_dir)/controls/slider/slider-impl.cpp \
$(toolkit_src_dir)/controls/super-blur-view/super-blur-view-impl.cpp \
$(toolkit_src_dir)/controls/table-view/table-view-impl.cpp \
- $(toolkit_src_dir)/controls/text-input/text-input-decorator-impl.cpp \
- $(toolkit_src_dir)/controls/text-input/text-input-handles-impl.cpp \
- $(toolkit_src_dir)/controls/text-input/text-input-impl.cpp \
- $(toolkit_src_dir)/controls/text-input/text-input-popup-impl.cpp \
- $(toolkit_src_dir)/controls/text-input/text-input-text-highlight-impl.cpp \
- $(toolkit_src_dir)/controls/text-view/relayout-utilities.cpp \
- $(toolkit_src_dir)/controls/text-view/split-by-char-policies.cpp \
- $(toolkit_src_dir)/controls/text-view/split-by-new-line-char-policies.cpp \
- $(toolkit_src_dir)/controls/text-view/split-by-word-policies.cpp \
- $(toolkit_src_dir)/controls/text-view/text-actor-cache.cpp \
- $(toolkit_src_dir)/controls/text-view/text-processor-bidirectional-info.cpp \
- $(toolkit_src_dir)/controls/text-view/text-processor.cpp \
- $(toolkit_src_dir)/controls/text-view/text-view-character-processor.cpp \
- $(toolkit_src_dir)/controls/text-view/text-view-impl.cpp \
- $(toolkit_src_dir)/controls/text-view/text-view-paragraph-processor.cpp \
- $(toolkit_src_dir)/controls/text-view/text-view-processor-dbg.cpp \
- $(toolkit_src_dir)/controls/text-view/text-view-processor-helper-functions.cpp \
- $(toolkit_src_dir)/controls/text-view/text-view-processor.cpp \
- $(toolkit_src_dir)/controls/text-view/text-view-word-processor.cpp \
+ $(toolkit_src_dir)/controls/text-controls/text-field-impl.cpp \
+ $(toolkit_src_dir)/controls/text-controls/text-label-impl.cpp \
$(toolkit_src_dir)/controls/tool-bar/tool-bar-impl.cpp \
$(toolkit_src_dir)/controls/view/view-impl.cpp \
$(toolkit_src_dir)/focus-manager/focus-manager-impl.cpp \
$(toolkit_src_dir)/shader-effects/page-turn-effect-impl.cpp \
$(toolkit_src_dir)/shader-effects/water-effect-impl.cpp \
$(toolkit_src_dir)/styling/style-manager-impl.cpp \
+ $(toolkit_src_dir)/text/rendering/text-backend-impl.cpp \
+ $(toolkit_src_dir)/text/multi-language-support-impl.cpp \
$(toolkit_src_dir)/transition-effects/cube-transition-effect-impl.cpp \
$(toolkit_src_dir)/transition-effects/cube-transition-cross-effect-impl.cpp \
$(toolkit_src_dir)/transition-effects/cube-transition-fold-effect-impl.cpp \
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/text/multi-language-support-impl.h>
+
+// EXTERNAL INCLUDES
+#include <memory.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/adaptor-framework/singleton-service.h>
+#include <dali/public-api/text-abstraction/font-client.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/logical-model.h>
+#include <dali-toolkit/public-api/text/font-run.h>
+#include <dali-toolkit/public-api/text/script.h>
+#include <dali-toolkit/public-api/text/script-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_MULTI_LANGUAGE_SUPPORT");
+#endif
+}
+
+namespace Text
+{
+
+namespace Internal
+{
+
+/**
+ * @brief Retrieves the font Id from the font run for a given character's @p index.
+ *
+ * If the character's index exceeds the current font run it increases the iterator to get the next one.
+ *
+ * @param[in] index The character's index.
+ * @param[in,out] fontRunIt Iterator to the current font run.
+ * @param[in] fontRunEndIt Iterator to one after the last font run.
+ *
+ * @return The font id.
+ */
+FontId GetFontId( Length index,
+ Vector<FontRun>::ConstIterator& fontRunIt,
+ const Vector<FontRun>::ConstIterator& fontRunEndIt )
+{
+ FontId fontId = 0u;
+
+ if( fontRunIt != fontRunEndIt )
+ {
+ const FontRun& fontRun = *fontRunIt;
+
+ if( ( index >= fontRun.characterRun.characterIndex ) &&
+ ( index < fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters ) )
+ {
+ fontId = fontRun.fontId;
+ }
+
+ if( index + 1u == fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters )
+ {
+ // All the characters of the current run have been traversed. Get the next one for the next iteration.
+ ++fontRunIt;
+ }
+ }
+
+ return fontId;
+}
+
+/**
+ * @brief Retrieves the script Id from the script run for a given character's @p index.
+ *
+ * If the character's index exceeds the current script run it increases the iterator to get the next one.
+ *
+ * @param[in] index The character's index.
+ * @param[in,out] scriptRunIt Iterator to the current font run.
+ * @param[in] scriptRunEndIt Iterator to one after the last script run.
+ *
+ * @return The script.
+ */
+Script GetScript( Length index,
+ Vector<ScriptRun>::ConstIterator& scriptRunIt,
+ const Vector<ScriptRun>::ConstIterator& scriptRunEndIt )
+{
+ Script script = TextAbstraction::UNKNOWN;
+
+ if( scriptRunIt != scriptRunEndIt )
+ {
+ const ScriptRun& scriptRun = *scriptRunIt;
+
+ if( ( index >= scriptRun.characterRun.characterIndex ) &&
+ ( index < scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters ) )
+ {
+ script = scriptRun.script;
+ }
+
+ if( index + 1u == scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters )
+ {
+ // All the characters of the current run have been traversed. Get the next one for the next iteration.
+ ++scriptRunIt;
+ }
+ }
+
+ return script;
+}
+
+/**
+ * @brief Whether the character is valid for all scripts. i.e. the white space.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is valid for all scripts.
+ */
+bool IsValidForAllScripts( Character character )
+{
+ return ( IsWhiteSpace( character ) ||
+ IsZeroWidthNonJoiner( character ) ||
+ IsZeroWidthJoiner( character ) ||
+ IsZeroWidthSpace( character ) ||
+ IsLeftToRightMark( character ) ||
+ IsRightToLeftMark( character ) ||
+ IsThinSpace( character ) );
+}
+
+bool ValidateFontsPerScript::FindValidFont( FontId fontId ) const
+{
+ for( Vector<FontId>::ConstIterator it = mValidFonts.Begin(),
+ endIt = mValidFonts.End();
+ it != endIt;
+ ++it )
+ {
+ if( fontId == *it )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+MultilanguageSupport::MultilanguageSupport()
+: mDefaultFontPerScriptCache(),
+ mValidFontsPerScriptCache()
+{
+ // Initializes the default font cache to zero (invalid font).
+ // Reserves space to cache the default fonts and access them with the script as an index.
+ mDefaultFontPerScriptCache.Resize( TextAbstraction::UNKNOWN, 0u );
+
+ // Initializes the valid fonts cache to NULL (no valid fonts).
+ // Reserves space to cache the valid fonts and access them with the script as an index.
+ mValidFontsPerScriptCache.Resize( TextAbstraction::UNKNOWN, NULL );
+}
+
+MultilanguageSupport::~MultilanguageSupport()
+{
+ // Destroy the valid fonts per script cache.
+
+ for( Vector<ValidateFontsPerScript*>::Iterator it = mValidFontsPerScriptCache.Begin(),
+ endIt = mValidFontsPerScriptCache.End();
+ it != endIt;
+ ++it )
+ {
+ delete *it;
+ }
+}
+
+Text::MultilanguageSupport MultilanguageSupport::Get()
+{
+ Text::MultilanguageSupport multilanguageSupportHandle;
+
+ SingletonService service( SingletonService::Get() );
+ if( service )
+ {
+ // Check whether the singleton is already created
+ Dali::BaseHandle handle = service.GetSingleton( typeid( Text::MultilanguageSupport ) );
+ if( handle )
+ {
+ // If so, downcast the handle
+ MultilanguageSupport* impl = dynamic_cast< Internal::MultilanguageSupport* >( handle.GetObjectPtr() );
+ multilanguageSupportHandle = Text::MultilanguageSupport( impl );
+ }
+ else // create and register the object
+ {
+ multilanguageSupportHandle = Text::MultilanguageSupport( new MultilanguageSupport );
+ service.Register( typeid( multilanguageSupportHandle ), multilanguageSupportHandle );
+ }
+ }
+
+ return multilanguageSupportHandle;
+}
+
+void MultilanguageSupport::SetScripts( const Vector<Character>& text,
+ const Vector<LineBreakInfo>& lineBreakInfo,
+ Vector<ScriptRun>& scripts )
+{
+ const Length numberOfCharacters = text.Count();
+
+ if( 0u == numberOfCharacters )
+ {
+ // Nothing to do if there are no characters.
+ return;
+ }
+
+ // Stores the current script run.
+ ScriptRun currentScriptRun;
+ currentScriptRun.characterRun.characterIndex = 0u;
+ currentScriptRun.characterRun.numberOfCharacters = 0u;
+ currentScriptRun.script = TextAbstraction::UNKNOWN;
+
+ // Reserve some space to reduce the number of reallocations.
+ scripts.Reserve( numberOfCharacters << 2u );
+
+ // Whether the first valid script need to be set.
+ bool firstValidScript = true;
+
+ // Whether the first valid script is a right to left script.
+ bool isParagraphRTL = false;
+
+ // Count the number of characters which are valid for all scripts. i.e. white spaces or '\n'.
+ Length numberOfAllScriptCharacters = 0u;
+
+ // Pointers to the text and break info buffers.
+ const Character* textBuffer = text.Begin();
+ const LineBreakInfo* breakInfoBuffer = lineBreakInfo.Begin();
+
+ // Traverse all characters and set the scripts.
+ for( Length index = 0u; index < numberOfCharacters; ++index )
+ {
+ Character character = *( textBuffer + index );
+ LineBreakInfo breakInfo = *( breakInfoBuffer + index );
+
+ // Some characters (like white spaces) are valid for many scripts. The rules to set a script
+ // for them are:
+ // - If they are at the begining of a paragraph they get the script of the first character with
+ // a defined script. If they are at the end, they get the script of the last one.
+ // - If they are between two scripts with the same direction, they get the script of the previous
+ // character with a defined script. If the two scripts have different directions, they get the
+ // script of the first character of the paragraph with a defined script.
+
+ // Skip those characters valid for many scripts like white spaces or '\n'.
+ bool endOfText = index == numberOfCharacters;
+ while( !endOfText &&
+ IsValidForAllScripts( character ) )
+ {
+ // Count all these characters to be added into a script.
+ ++numberOfAllScriptCharacters;
+
+ if( TextAbstraction::LINE_MUST_BREAK == breakInfo )
+ {
+ // The next character is a new paragraph.
+ // Know when there is a new paragraph is needed because if there is a white space
+ // between two scripts with different directions, it is added to the script with
+ // the same direction than the first script of the paragraph.
+ firstValidScript = true;
+ isParagraphRTL = false;
+ }
+
+ // Get the next character.
+ ++index;
+ endOfText = index == numberOfCharacters;
+ if( !endOfText )
+ {
+ character = *( textBuffer + index );
+ breakInfo = *( breakInfoBuffer + index );
+ }
+ }
+
+ if( endOfText )
+ {
+ // Last characters of the text are 'white spaces'.
+ // There is nothing else to do. Just add the remaining characters to the last script after this bucle.
+ break;
+ }
+
+ // Get the script of the character.
+ Script script = GetCharacterScript( character );
+
+ // Check if it is the first character of a paragraph.
+ if( firstValidScript &&
+ ( TextAbstraction::UNKNOWN != script ) )
+ {
+ // Sets the direction of the first valid script.
+ isParagraphRTL = ( TextAbstraction::ARABIC == script );
+ firstValidScript = false;
+ }
+
+ if( script != currentScriptRun.script )
+ {
+ // Current run needs to be stored and a new one initialized.
+
+ if( isParagraphRTL != ( TextAbstraction::ARABIC == script ) )
+ {
+ // Current script has different direction than the first script of the paragraph.
+ // All the previously skipped characters need to be added to the previous script before it's stored.
+ currentScriptRun.characterRun.numberOfCharacters += numberOfAllScriptCharacters;
+ numberOfAllScriptCharacters = 0u;
+ }
+
+ if( 0u != currentScriptRun.characterRun.numberOfCharacters )
+ {
+ // Store the script run.
+ scripts.PushBack( currentScriptRun );
+ }
+
+ // Initialize the new one.
+ currentScriptRun.characterRun.characterIndex = currentScriptRun.characterRun.characterIndex + currentScriptRun.characterRun.numberOfCharacters;
+ currentScriptRun.characterRun.numberOfCharacters = numberOfAllScriptCharacters; // Adds the white spaces which are at the begining of the script.
+ currentScriptRun.script = script;
+ numberOfAllScriptCharacters = 0u;
+ }
+ else
+ {
+ // Adds white spaces between characters.
+ currentScriptRun.characterRun.numberOfCharacters += numberOfAllScriptCharacters;
+ numberOfAllScriptCharacters = 0u;
+ }
+
+ if( TextAbstraction::LINE_MUST_BREAK == breakInfo )
+ {
+ // The next character is a new paragraph.
+ firstValidScript = true;
+ isParagraphRTL = false;
+ }
+
+ // Add one more character to the run.
+ ++currentScriptRun.characterRun.numberOfCharacters;
+ }
+
+ // Add remaining characters into the last script.
+ currentScriptRun.characterRun.numberOfCharacters += numberOfAllScriptCharacters;
+ if( 0u != currentScriptRun.characterRun.numberOfCharacters )
+ {
+ if( TextAbstraction::UNKNOWN == currentScriptRun.script )
+ {
+ // There are only white spaces in the last script. Set the latin script.
+ currentScriptRun.script = TextAbstraction::LATIN;
+ }
+
+ // Store the last run.
+ scripts.PushBack( currentScriptRun );
+ }
+}
+
+void MultilanguageSupport::ReplaceScripts( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert )
+{
+}
+
+void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
+ const Vector<ScriptRun>& scripts,
+ Vector<FontRun>& fonts )
+{
+ const Length numberOfCharacters = text.Count();
+
+ if( 0u == numberOfCharacters )
+ {
+ // Nothing to do if there are no characters.
+ return;
+ }
+
+ // Copy the fonts set by application developers.
+ const Length numberOfFontRuns = fonts.Count();
+ const Vector<FontRun> definedFonts = fonts;
+ fonts.Clear();
+
+ // Traverse the characters and validate/set the fonts.
+
+ // Get the caches.
+ FontId* defaultFontPerScriptCacheBuffer = mDefaultFontPerScriptCache.Begin();
+ ValidateFontsPerScript** validFontsPerScriptCacheBuffer = mValidFontsPerScriptCache.Begin();
+
+ // Stores the validated font runs.
+ fonts.Reserve( numberOfFontRuns );
+
+ // Initializes a validated font run.
+ FontRun currentFontRun;
+ currentFontRun.characterRun.characterIndex = 0u;
+ currentFontRun.characterRun.numberOfCharacters = 0u;
+ currentFontRun.fontId = 0u;
+ currentFontRun.isDefault = false;
+
+ // Get the font client.
+ TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+
+ // Iterators of the font and script runs.
+ Vector<FontRun>::ConstIterator fontRunIt = definedFonts.Begin();
+ Vector<FontRun>::ConstIterator fontRunEndIt = definedFonts.End();
+ Vector<ScriptRun>::ConstIterator scriptRunIt = scripts.Begin();
+ Vector<ScriptRun>::ConstIterator scriptRunEndIt = scripts.End();
+
+ for( Length index = 0u; index < numberOfCharacters; ++index )
+ {
+ // Get the character.
+ const Character character = *( text.Begin() + index );
+
+ // Get the font for the character.
+ FontId fontId = GetFontId( index,
+ fontRunIt,
+ fontRunEndIt );
+
+ // Get the script for the character.
+ Script script = GetScript( index,
+ scriptRunIt,
+ scriptRunEndIt );
+
+ if( TextAbstraction::UNKNOWN == script )
+ {
+ DALI_LOG_WARNING( "MultilanguageSupport::ValidateFonts. Unknown script!" );
+ script = TextAbstraction::LATIN;
+ }
+
+ // Whether the font being validated is a default one not set by the user.
+ const bool isDefault = ( 0u == fontId );
+
+ // The default font point size.
+ PointSize26Dot6 pointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
+
+ if( !isDefault )
+ {
+ // Validate if the font set by the user supports the character.
+
+ // Check first in the caches.
+
+ // The user may have set the default font. Check it. Otherwise check in the valid fonts cache.
+ if( fontId != *( defaultFontPerScriptCacheBuffer + script ) )
+ {
+ // Check in the valid fonts cache.
+ ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script );
+ if( NULL != validateFontsPerScript )
+ {
+ if( !validateFontsPerScript->FindValidFont( fontId ) )
+ {
+ // Use the font client to validate the font.
+ const GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character );
+
+ if( 0u == glyphIndex )
+ {
+ // Get the point size of the current font. It will be used to get a default font id.
+ pointSize = fontClient.GetPointSize( fontId );
+
+ // The font is not valid. Set to zero and a default one will be set.
+ fontId = 0u;
+ }
+ else
+ {
+ // Add the font to the valid font cache.
+ validateFontsPerScript->mValidFonts.PushBack( fontId );
+ }
+ }
+ }
+ else
+ {
+ // Use the font client to validate the font.
+ const GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character );
+
+ if( 0u == glyphIndex )
+ {
+ // Get the point size of the current font. It will be used to get a default font id.
+ pointSize = fontClient.GetPointSize( fontId );
+
+ // The font is not valid. Set to zero and a default one will be set.
+ fontId = 0u;
+ }
+ else
+ {
+ // Add the font to the valid font cache.
+ validateFontsPerScript = new ValidateFontsPerScript();
+ *( validFontsPerScriptCacheBuffer + script ) = validateFontsPerScript;
+
+ validateFontsPerScript->mValidFonts.PushBack( fontId );
+ }
+ }
+ }
+ }
+
+ // The font has not been validated. Find a default one.
+ if( 0u == fontId )
+ {
+ // The character has no font assigned. Get a default one from the cache
+ fontId = *( defaultFontPerScriptCacheBuffer + script );
+
+ // If the cache has not a default font, get one from the font client.
+ if( 0u == fontId )
+ {
+ // Find a default font.
+ fontId = fontClient.FindDefaultFont( character, pointSize );
+
+#ifdef DEBUG_ENABLED
+ Dali::TextAbstraction::FontDescription description;
+ fontClient.GetDescription( fontId, description );
+ DALI_LOG_INFO( gLogFilter, Debug::Concise, "Script: %s; Selected font: %s\n", Dali::TextAbstraction::ScriptName[script], description.path.c_str() );
+#endif
+ // Cache the font.
+ *( defaultFontPerScriptCacheBuffer + script ) = fontId;
+ }
+ }
+
+ // The font is now validated.
+
+ if( ( fontId != currentFontRun.fontId ) ||
+ ( isDefault != currentFontRun.isDefault ) )
+ {
+ // Current run needs to be stored and a new one initialized.
+
+ if( 0u != currentFontRun.characterRun.numberOfCharacters )
+ {
+ // Store the font run.
+ fonts.PushBack( currentFontRun );
+ }
+
+ // Initialize the new one.
+ currentFontRun.characterRun.characterIndex = currentFontRun.characterRun.characterIndex + currentFontRun.characterRun.numberOfCharacters;
+ currentFontRun.characterRun.numberOfCharacters = 0u;
+ currentFontRun.fontId = fontId;
+ currentFontRun.isDefault = isDefault;
+ }
+
+ // Add one more character to the run.
+ ++currentFontRun.characterRun.numberOfCharacters;
+ }
+
+ if( 0u != currentFontRun.characterRun.numberOfCharacters )
+ {
+ // Store the last run.
+ fonts.PushBack( currentFontRun );
+ }
+}
+
+void MultilanguageSupport::ValidateFonts( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert )
+{
+}
+
+} // namespace Internal
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_MULTI_LANGUAGE_SUPPORT_IMPL_H__
+#define __DALI_TOOLKIT_TEXT_MULTI_LANGUAGE_SUPPORT_IMPL_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/multi-language-support.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-object.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace Internal
+{
+
+/**
+ * @brief Stores valid font ids per script.
+ */
+struct ValidateFontsPerScript
+{
+ /**
+ * Default constructor.
+ */
+ ValidateFontsPerScript()
+ : mValidFonts()
+ {}
+
+ /**
+ * Default destructor.
+ */
+ ~ValidateFontsPerScript()
+ {}
+
+ /**
+ * @brief Whether the given @p fontId is in the vector of valid fonts.
+ *
+ * @param[in] fontId The font id.
+ *
+ * @return @e true if the font is in the vector of valid fonts.
+ */
+ bool FindValidFont( FontId fontId ) const;
+
+ Vector<FontId> mValidFonts;
+};
+
+/**
+ * @brief Multi-language support implementation. @see Text::MultilanguageSupport.
+ */
+class MultilanguageSupport : public BaseObject
+{
+public:
+
+ /**
+ * Constructor
+ */
+ MultilanguageSupport();
+
+ /**
+ * Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~MultilanguageSupport();
+
+ /**
+ * @copydoc Dali::MultilanguageSupport::Get()
+ */
+ static Text::MultilanguageSupport Get();
+
+ /**
+ * @copydoc Dali::MultilanguageSupport::SetScripts()
+ */
+ void SetScripts( const Vector<Character>& text,
+ const Vector<LineBreakInfo>& lineBreakInfo,
+ Vector<ScriptRun>& scripts );
+
+ /**
+ * @copydoc Dali::MultilanguageSupport::ReplaceScripts()
+ */
+ void ReplaceScripts( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert );
+
+ /**
+ * @copydoc Dali::MultilanguageSupport::ValidateFonts( const Vector<Character>& text, const Vector<ScriptRun>& scripts, Vector<FontRun>& fonts )
+ */
+ void ValidateFonts( const Vector<Character>& text,
+ const Vector<ScriptRun>& scripts,
+ Vector<FontRun>& fonts );
+
+ /**
+ * @copydoc Dali::MultilanguageSupport::ValidateFonts( LogicalModel& model, CharacterIndex characterIndex, Length numberOfCharactersToRemove, Length numberOfCharactersToInsert )
+ */
+ void ValidateFonts( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert );
+private:
+ Vector<FontId> mDefaultFontPerScriptCache; ///< Caches the default font for a script.
+ Vector<ValidateFontsPerScript*> mValidFontsPerScriptCache; ///< Caches valid fonts for a script.
+};
+
+} // namespace Internal
+
+inline static Internal::MultilanguageSupport& GetImplementation( MultilanguageSupport& multilanguageSupport )
+{
+ DALI_ASSERT_ALWAYS( multilanguageSupport && "multi-language handle is empty" );
+ BaseObject& handle = multilanguageSupport.GetBaseObject();
+ return static_cast<Internal::MultilanguageSupport&>( handle );
+}
+
+inline static const Internal::MultilanguageSupport& GetImplementation( const MultilanguageSupport& multilanguageSupport )
+{
+ DALI_ASSERT_ALWAYS( multilanguageSupport && "multi-language handle is empty" );
+ const BaseObject& handle = multilanguageSupport.GetBaseObject();
+ return static_cast<const Internal::MultilanguageSupport&>( handle );
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_MULTI_LANGUAGE_SUPPORT_IMPL_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/text/rendering/text-backend-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/singleton-service.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/rendering/basic/text-basic-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace Internal
+{
+
+struct Backend::Impl
+{
+ int temp; // placeholder for future backend implemenations
+};
+
+Backend::Backend()
+: mImpl( NULL )
+{
+ mImpl = new Impl();
+}
+
+Backend::~Backend()
+{
+ delete mImpl;
+}
+
+Dali::Toolkit::Text::Backend Backend::Get()
+{
+ Dali::Toolkit::Text::Backend backendHandle;
+
+ Dali::SingletonService service( SingletonService::Get() );
+ if ( service )
+ {
+ // Check whether the singleton is already created
+ Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::Toolkit::Text::Backend ) );
+ if(handle)
+ {
+ // If so, downcast the handle
+ Backend* impl = dynamic_cast< Dali::Toolkit::Text::Internal::Backend* >( handle.GetObjectPtr() );
+ backendHandle = Dali::Toolkit::Text::Backend( impl );
+ }
+ else // create and register the object
+ {
+ backendHandle = Dali::Toolkit::Text::Backend( new Backend );
+ service.Register( typeid( backendHandle ), backendHandle );
+ }
+ }
+
+ return backendHandle;
+}
+
+RendererPtr Backend::NewRenderer( unsigned int renderingType )
+{
+ RendererPtr renderer;
+
+ switch( renderingType )
+ {
+ case Dali::Toolkit::Text::RENDERING_BASIC:
+ {
+ renderer = Dali::Toolkit::Text::BasicRenderer::New();
+ }
+ break;
+
+ case Dali::Toolkit::Text::RENDERING_SHARED_ATLAS:
+ {
+ // TODO
+ }
+ break;
+
+ default:
+ {
+ DALI_LOG_WARNING( "Unknown renderer type: %d", renderingType );
+ break;
+ }
+ }
+
+ return renderer;
+}
+
+} // namespace Internal
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_BACKEND_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_BACKEND_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/rendering/text-backend.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace Internal
+{
+
+/**
+ * Implementation of the text rendering backend
+ */
+class Backend : public BaseObject
+{
+public:
+
+ /**
+ * Constructor
+ */
+ Backend();
+
+ /**
+ * Destructor
+ */
+ ~Backend();
+
+ /**
+ * @copydoc Dali::Toolkit::Text::Backend::Get()
+ */
+ static Dali::Toolkit::Text::Backend Get();
+
+ /**
+ * @copydoc Dali::Toolkit::Text::Backend::NewRenderer()
+ */
+ RendererPtr NewRenderer( unsigned int renderingType );
+
+private:
+
+ // Undefined copy constructor.
+ Backend( const Backend& );
+
+ // Undefined assignment constructor.
+ Backend& operator=( Backend& );
+
+private:
+
+ struct Impl;
+ Impl* mImpl;
+
+}; // class Backend
+
+} // namespace Internal
+
+inline static Internal::Backend& GetImplementation(Backend& backend)
+{
+ DALI_ASSERT_ALWAYS( backend && "backend handle is empty" );
+ BaseObject& handle = backend.GetBaseObject();
+ return static_cast<Internal::Backend&>(handle);
+}
+
+inline static const Internal::Backend& GetImplementation(const Backend& backend)
+{
+ DALI_ASSERT_ALWAYS( backend && "backend handle is empty" );
+ const BaseObject& handle = backend.GetBaseObject();
+ return static_cast<const Internal::Backend&>(handle);
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_BACKEND_H__
* Constructor
*/
NaviTitleBarStyle( Actor background,
- TextStyle titleTextStyle,
- TextStyle subtitleTextStyle,
int referenceWidth,
int height,
int titleHeightWithoutSubtitle,
int buttonBottomMargin,
int gapBetweenButtons )
: BasicNaviBarStyle( background, referenceWidth, height),
- titleTextStyle( titleTextStyle ), subtitleTextStyle( subtitleTextStyle ),
titleHeightWithoutSubtitle( titleHeightWithoutSubtitle ),
titleHeightWithSubtitle( titleHeightWithSubtitle ), subtitleHeight( subtitleHeight ),
titleLeftMargin( titleLeftMargin ), titleBottomMargin( titleBottomMargin ),
{
}
- TextStyle titleTextStyle; ///< the text style of the tile text
- TextStyle subtitleTextStyle; ///< the text style of the subtitle text
int titleHeightWithoutSubtitle; ///< the height of the title when no subtitle exists
int titleHeightWithSubtitle; ///< the height of the title when there is subtitle below
int subtitleHeight; ///< the height of the subtitle
GetImpl(*this).SetTitle( text );
}
-void Popup::SetTitle( TextView titleActor )
-{
- GetImpl(*this).SetTitle( titleActor );
-}
-
-TextView Popup::GetTitle() const
+const std::string& Popup::GetTitle() const
{
return GetImpl(*this).GetTitle();
}
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control.h>
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
namespace Dali
{
void SetTitle( const std::string& text );
/**
- * @brief Sets a title for this Popup.
- *
- * @param[in] titleActor The TextView to appear as the heading for this Popup
- */
- void SetTitle( TextView titleActor );
-
- /**
* @brief Gets the text (TextView) for this Popup.
*
- * @return The TextView representing this popup is returned.
+ * @return The text to appear as the heading for this Popup
*/
- TextView GetTitle() const;
+ const std::string& GetTitle() const;
/**
* @brief Adds a button to this Popup.
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/controls/text-controls/text-field.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+const std::string TextField::RENDERING_BACKEND_PROPERTY_NAME("rendering-backend");
+const std::string TextField::PLACEHOLDER_TEXT_PROPERTY_NAME("placeholder-text");
+const std::string TextField::TEXT_PROPERTY_NAME("text");
+const std::string TextField::CURSOR_IMAGE_PROPERTY_NAME("cursor-image");
+const std::string TextField::PRIMARY_CURSOR_COLOR_PROPERTY_NAME("primary-cursor-color");
+const std::string TextField::SECONDARY_CURSOR_COLOR_PROPERTY_NAME("secondary-cursor-color");
+const std::string TextField::ENABLE_CURSOR_BLINK_PROPERTY_NAME("enable-cursor-blink");
+const std::string TextField::CURSOR_BLINK_INTERVAL_PROPERTY_NAME("cursor-blink-interval");
+const std::string TextField::CURSOR_BLINK_DURATION_PROPERTY_NAME("cursor-blink-duration");
+const std::string TextField::GRAB_HANDLE_IMAGE_PROPERTY_NAME("grab-handle-image");
+const std::string TextField::DECORATION_BOUNDING_BOX("decoration-bounding-box");
+
+TextField TextField::New()
+{
+ return Internal::TextField::New();
+}
+
+TextField::TextField()
+{
+}
+
+TextField::TextField( const TextField& handle )
+: Control( handle )
+{
+}
+
+TextField& TextField::operator=( const TextField& handle )
+{
+ if( &handle != this )
+ {
+ Control::operator=( handle );
+ }
+ return *this;
+}
+
+TextField::~TextField()
+{
+}
+
+TextField TextField::DownCast( BaseHandle handle )
+{
+ return Control::DownCast<TextField, Internal::TextField>(handle);
+}
+
+TextField::TextField( Internal::TextField& implementation )
+: Control(implementation)
+{
+}
+
+TextField::TextField( Dali::Internal::CustomActor* internal )
+: Control( internal )
+{
+ VerifyCustomActorPointer<Internal::TextField>( internal );
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_FIELD_H__
+#define __DALI_TOOLKIT_TEXT_FIELD_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali-toolkit/public-api/text/rendering/text-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class TextField;
+}
+
+/**
+ * @brief A control which provides a single-line editable text field.
+ */
+class DALI_IMPORT_API TextField : public Control
+{
+public:
+
+ // Property indices
+ static const Dali::Property::Index PROPERTY_RENDERING_BACKEND; ///< name "rendering-backend", type INT
+ static const Dali::Property::Index PROPERTY_PLACEHOLDER_TEXT; ///< name "placeholder-text", type STRING
+ static const Dali::Property::Index PROPERTY_TEXT; ///< name "text", type STRING
+ static const Dali::Property::Index PROPERTY_CURSOR_IMAGE; ///< name "cursor-image", type STRING
+ static const Dali::Property::Index PROPERTY_PRIMARY_CURSOR_COLOR; ///< name "primary-cursor-color", type VECTOR4
+ static const Dali::Property::Index PROPERTY_SECONDARY_CURSOR_COLOR; ///< name "secondary-cursor-color", type VECTOR4
+ static const Dali::Property::Index PROPERTY_ENABLE_CURSOR_BLINK; ///< name "enable-cursor-blink", type BOOLEAN
+ static const Dali::Property::Index PROPERTY_CURSOR_BLINK_INTERVAL; ///< name "cursor-blink-interval", type FLOAT
+ static const Dali::Property::Index PROPERTY_CURSOR_BLINK_DURATION; ///< name "cursor-blink-duration", type FLOAT
+ static const Dali::Property::Index PROPERTY_GRAB_HANDLE_IMAGE; ///< name "grab-handle-image", type STRING
+ static const Dali::Property::Index PROPERTY_DECORATION_BOUNDING_BOX; ///< name "decoration-bounding-box", type RECTANGLE
+
+ // Property names
+ static const std::string RENDERING_BACKEND_PROPERTY_NAME; ///< Property, name "rendering-backend", type INT
+ static const std::string PLACEHOLDER_TEXT_PROPERTY_NAME; ///< Property, name "placeholder-text", type STRING
+ static const std::string TEXT_PROPERTY_NAME; ///< Property, name "text", type STRING
+ static const std::string CURSOR_IMAGE_PROPERTY_NAME; ///< Property, name "cursor-image", type STRING
+ static const std::string PRIMARY_CURSOR_COLOR_PROPERTY_NAME; ///< Property, name "primary-cursor-color", type VECTOR4
+ static const std::string SECONDARY_CURSOR_COLOR_PROPERTY_NAME; ///< Property, name "secondary-cursor-color", type VECTOR4
+ static const std::string ENABLE_CURSOR_BLINK_PROPERTY_NAME; ///< Property, name "enable-cursor-blink", type BOOLEAN
+ static const std::string CURSOR_BLINK_INTERVAL_PROPERTY_NAME; ///< Property, name "cursor-blink-interval", type FLOAT
+ static const std::string CURSOR_BLINK_DURATION_PROPERTY_NAME; ///< Property, name "cursor-blink-duration", type FLOAT
+ static const std::string GRAB_HANDLE_IMAGE_PROPERTY_NAME; ///< Property, name "grab-handle-image", type STRING
+ static const std::string DECORATION_BOUNDING_BOX; ///< Property, name "decoration-bounding-box", type RECTANGLE
+
+ /**
+ * Create the TextField control.
+ * @return A handle to the TextField control.
+ */
+ static TextField New();
+
+ /**
+ * @brief Creates an empty handle.
+ */
+ TextField();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param[in] handle The handle to copy from.
+ */
+ TextField( const TextField& handle );
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @param[in] handle The handle to copy from.
+ * @return A reference to this.
+ */
+ TextField& operator=( const TextField& handle );
+
+ /**
+ * @brief Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~TextField();
+
+ /**
+ * @brief Downcast a handle to TextField.
+ *
+ * If the BaseHandle points is a TextField the downcast returns a valid handle.
+ * If not the returned handle is left empty.
+ *
+ * @param[in] handle Handle to an object
+ * @return handle to a TextField or an empty handle
+ */
+ static TextField DownCast( BaseHandle handle );
+
+public: // Not intended for application developers
+
+ /**
+ * @brief Creates a handle using the Toolkit::Internal implementation.
+ *
+ * @param[in] implementation The Control implementation.
+ */
+ DALI_INTERNAL TextField( Internal::TextField& implementation );
+
+ /**
+ * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
+ *
+ * @param[in] internal A pointer to the internal CustomActor.
+ */
+ explicit DALI_INTERNAL TextField( Dali::Internal::CustomActor* internal );
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_FIELD_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/text-controls/text-label-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+const std::string TextLabel::RENDERING_BACKEND_PROPERTY_NAME("rendering-backend");
+const std::string TextLabel::TEXT_PROPERTY_NAME("text");
+const std::string TextLabel::MULTI_LINE_PROPERTY_NAME("multi-line");
+
+TextLabel TextLabel::New()
+{
+ return Internal::TextLabel::New();
+}
+
+TextLabel::TextLabel()
+{
+}
+
+TextLabel::TextLabel( const TextLabel& handle )
+: Control( handle )
+{
+}
+
+TextLabel& TextLabel::operator=( const TextLabel& handle )
+{
+ if( &handle != this )
+ {
+ Control::operator=( handle );
+ }
+ return *this;
+}
+
+TextLabel::~TextLabel()
+{
+}
+
+TextLabel TextLabel::DownCast( BaseHandle handle )
+{
+ return Control::DownCast<TextLabel, Internal::TextLabel>(handle);
+}
+
+TextLabel::TextLabel( Internal::TextLabel& implementation )
+: Control(implementation)
+{
+}
+
+TextLabel::TextLabel( Dali::Internal::CustomActor* internal )
+: Control( internal )
+{
+ VerifyCustomActorPointer<Internal::TextLabel>( internal );
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_LABEL_H__
+#define __DALI_TOOLKIT_TEXT_LABEL_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali-toolkit/public-api/text/rendering/text-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class TextLabel;
+}
+
+/**
+ * @brief A control which renders a short text string.
+ *
+ * Text labels are lightweight, non-editable and do not respond to user input.
+ */
+class DALI_IMPORT_API TextLabel : public Control
+{
+public:
+
+ // Property indices
+ static const Dali::Property::Index PROPERTY_RENDERING_BACKEND; ///< name "rendering-backend", type INT
+ static const Dali::Property::Index PROPERTY_TEXT; ///< name "text", type STRING
+ static const Dali::Property::Index PROPERTY_MULTI_LINE; ///< name "multi-line", type BOOLEAN
+
+ // Property names
+ static const std::string RENDERING_BACKEND_PROPERTY_NAME; ///< Property, name "rendering-backend", type INT
+ static const std::string TEXT_PROPERTY_NAME; ///< Property, name "text", type STRING
+ static const std::string MULTI_LINE_PROPERTY_NAME; ///< Property, name "multi-line", type BOOLEAN
+
+ /**
+ * Create the TextLabel control.
+ * @return A handle to the TextLabel control.
+ */
+ static TextLabel New();
+
+ /**
+ * @brief Creates an empty handle.
+ */
+ TextLabel();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param[in] handle The handle to copy from.
+ */
+ TextLabel( const TextLabel& handle );
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @param[in] handle The handle to copy from.
+ * @return A reference to this.
+ */
+ TextLabel& operator=( const TextLabel& handle );
+
+ /**
+ * @brief Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~TextLabel();
+
+ /**
+ * @brief Downcast a handle to TextLabel.
+ *
+ * If the BaseHandle points is a TextLabel the downcast returns a valid handle.
+ * If not the returned handle is left empty.
+ *
+ * @param[in] handle Handle to an object
+ * @return handle to a TextLabel or an empty handle
+ */
+ static TextLabel DownCast( BaseHandle handle );
+
+public: // Not intended for application developers
+
+ /**
+ * @brief Creates a handle using the Toolkit::Internal implementation.
+ *
+ * @param[in] implementation The Control implementation.
+ */
+ DALI_INTERNAL TextLabel( Internal::TextLabel& implementation );
+
+ /**
+ * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
+ *
+ * @param[in] internal A pointer to the internal CustomActor.
+ */
+ explicit DALI_INTERNAL TextLabel( Dali::Internal::CustomActor* internal );
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_LABEL_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali-toolkit/public-api/controls/text-input/text-input.h>
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/actors/mesh-actor.h>
-#include <dali/public-api/adaptor-framework/clipboard.h>
-#include <dali/public-api/adaptor-framework/clipboard-event-notifier.h>
-#include <dali/public-api/adaptor-framework/imf-manager.h>
-#include <dali/public-api/adaptor-framework/timer.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/text-input/text-input.h>
-#include <dali-toolkit/internal/controls/text-input/text-input-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-TextInput::TextInput()
-{
-}
-
-TextInput::TextInput(Internal::TextInput& implementation)
-: Control(implementation)
-{
-}
-
-TextInput::TextInput( const TextInput& textInput )
-: Control( textInput )
-{
-}
-
-TextInput& TextInput::operator=( const TextInput& textInput )
-{
- if( &textInput != this )
- {
- Control::operator=( textInput );
- }
-
- return *this;
-}
-
-TextInput TextInput::New()
-{
- return Internal::TextInput::New();
-}
-
-TextInput TextInput::DownCast( BaseHandle actor )
-{
- return Control::DownCast<TextInput, Internal::TextInput>(actor);
-}
-
-TextInput::~TextInput()
-{
-}
-
-std::string TextInput::GetText() const
-{
- return GetImpl(*this).GetText();
-}
-
-std::string TextInput::GetMarkupText() const
-{
- return GetImpl(*this).GetMarkupText();
-}
-
-void TextInput::SetMaxCharacterLength(std::size_t maxChars)
-{
- GetImpl(*this).SetMaxCharacterLength(maxChars);
-}
-
-void TextInput::SetNumberOfLinesLimit(std::size_t maxLines)
-{
- GetImpl(*this).SetNumberOfLinesLimit( maxLines );
-}
-
-std::size_t TextInput::GetNumberOfLinesLimit() const
-{
- return GetImpl(*this).GetNumberOfLinesLimit();
-}
-
-std::size_t TextInput::GetNumberOfCharacters() const
-{
- return GetImpl(*this).GetNumberOfCharacters();
-}
-
-void TextInput::SetPlaceholderText( const std::string& placeHolderText )
-{
- GetImpl(*this).SetPlaceholderText( placeHolderText );
-}
-
-std::string TextInput::GetPlaceholderText()
-{
- return GetImpl(*this).GetPlaceholderText();
-}
-
-void TextInput::SetInitialText(const std::string& initialText)
-{
- GetImpl(*this).SetInitialText(initialText);
-}
-
-void TextInput::SetEditable(bool editMode)
-{
- GetImpl(*this).SetEditable(editMode, false);
-}
-
-void TextInput::SetEditable(bool editMode, const Vector2& touchPoint)
-{
- GetImpl(*this).SetEditable(editMode, true, touchPoint);
-}
-
-bool TextInput::IsEditable() const
-{
- return GetImpl(*this).IsEditable();
-}
-
-void TextInput::SetEditOnTouch( bool editOnTouch )
-{
- GetImpl(*this).SetEditOnTouch( editOnTouch );
-}
-
-bool TextInput::IsEditOnTouch() const
-{
- return GetImpl(*this).IsEditOnTouch();
-}
-
-void TextInput::SetTextSelectable( bool textSelectable )
-{
- GetImpl(*this).SetTextSelectable( textSelectable );
-}
-
-bool TextInput::IsTextSelectable() const
-{
- return GetImpl(*this).IsTextSelectable();
-}
-
-bool TextInput::IsTextSelected() const
-{
- return GetImpl(*this).IsTextSelected();
-}
-
-void TextInput::SelectText(std::size_t start, std::size_t end)
-{
- GetImpl(*this).SelectText( start, end );
-}
-
-void TextInput::DeSelectText()
-{
- GetImpl(*this).DeSelectText();
-}
-
-void TextInput::SetGrabHandleImage( Image image )
-{
- GetImpl(*this).SetGrabHandleImage(image);
-}
-
-void TextInput::SetCursorImage(Dali::Image image, const Vector4& border )
-{
- GetImpl(*this).SetCursorImage(image, border );
-}
-
-Vector3 TextInput::GetSelectionHandleSize()
-{
- return GetImpl(*this).GetSelectionHandleSize();
-}
-
-void TextInput::SetRTLCursorImage(Dali::Image image, const Vector4& border )
-{
- GetImpl(*this).SetRTLCursorImage(image, border );
-}
-
-void TextInput::EnableGrabHandle(bool toggle)
-{
- GetImpl(*this).EnableGrabHandle( toggle );
-}
-
-bool TextInput::IsGrabHandleEnabled()
-{
- return GetImpl(*this).IsGrabHandleEnabled();
-}
-
-void TextInput::SetBoundingRectangle( const Rect<float>& boundingOriginAndSize )
-{
- GetImpl(*this).SetBoundingRectangle( boundingOriginAndSize );
-}
-
-const Rect<float> TextInput::GetBoundingRectangle() const
-{
- return GetImpl(*this).GetBoundingRectangle();
-}
-
-void TextInput::SetActiveStyle( const TextStyle& style, const TextStyle::Mask mask )
-{
- GetImpl(*this).SetActiveStyle(style,mask);
-}
-
-void TextInput::ApplyStyle( const TextStyle& style, const TextStyle::Mask mask )
-{
- GetImpl(*this).ApplyStyle( style, mask );
-}
-
-void TextInput::ApplyStyleToAll( const TextStyle& style, const TextStyle::Mask mask )
-{
- GetImpl(*this).ApplyStyleToAll( style, mask );
-}
-
-TextStyle TextInput::GetStyleAtCursor() const
-{
- return GetImpl(*this).GetStyleAtCursor();
-}
-
-void TextInput::SetTextAlignment( Toolkit::Alignment::Type align )
-{
- GetImpl(*this).SetTextAlignment(align);
-}
-
-void TextInput::SetTextLineJustification( Toolkit::TextView::LineJustification justification )
-{
- GetImpl(*this).SetTextLineJustification(justification);
-}
-
-void TextInput::SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary )
-{
- GetImpl(*this).SetFadeBoundary( fadeBoundary );
-}
-
-const Toolkit::TextView::FadeBoundary& TextInput::GetFadeBoundary() const
-{
- return GetImpl(*this).GetFadeBoundary();
-}
-
-Alignment::Type TextInput::GetTextAlignment() const
-{
- return GetImpl(*this).GetTextAlignment();
-}
-
-void TextInput::SetMultilinePolicy( TextView::MultilinePolicy policy )
-{
- GetImpl(*this).SetMultilinePolicy(policy);
-}
-
-TextView::MultilinePolicy TextInput::GetMultilinePolicy() const
-{
- return GetImpl(*this).GetMultilinePolicy();
-}
-
-void TextInput::SetWidthExceedPolicy( TextView::ExceedPolicy policy )
-{
- GetImpl(*this).SetWidthExceedPolicy(policy);
-}
-
-TextView::ExceedPolicy TextInput::GetWidthExceedPolicy() const
-{
- return GetImpl(*this).GetWidthExceedPolicy();
-}
-
-void TextInput::SetHeightExceedPolicy( TextView::ExceedPolicy policy )
-{
- GetImpl(*this).SetHeightExceedPolicy(policy);
-}
-
-TextView::ExceedPolicy TextInput::GetHeightExceedPolicy() const
-{
- return GetImpl(*this).GetHeightExceedPolicy();
-}
-
-void TextInput::SetExceedEnabled( bool enable )
-{
- GetImpl(*this).SetExceedEnabled( enable );
-}
-
-bool TextInput::GetExceedEnabled() const
-{
- return GetImpl(*this).GetExceedEnabled();
-}
-
-void TextInput::SetSortModifier( float depthOffset )
-{
- GetImpl( *this ).SetSortModifier( depthOffset );
-}
-
-void TextInput::SetSnapshotModeEnabled( bool enable )
-{
- GetImpl( *this ).SetSnapshotModeEnabled( enable );
-}
-
-bool TextInput::IsSnapshotModeEnabled() const
-{
- return GetImpl( *this ).IsSnapshotModeEnabled();
-}
-
-void TextInput::SetScrollEnabled( bool enable )
-{
- GetImpl( *this ).SetScrollEnabled( enable );
-}
-
-bool TextInput::IsScrollEnabled() const
-{
- return GetImpl( *this ).IsScrollEnabled();
-}
-
-void TextInput::SetScrollPosition( const Vector2& position )
-{
- GetImpl( *this ).SetScrollPosition( position );
-}
-
-Vector2 TextInput::GetScrollPosition() const
-{
- return GetImpl( *this ).GetScrollPosition();
-}
-
-TextInput::InputSignalType& TextInput::InputStartedSignal()
-{
- return GetImpl(*this).InputStartedSignal();
-}
-
-TextInput::InputSignalType& TextInput::InputFinishedSignal()
-{
- return GetImpl(*this).InputFinishedSignal();
-}
-
-TextInput::InputSignalType& TextInput::CutAndPasteToolBarDisplayedSignal()
-{
- return GetImpl(*this).CutAndPasteToolBarDisplayedSignal();
-}
-
-TextInput::StyleChangedSignalType& TextInput::StyleChangedSignal()
-{
- return GetImpl(*this).StyleChangedSignal();
-}
-
-TextInput::TextModifiedSignalType& TextInput::TextModifiedSignal()
-{
- return GetImpl(*this).TextModifiedSignal();
-}
-
-TextInput::MaxInputCharactersReachedSignalType& TextInput::MaxInputCharactersReachedSignal()
-{
- return GetImpl(*this).MaxInputCharactersReachedSignal();
-}
-
-TextInput::InputTextExceedBoundariesSignalType& TextInput::InputTextExceedBoundariesSignal()
-{
- return GetImpl(*this).InputTextExceedBoundariesSignal();
-}
-
-void TextInput::SetMarkupProcessingEnabled( bool enable )
-{
- return GetImpl( *this ).SetMarkupProcessingEnabled( enable );
-}
-
-bool TextInput::IsMarkupProcessingEnabled() const
-{
- return GetImpl( *this ).IsMarkupProcessingEnabled();
-}
-
-
-TextInput::TextInput( Dali::Internal::CustomActor* internal )
-: Control( internal )
-{
- VerifyCustomActorPointer<Internal::TextInput>(internal);
-}
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_TEXT_INPUT_H__
-#define __DALI_TOOLKIT_TEXT_INPUT_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal DALI_INTERNAL
-{
-class TextInput;
-}
-
-/**
- * @brief TextInput Actor takes input one character at a time and displays it as a string within an input box.
- * Characters can be removed from the end of the string until it is empty. A maximum length of displayed string
- * can be set.
- */
-class DALI_IMPORT_API TextInput : public Control
-{
-
-public:
-
- /// @name Properties
- /** @{ */
- static const Dali::Property::Index HIGHLIGHT_COLOR_PROPERTY; // Property, name "highlight-color", type VECTOR4
- static const Dali::Property::Index CUT_AND_PASTE_COLOR_PROPERTY; // Property, name "cut-and-paste-bg-color", type VECTOR4
- static const Dali::Property::Index CUT_AND_PASTE_PRESSED_COLOR_PROPERTY; // Property, name "cut-and-paste-pressed-color", type VECTOR4
- static const Dali::Property::Index CUT_AND_PASTE_BORDER_COLOR_PROPERTY; // Property, name "cut-and-paste-border-color", type VECTOR4
- static const Dali::Property::Index CUT_AND_PASTE_ICON_COLOR_PROPERTY; // Property, name "cut-and-paste-icon-color", type VECTOR4
- static const Dali::Property::Index CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY; // Property, name "cut-and-paste-icon-pressed-color", type VECTOR4
- static const Dali::Property::Index CUT_AND_PASTE_TEXT_COLOR_PROPERTY; // Property, name "cut-and-paste-text-color", type VECTOR4
- static const Dali::Property::Index CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY; // Property, name "cut-and-paste-text-pressed-color", type VECTOR4
- static const Dali::Property::Index CUT_BUTTON_POSITION_PRIORITY_PROPERTY; // Property, name "cut-button-position-priority", type unsigned int
- static const Dali::Property::Index COPY_BUTTON_POSITION_PRIORITY_PROPERTY; // Property, name "copy-button-position-priority", type unsigned int
- static const Dali::Property::Index PASTE_BUTTON_POSITION_PRIORITY_PROPERTY; // Property, name "paste-button-position-priority", type unsigned int
- static const Dali::Property::Index SELECT_BUTTON_POSITION_PRIORITY_PROPERTY; // Property, name "select-button-position-priority", type unsigned int
- static const Dali::Property::Index SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY; // Property, name "select-all-button-position-priority", type unsigned int
- static const Dali::Property::Index CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY; // Property, name "clipboard-button-position-priority", type unsigned int
- static const Dali::Property::Index POP_UP_OFFSET_FROM_TEXT_PROPERTY; // Property, name "popup-offset-from-text", type VECTOR4
- static const Dali::Property::Index CURSOR_COLOR_PROPERTY; // Property, name "cursor-color", type VECTOR4
- /** @} */
-
-public:
-
- /**
- * @brief Create an uninitialized TextInput; this can be initialized with TextView::New().
- *
- * Calling member functions with an uninitialized Dali::Object is not allowed.
- */
- TextInput();
-
- /**
- * @brief Copy constructor.
- *
- * @param handle to be copied
- */
- TextInput( const TextInput& handle );
-
- /**
- * @brief Assignment operator.
- *
- * @param handle to object we want to point to
- * @return handle to the TextInput
- */
- TextInput& operator=( const TextInput& handle );
-
- /**
- * @brief Create an initialised TextInput.
- *
- * @return A handle to a newly allocated Dali resource.
- */
- static TextInput New();
-
- /**
- * @brief Downcast an Object handle to TextInput.
- *
- * If handle points to a TextInput the downcast produces valid
- * handle. If not the returned handle is left uninitialized.
- *
- * @param[in] handle Handle to an object
- * @return handle to a TextInput or an uninitialized handle
- */
- static TextInput DownCast( BaseHandle handle );
-
- /**
- * @brief Destructor
- *
- * This is non-virtual since derived Handle types must not contain data or virtual methods.
- */
- ~TextInput();
-
- /**
- * @brief Get the inputed text currently being displayed.
- *
- * @return string, the currently displayed string.
- */
- std::string GetText() const;
-
- /**
- * @brief Get the inputed text currently being displayed together with mark-up tags.
- *
- * @return string, the currently displayed string with mark-up.
- */
- std::string GetMarkupText() const;
-
- /**
- * @brief Set the maximum number of characters for the Text Input.
- *
- * @param [in] maxChars the max number of characters
- */
- void SetMaxCharacterLength(std::size_t maxChars);
-
- /**
- * @brief Limits the number of lines of text Text Input will display.
- *
- * @param [in] maxLines the max number of lines to display, must be greater than 0.
- * Currently the only valid limit is 1. Which turns TextInput into Single line mode. Any number higher than 1 results in no limit.
- */
- void SetNumberOfLinesLimit(std::size_t maxLines);
-
- /**
- * @brief Returns the limit of lines Text Input is allowed to display.
- *
- * @return max line number limit
- */
- std::size_t GetNumberOfLinesLimit() const;
-
- /**
- * @brief Returns the number of characters TextInput is displaying.
- *
- * @return number of characters
- */
- std::size_t GetNumberOfCharacters() const;
-
- /**
- * @brief Sets a place holder text to be displayed when the text-input is empty.
- *
- * If not set or set to an empty string then no place holder will be shown.
- * @param [in] placeHolderText text to be used as place holder.
- */
- void SetPlaceholderText( const std::string& placeHolderText );
-
- /**
- * @return the current set place holder text, empty string returned if not set.
- */
- std::string GetPlaceholderText();
-
- /**
- * @brief set initial text to be displayed in text-input.
- *
- * Can be used to edit a pre-existing string.
- * @param [in] initialText text to be initially displayed
- */
- void SetInitialText(const std::string& initialText);
-
- /**
- * @brief Manual method to set the focus on the TextInput so it starts or stops edit state.
- *
- * @pre The text input actor has been initialised.
- * @param[in] editMode true or false to indicate editMode on or off
- */
- void SetEditable(bool editMode);
-
- /**
- * @see SetEditable(bool editMode).
- *
- * It sets the cursor in the closest character to the given touch point.
- *
- * @param[in] editMode true or false to indicate editMode on or off
- * @param[in] touchPoint A position in actor coordinates within the text-input.
- */
- void SetEditable(bool editMode, const Vector2& touchPoint);
-
- /**
- * @brief Check if TextInput is in edit state.
- *
- * @pre The text input actor has been initialised.
- * @return True or False to indicate editMode on or off
- */
- bool IsEditable() const;
-
- /**
- * @brief Method to enable or disable edit on touch/tap.
- *
- * If not enabled (set to false) then SetEditable(true) will be used to start edit mode.
- * @pre The text input actor has been initialised.
- * @param[in] editOnTouch true or false to indicate if editing should start on touch
- * default is for editing to start on touching textinput
- */
- void SetEditOnTouch(bool editOnTouch = true);
-
- /**
- * @brief Check if TextInput starts edit mode on touch.
- *
- * @pre The text input actor has been initialised.
- * @return True or False to indicate editOnTouch on or off
- */
- bool IsEditOnTouch() const;
-
- /**
- * @brief Check if Text Selection is enabled so required text can be highlighted.
- *
- * @pre The text input actor has been initialised.
- * @param[in] textSelectable true or false to indicate if text can be selected or not
- * default is for text to be select-able when in edit mode
- */
- void SetTextSelectable(bool textSelectable = true);
-
- /**
- * @brief Check if Text can be selected.
- *
- * @pre The text input actor has been initialised.
- * @return True or False to indicate if text can be selected or not
- */
- bool IsTextSelectable() const;
-
- /**
- * @brief Check if any text is currently selected, can be used to determine if ApplyStyle or SetActiveStyle should be used.
- *
- * @pre The text input actor has been initialised.
- * @return True if text selected else False
- */
- bool IsTextSelected() const;
-
- /**
- * @brief Selects text between the given positions.
- *
- * @pre TextInput should be in edit mode.
- * @param start position to start selection
- * @param end position to end selection, inclusive of this character.
- * Providing 0 and result from GetNumberOfCharacters() will select all text.
- */
- void SelectText(std::size_t start, std::size_t end);
-
- /**
- * @brief If any text is selected then de-select it and hide highlight.
- *
- * @pre The text input actor has been initialised.
- */
- void DeSelectText();
-
- /**
- * @brief Set the image to be used as the cursor grab hander.
- *
- * @pre The text input actor has been initialised.
- * @param[in] image The image to be used.
- */
- void SetGrabHandleImage( Image image );
-
- /**
- * Depreciated API.
- * @brief Set the image to be used for the regular left to right cursor.
- *
- * @pre The text input actor has been initialised.
- * @param[in] image The image to be used.
- * @param[in] border The nine patch border for the image.
- */
- void SetCursorImage(Dali::Image image, const Vector4& border );
-
- /**
- * @brief Retrieve the selection handle size.
- *
- * Both handles have same size.
- * @return Vector3 the selection handle size.
- */
- Vector3 GetSelectionHandleSize();
-
- /**
- * @brief Set the image to be used for the Right to Left cursor.
- *
- * @pre The text input actor has been initialised.
- * @param[in] image The image to be used.
- * @param[in] border The nine patch border for the image.
- */
- void SetRTLCursorImage(Dali::Image image, const Vector4& border );
-
- /**
- * @brief Toggle to enable the grab handle, used to position cursor when magnifier not being used.
- *
- * Default behaviour is to use the magnifier to position the cursor, enabling this prevents the magnifier from being shown.
- * @param[in] toggle true to enable, false to disable grab handle
- */
- void EnableGrabHandle(bool toggle);
-
- /**
- * @brief Method to check if grab handle is enabled, if false then the magnifier will be used to position cursor.
- *
- * @return bool returns true is grab handle enabled.
- */
- bool IsGrabHandleEnabled();
-
- /**
- * @brief Set the bounding rectangle which handles, popup and similar decorations will not exceed.
- *
- * The default value is the width and height of the stage from the top left origin.
- * If a title bar for example is on the top of the screen then the y should be the title's height and
- * the boundary height the stage height minus the title's height.
- * Restrictions - The boundary box should be set up with a fixed z position for the text-input and the default camera.
- * @param[in] boundingOriginAndSize Rect( x coordinate, y coordinate, width, height )
- * @code
- * +----------------------------------------+
- * |(x,y) |
- * |+--------------------------------------+|
- * || ||
- * || Bounding Box || boundary height
- * || ||
- * |+--------------------------------------+|
- * +----------------------------------------+
- * boundary width
- * @endcode
- */
- void SetBoundingRectangle( const Rect<float>& boundingOriginAndSize );
-
- /**
- * @brief Retrieve the bounding box origin and dimensions.
- *
- * default is set once control is added to stage, before this the return vector will be Vector4:ZERO
- * @return Rect the bounding rectangle
- */
- const Rect<float> GetBoundingRectangle() const;
-
- /**
- * @brief Sets the style for new text being typed.
- *
- * By default all style settings are applied but a bit mask could be used to modify only certain style settings.
- * @pre The text input actor has been initialised.
- * @param[in] style The style for the new text.
- * @param[in] mask The bit mask.
- */
- void SetActiveStyle( const TextStyle& style, const TextStyle::Mask mask = TextStyle::ALL );
-
- /**
- * @brief Applies the given style to the selected text.
- *
- * By default all style settings are applied but a bit mask could be used to modify only certain style settings.
- * Introduced text after this call uses the new style.
- * @param[in] style The given style.
- * @param[in] mask The bit mask.
- */
- void ApplyStyle( const TextStyle& style, const TextStyle::Mask mask = TextStyle::ALL );
-
- /**
- * @brief Applies the given style to all text, selected or not selected.
- *
- * By default all style settings are applied but a bit mask could be used to modify only certain style settings.
- * @param[in] style The given style.
- * @param[in] mask The bit mask.
- */
- void ApplyStyleToAll( const TextStyle& style, const TextStyle::Mask mask = TextStyle::ALL );
-
- /**
- * @brief Get the style of the Text character before the cursor.
- *
- * If no character before then return the InputStyle.
- * @return TextStyle, the style of the character before the cursor
- */
- TextStyle GetStyleAtCursor() const;
-
- /**
- * @brief Set the current text alignment (overrides default setting).
- *
- * The default alignment is dependent on the current text in the text field.
- * If the text begins using LTR characters (e.g. European text) then the
- * alignment is HorizontalLeft. If the text begins using RTL characters
- * (e.g. Hebrew/Arabic text) then the alignment is HorizontalRight.
- * If there is no text, then the alignment defaults to:
- * (HorizontalLeft | VerticalCenter)
- * @param[in] align The new alignment option.
- */
- void SetTextAlignment( Toolkit::Alignment::Type align );
-
- /**
- * @brief Set the current line justification. (overrides default setting).
- *
- * The default justification is dependent on the current text in the text field.
- * If the text begins using LTR characters (e.g. European text) then the
- * justification is HorizontalLeft. If the text begins using RTL characters
- * (e.g. Hebrew/Arabic text) then the justification is HorizontalRight.
- * If there is no text, then the justification defaults to:
- * (HorizontalLeft | VerticalCenter)
- * @param[in] justification The new line justification.
- */
- void SetTextLineJustification( Toolkit::TextView::LineJustification justification );
-
- /**
- * @brief Sets a fade boundary.
- *
- * @see TextView::FadeBoundary.
- *
- * @param[in] fadeBoundary The given fade boundary.
- */
- void SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary );
-
- /**
- * @brief Retrieves the fade boundary.
- *
- * @see TextView::FadeBoundary.
- *
- * @return The fade boundary.
- */
- const Toolkit::TextView::FadeBoundary& GetFadeBoundary() const;
-
- /**
- * @brief Get the current text alignment combined into a single value.
- *
- * The values can be tested by using the & operator
- * and the desired flag. e.g. if (GetTextAlignment() & HorizontalCentre) ...
- * @return The combined text alignment
- */
- Toolkit::Alignment::Type GetTextAlignment() const;
-
- /**
- * @brief Sets how to split the text in lines policy.
- *
- * @param policy The multi-line policy.
- */
- void SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy );
-
- /**
- * @brief Gets the split in lines policy.
- *
- * @return The multi-line policy.
- */
- Toolkit::TextView::MultilinePolicy GetMultilinePolicy() const;
-
- /**
- * @brief Sets how to display the text inside the TextView when it exceeds the text-view's width.
- *
- * @param policy The exceed policy.
- */
- void SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy );
-
- /**
- * @brief Gets the width exceed policy.
- *
- * @return The exceed policy.
- */
- TextView::ExceedPolicy GetWidthExceedPolicy() const;
-
- /**
- * @brief Sets how to display the text inside the TextView when it exceeds the text-view's height.
- *
- * @param policy The exceed policy.
- */
- void SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy );
-
- /**
- * @brief Gets the height exceed policy.
- *
- * @return The exceed policy.
- */
- TextView::ExceedPolicy GetHeightExceedPolicy() const;
-
- /**
- * @brief Sets if the inputed text can exceed the text-input boundary.
- *
- * By default is enabled.
- *
- * @param[in] enable Whether the inputed text can exceed its boundary.
- */
- void SetExceedEnabled( bool enable );
-
- /**
- * @brief Retrieves whether inputed text can exceed the text-input boundary.
- *
- * @return \e true if text inputed can exceed the boundary, otherwise \e false.
- */
- bool GetExceedEnabled() const;
-
- /**
- * @brief Allows modification of text-actor's position in the depth sort algorithm.
- *
- * @see Dali::RenderableActor::SetSortModifier()
- * @param [in] depthOffset the offset to be given to the internal text-actors. Positive values pushing it further back.
- */
- void SetSortModifier( float depthOffset );
-
- /**
- * @brief Sets whether text-view renders text using a previously generated snapshot.
- *
- * @see TextView::SetSnapshotModeEnabled()
- *
- * @param[in] enable Whether text-view is using or not a snapshot to render text.
- */
- void SetSnapshotModeEnabled( bool enable );
-
- /**
- * @brief Retrieves whether text-view is using a snapshot to render text.
- *
- * @see TextView::IsSnapshotModeEnabled()
- *
- * @return \e true if text-view is using a snapshot to render text, otherwhise it returns \e false.
- */
- bool IsSnapshotModeEnabled() const;
-
- /**
- * @copydoc TextView::SetScrollEnabled()
- */
- void SetScrollEnabled( bool enable );
-
- /**
- * @copydoc TextView::IsScrollEnabled()
- */
- bool IsScrollEnabled() const;
-
- /**
- * @copydoc TextView::SetScrollPosition()
- */
- void SetScrollPosition( const Vector2& position );
-
- /**
- * @copydoc TextView::GetScrollPosition()
- */
- Vector2 GetScrollPosition() const;
-
- /**
- * @brief Sets whether markup processing should be carried out.
- *
- * @param[in] enable whether markup processing is carried out or not.
- */
- void SetMarkupProcessingEnabled( bool enable );
-
- /**
- * @brief Returns whether markup processing is enabled or not
- *
- * @return true is markup processing is enabled
- */
- bool IsMarkupProcessingEnabled() const;
-
-
-public: /* Signals */
-
- /// @brief Input Signal.
- typedef Signal< void ( TextInput textInput ) > InputSignalType;
-
- /// @brief Input style changed signal.
- typedef Signal< void ( TextInput textInput, const TextStyle& style ) > StyleChangedSignalType;
-
- /// @brief Text modified signal.
- typedef Signal< void ( TextInput textInput ) > TextModifiedSignalType;
-
- /// @brief Max input characters reached signal.
- typedef Signal< void ( TextInput textInput ) > MaxInputCharactersReachedSignalType;
-
- /// @brief Input text exceeds boundaries signal.
- typedef Signal< void ( TextInput textInput ) > InputTextExceedBoundariesSignalType;
-
- /**
- * @brief Signal emitted when the Text-Input starts receiving input.
- */
- InputSignalType& InputStartedSignal();
-
- /**
- * @brief Signal emitted when the Text-Input is finished receiving input.
- *
- * TextInput::GetText() can be called to get current text string.
- * @return The signal to connect to
- */
- InputSignalType& InputFinishedSignal();
-
- /**
- * @brief Signal emitted when the cut and paste toolbar is displayed.
- *
- * @return The signal to connect to
- */
- InputSignalType& CutAndPasteToolBarDisplayedSignal();
-
- /**
- * @brief Signal emitted when style changes.
- *
- * @return The signal to connect to
- */
- StyleChangedSignalType& StyleChangedSignal();
-
- /**
- * @brief Signal emitted when text changes.
- *
- * @return The signal to connect to.
- */
- TextModifiedSignalType& TextModifiedSignal();
-
- /**
- * @brief Signal emitted when max input characters are reached during text input.
- *
- * @return The signal to connect to
- */
- MaxInputCharactersReachedSignalType& MaxInputCharactersReachedSignal();
-
- /**
- * @brief Signal emitted when input text exceeds the boundaries of the text-input.
- *
- * @return The signal to connect to
- */
- InputTextExceedBoundariesSignalType& InputTextExceedBoundariesSignal();
-
-public: // Not intended for application developers
-
- /**
- * @brief Creates a handle using the Toolkit::Internal implementation.
- *
- * @param[in] implementation The Control implementation.
- */
- DALI_INTERNAL TextInput(Internal::TextInput& implementation);
-
- /**
- * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
- *
- * @param[in] internal A pointer to the internal CustomActor.
- */
- explicit DALI_INTERNAL TextInput(Dali::Internal::CustomActor* internal );
-};
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_TEXT_INPUT_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-TextView::CharacterLayoutInfo::CharacterLayoutInfo()
-: mSize(),
- mPosition(),
- mIsNewLineChar( false ),
- mIsNewParagraphChar( false ),
- mIsRightToLeftCharacter( false ),
- mIsVisible( true ),
- mDescender()
-{
-}
-
-TextView::CharacterLayoutInfo::~CharacterLayoutInfo()
-{
-}
-
-TextView::CharacterLayoutInfo::CharacterLayoutInfo( const TextView::CharacterLayoutInfo& characterLayoutInfo )
-: mSize( characterLayoutInfo.mSize ),
- mPosition( characterLayoutInfo.mPosition ),
- mIsNewLineChar( characterLayoutInfo.mIsNewParagraphChar ),
- mIsNewParagraphChar( characterLayoutInfo.mIsNewParagraphChar ),
- mIsRightToLeftCharacter( characterLayoutInfo.mIsRightToLeftCharacter ),
- mIsVisible( characterLayoutInfo.mIsVisible ),
- mDescender( characterLayoutInfo.mDescender )
-{
-}
-
-TextView::CharacterLayoutInfo& TextView::CharacterLayoutInfo::operator=( const TextView::CharacterLayoutInfo& characterLayoutInfo )
-{
- mSize = characterLayoutInfo.mSize;
- mPosition = characterLayoutInfo.mPosition;
- mIsNewLineChar = characterLayoutInfo.mIsNewParagraphChar;
- mIsNewParagraphChar = characterLayoutInfo.mIsNewParagraphChar;
- mIsRightToLeftCharacter = characterLayoutInfo.mIsRightToLeftCharacter;
- mIsVisible = characterLayoutInfo.mIsVisible;
- mDescender = characterLayoutInfo.mDescender;
-
- return *this;
-}
-
-TextView::CharacterLayoutInfo::CharacterLayoutInfo( const Size& size,
- const Vector3& position,
- bool isNewParagraphChar,
- bool isRightToLeftCharacter,
- bool isVisible,
- float descender )
-: mSize( size ),
- mPosition( position ),
- mIsNewLineChar( isNewParagraphChar ),
- mIsNewParagraphChar( isNewParagraphChar ),
- mIsRightToLeftCharacter( isRightToLeftCharacter ),
- mIsVisible( isVisible ),
- mDescender( descender )
-{
-}
-
-TextView::TextLayoutInfo::TextLayoutInfo()
-: mCharacterLayoutInfoTable(),
- mLines(),
- mCharacterLogicalToVisualMap(),
- mCharacterVisualToLogicalMap(),
- mTextSize(),
- mScrollOffset()
-{
-}
-
-TextView::TextLayoutInfo::~TextLayoutInfo()
-{
-}
-
-TextView::TextLayoutInfo::TextLayoutInfo( const TextView::TextLayoutInfo& textLayoutInfo )
-: mCharacterLayoutInfoTable( textLayoutInfo.mCharacterLayoutInfoTable ),
- mLines( textLayoutInfo.mLines ),
- mCharacterLogicalToVisualMap( textLayoutInfo.mCharacterLogicalToVisualMap ),
- mCharacterVisualToLogicalMap( textLayoutInfo.mCharacterVisualToLogicalMap ),
- mTextSize( textLayoutInfo.mTextSize ),
- mScrollOffset( textLayoutInfo.mScrollOffset )
-{
-}
-
-TextView::TextLayoutInfo& TextView::TextLayoutInfo::operator=( const TextView::TextLayoutInfo& textLayoutInfo )
-{
- mCharacterLayoutInfoTable = textLayoutInfo.mCharacterLayoutInfoTable;
- mLines = textLayoutInfo.mLines;
- mCharacterLogicalToVisualMap = textLayoutInfo.mCharacterLogicalToVisualMap;
- mCharacterVisualToLogicalMap = textLayoutInfo.mCharacterVisualToLogicalMap;
- mTextSize = textLayoutInfo.mTextSize;
- mScrollOffset = textLayoutInfo.mScrollOffset;
-
- return *this;
-}
-
-TextView::FadeBoundary::FadeBoundary()
-: mLeft( 0 ),
- mRight( 0 ),
- mTop( 0 ),
- mBottom( 0 )
-{
-}
-
-TextView::FadeBoundary::FadeBoundary( PixelSize left, PixelSize right, PixelSize top, PixelSize bottom )
-: mLeft( left ),
- mRight( right ),
- mTop( top ),
- mBottom( bottom )
-{
-}
-
-TextView::TextView()
-{
-}
-
-TextView::TextView( const TextView& handle )
-: Control( handle )
-{
-}
-
-TextView::TextView( Dali::Internal::CustomActor* internal )
-: Control( internal )
-{
- VerifyCustomActorPointer<Internal::TextView>(internal);
-}
-
-TextView& TextView::operator=( const TextView& handle )
-{
- if( &handle != this )
- {
- Control::operator=( handle );
- }
- return *this;
-}
-
-TextView TextView::New()
-{
- return Internal::TextView::New();
-}
-
-TextView TextView::New( const std::string& text )
-{
- TextView textView = Internal::TextView::New();
- textView.SetText( text );
- return textView;
-}
-
-TextView TextView::New( const MarkupProcessor::StyledTextArray& text )
-{
- TextView textView = Internal::TextView::New();
- textView.SetText( text );
- return textView;
-}
-
-TextView TextView::DownCast( BaseHandle handle )
-{
- return Control::DownCast<TextView, Internal::TextView>(handle);
-}
-
-TextView::~TextView()
-{
-}
-
-void TextView::SetText( const std::string& text )
-{
- GetImpl( *this ).SetText( text );
-}
-
-void TextView::SetText( const MarkupProcessor::StyledTextArray& text )
-{
- GetImpl( *this ).SetText( text );
-}
-
-void TextView::InsertTextAt( std::size_t position, const std::string& text )
-{
- GetImpl( *this ).InsertTextAt( position, text );
-}
-
-void TextView::InsertTextAt( std::size_t position, const MarkupProcessor::StyledTextArray& text )
-{
- GetImpl( *this ).InsertTextAt( position, text );
-}
-
-void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text )
-{
- GetImpl( *this ).ReplaceTextFromTo( position, numberOfCharacters, text );
-}
-
-void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text )
-{
- GetImpl( *this ).ReplaceTextFromTo( position, numberOfCharacters, text );
-}
-
-void TextView::RemoveTextFrom( std::size_t position, std::size_t numberOfCharacters )
-{
- GetImpl( *this ).RemoveTextFrom( position, numberOfCharacters );
-}
-
-std::string TextView::GetText() const
-{
- return GetImpl( *this ).GetText();
-}
-
-void TextView::SetLineHeightOffset( PointSize offset )
-{
- GetImpl( *this ).SetLineHeightOffset( offset );
-}
-
-PointSize TextView::GetLineHeightOffset() const
-{
- return GetImpl( *this ).GetLineHeightOffset();
-}
-
-void TextView::SetStyleToCurrentText( const TextStyle& style, TextStyle::Mask mask )
-{
- GetImpl( *this ).SetStyleToCurrentText( style, mask );
-}
-
-void TextView::SetTextAlignment( Alignment::Type align )
-{
- GetImpl( *this ).SetTextAlignment( align );
-}
-
-Alignment::Type TextView::GetTextAlignment() const
-{
- return GetImpl( *this ).GetTextAlignment();
-}
-
-void TextView::SetMultilinePolicy( TextView::MultilinePolicy policy )
-{
- GetImpl( *this ).SetMultilinePolicy( policy );
-}
-
-TextView::MultilinePolicy TextView::GetMultilinePolicy() const
-{
- return GetImpl( *this ).GetMultilinePolicy();
-}
-
-void TextView::SetWidthExceedPolicy( TextView::ExceedPolicy policy )
-{
- GetImpl( *this ).SetWidthExceedPolicy( policy );
-}
-
-TextView::ExceedPolicy TextView::GetWidthExceedPolicy() const
-{
- return GetImpl( *this ).GetWidthExceedPolicy();
-}
-
-void TextView::SetHeightExceedPolicy( ExceedPolicy policy )
-{
- GetImpl( *this ).SetHeightExceedPolicy( policy );
-}
-
-TextView::ExceedPolicy TextView::GetHeightExceedPolicy() const
-{
- return GetImpl( *this ).GetHeightExceedPolicy();
-}
-
-void TextView::SetLineJustification( TextView::LineJustification justification )
-{
- GetImpl( *this ).SetLineJustification( justification );
-}
-
-TextView::LineJustification TextView::GetLineJustification() const
-{
- return GetImpl( *this ).GetLineJustification();
-}
-
-void TextView::SetFadeBoundary( const TextView::FadeBoundary& fadeBoundary )
-{
- GetImpl( *this ).SetFadeBoundary( fadeBoundary );
-}
-
-const TextView::FadeBoundary& TextView::GetFadeBoundary() const
-{
- return GetImpl( *this ).GetFadeBoundary();
-}
-
-void TextView::SetEllipsizeText( const std::string& ellipsizeText )
-{
- GetImpl( *this ).SetEllipsizeText( ellipsizeText );
-}
-
-void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText )
-{
- GetImpl( *this ).SetEllipsizeText( ellipsizeText );
-}
-
-std::string TextView::GetEllipsizeText() const
-{
- return GetImpl( *this ).GetEllipsizeText();
-}
-
-void TextView::GetTextLayoutInfo( TextLayoutInfo& textLayoutInfo )
-{
- GetImpl( *this ).GetTextLayoutInfo( textLayoutInfo );
-}
-
-void TextView::SetSortModifier( float depthOffset )
-{
- GetImpl( *this ).SetSortModifier( depthOffset );
-}
-
-void TextView::SetSnapshotModeEnabled( bool enable )
-{
- GetImpl( *this ).SetSnapshotModeEnabled( enable );
-}
-
-bool TextView::IsSnapshotModeEnabled() const
-{
- return GetImpl( *this ).IsSnapshotModeEnabled();
-}
-
-void TextView::SetScrollEnabled( bool enable )
-{
- GetImpl( *this ).SetScrollEnabled( enable );
-}
-
-bool TextView::IsScrollEnabled() const
-{
- return GetImpl( *this ).IsScrollEnabled();
-}
-
-void TextView::SetScrollPosition( const Vector2& position )
-{
- GetImpl( *this ).SetScrollPosition( position );
-}
-
-const Vector2& TextView::GetScrollPosition() const
-{
- return GetImpl( *this ).GetScrollPosition();
-}
-
-bool TextView::IsScrollPositionTrimmed() const
-{
- return GetImpl( *this ).IsScrollPositionTrimmed();
-}
-
-TextView::ScrolledSignalType& TextView::ScrolledSignal()
-{
- return GetImpl( *this ).ScrolledSignal();
-}
-
-void TextView::SetMarkupProcessingEnabled( bool enable )
-{
- return GetImpl( *this ).SetMarkupProcessingEnabled( enable );
-}
-
-bool TextView::IsMarkupProcessingEnabled() const
-{
- return GetImpl( *this ).IsMarkupProcessingEnabled();
-}
-
-TextView::TextView( Internal::TextView& implementation )
-: Control( implementation )
-{
-}
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_TEXT_VIEW_H__
-#define __DALI_TOOLKIT_TEXT_VIEW_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <string>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/alignment/alignment.h>
-#include <dali-toolkit/public-api/markup-processor/markup-processor.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal DALI_INTERNAL
-{
-class TextView;
-}
-
-/**
- * @brief The TextView class is a UI Dali::Toolkit::Control designed to extend the capabilities of the basic Dali::TextActor.
- *
- * It provides support for multi-line wrapping, multi-language font detection, text alignment, scrolling and styling.
- *
- * See the \link text-view Text View \endlink page of the Programming Guide for more details and examples.
- *
- * Signals
- * | %Signal Name | Method |
- * |-------------------|---------------------------|
- * | scrolled | @ref ScrolledSignal() |
- */
-class DALI_IMPORT_API TextView : public Control
-{
-public:
-
- // Properties
- static const Dali::Property::Index PROPERTY_MARKUP_ENABLED; ///< name "markup-enabled", @see SetMarkupProcessingEnabled(), type BOOLEAN
- static const Dali::Property::Index PROPERTY_TEXT; ///< name "text", @see SetText(), type STRING
- static const Dali::Property::Index PROPERTY_MULTILINE_POLICY; ///< name "multiline-policy", @see SetMultilinePolicy(), type STRING
- static const Dali::Property::Index PROPERTY_WIDTH_EXCEED_POLICY; ///< name "width-exceed-policy", @see SetWidthExceedPolicy(), type STRING
- static const Dali::Property::Index PROPERTY_HEIGHT_EXCEED_POLICY; ///< name "height-exceed-policy", @see SetHeightExceedPolicy(), type STRING
- static const Dali::Property::Index PROPERTY_LINE_JUSTIFICATION; ///< name "line-justification", @see SetLineJustification(), type STRING
- static const Dali::Property::Index PROPERTY_FADE_BOUNDARY; ///< name "fade-boundary", @see SetFadeBoundary(), type VECTOR4
- static const Dali::Property::Index PROPERTY_LINE_HEIGHT_OFFSET; ///< name "line-height-offset", @see SetLineHeightOffset(), type FLOAT
- static const Dali::Property::Index PROPERTY_HORIZONTAL_ALIGNMENT; ///< name "horizontal-alignment", @see SetTextAlignment(), type STRING
- static const Dali::Property::Index PROPERTY_VERTICAL_ALIGNMENT; ///< name "vertical-alignment", @see SetTextAlignment(), type STRING
-
- /**
- * @brief Structure used to retrieve Layout info per character.
- */
- struct CharacterLayoutInfo
- {
- /**
- * @brief Default constructor.
- *
- * Initializes all members to their default values.
- */
- CharacterLayoutInfo();
-
- /**
- * @brief Empty destructor.
- *
- * @note Added to increase coverage.
- */
- ~CharacterLayoutInfo();
-
- /**
- * @brief Copy constructor.
- */
- CharacterLayoutInfo( const CharacterLayoutInfo& characterLayoutInfo );
-
- /**
- * @brief Assignment operator.
- */
- CharacterLayoutInfo& operator=( const CharacterLayoutInfo& character );
-
- /**
- * @brief Constructor.
- *
- * @param[in] size of the character.
- * @param[in] position of the character.
- * @param[in] isNewParagraphChar Whether the character is a new paragraph character.
- * @param[in] isRightToLeftCharacter Whether is a right to left character.
- * @param[in] visible Whether is visible.
- * @param[in] descender of the character (distance from the base line to the bottom of the character.)
- */
- CharacterLayoutInfo( const Size& size,
- const Vector3& position,
- bool isNewParagraphChar,
- bool isRightToLeftCharacter,
- bool visible,
- float descender );
-
- Size mSize; ///< Size of the character.
- Vector3 mPosition; ///< Position of the character within the text view.
- bool mIsNewLineChar:1; ///< @deprecated. Use mIsNewParagraphChar instead.
- bool mIsNewParagraphChar:1; ///< Whether this character represent a new paragraph.
- bool mIsRightToLeftCharacter:1; ///< Whether it's a right-to-left character.
- bool mIsVisible:1; ///< Whether this character is visible or not.
- float mDescender; ///< The character's descender which is the distance from the baseline to the bottom of the character
- };
-
- typedef std::vector<CharacterLayoutInfo> CharacterLayoutInfoContainer; ///< Container of layout info per character.
-
- /**
- * @brief Stores some info about a line.
- */
- struct LineLayoutInfo
- {
- std::size_t mCharacterGlobalIndex; ///< Global index within the whole text of the first character of current line.
- Size mSize; ///< Size of the current line.
- float mAscender; ///< The max ascender of the current line.
- };
-
- typedef std::vector<LineLayoutInfo> LineLayoutInfoContainer; ///< Container of layout info per line.
-
- /**
- * @brief How text is laid out.
- */
- struct TextLayoutInfo
- {
- /**
- * @brief Default constructor.
- */
- TextLayoutInfo();
-
- /**
- * @brief Empty destructor.
- *
- * @note Added to increase coverage.
- */
- ~TextLayoutInfo();
-
- /**
- * @brief Copy constructor.
- */
- TextLayoutInfo( const TextLayoutInfo& textLayoutInfo );
-
- /**
- * @brief Assignment operator.
- */
- TextLayoutInfo& operator=( const TextLayoutInfo& textLayoutInfo );
-
- CharacterLayoutInfoContainer mCharacterLayoutInfoTable; ///< The table of character's positions and sizes sorted by the character's visual index.
- LineLayoutInfoContainer mLines; ///< For each line, it stores an index to the first character of the line.
- std::vector<int> mCharacterLogicalToVisualMap; ///< The map to store the character's logical (input) index according to its visual (reordered) index.
- std::vector<int> mCharacterVisualToLogicalMap; ///< The map to store the character's visual (reordered) index according to its logical (input) index.
- Size mTextSize; ///< Text size after relayout.
- Vector2 mScrollOffset; ///< Scroll's position.
- };
-
- /**
- * @brief This structure represents a fade boundary.
- *
- * If the Exceed policy is set to Fade all text which does not fit within the text-view fade boundary is faded out. Text which exceeds the text-view boundary becomes invisible.
- * The \e left, \e right, \e top and \e bottom values are positive, in pixels and set the distances between the text-view and fade boundaries.
- */
- struct FadeBoundary
- {
- /**
- * @brief Default constructor.
- *
- * Initializes all values to 0. It means no fade boundary.
- */
- FadeBoundary();
-
- /**
- * @brief Constructor.
- *
- * Initializes the fade boundary with the given values.
- *
- * @param[in] left value in pixels.
- * @param[in] right value in pixels.
- * @param[in] top value in pixels.
- * @param[in] bottom value in pixels.
- */
- FadeBoundary( PixelSize left, PixelSize right, PixelSize top, PixelSize bottom );
-
- PixelSize mLeft; ///< The left fade boundary
- PixelSize mRight; ///< The right fade boundary
- PixelSize mTop; ///< The top fade boundary
- PixelSize mBottom; ///< The bottom fade bounday
- };
-
- /**
- * @brief Define how to wrap the text's paragraphs in lines.
- *
- * \e SplitByNewLineChar will wrap the text's paragraphs in lines when a '\\n' character or a \<br /\> is found.
- * \e SplitByWord has effect only when TextView size is assigned.
- * It will wrap the text's paragraphs in lines when a '\\n' character or a \<br /\> is found or if a paragraph exceeds the TextView's boundary. This option won't split a word in two.
- * \e SplitByChar has effect only when TextView size is assigned.
- * It will wrap the text's paragraphs in lines when a '\\n' character or a \<br /\> is found or if a paragraph exceeds the TextView's boundary. This option might split a word in two.
- * The default value is \e SplitByNewLineChar.
- */
- enum MultilinePolicy
- {
- SplitByNewLineChar, ///< Text's paragraphs will wrap in lines when '\\n' character is found.
- SplitByWord, ///< Text's paragraphs will wrap in lines by word or if '\\n' character is found. It has effect only when TextView size is assigned.
- SplitByChar ///< Text's paragraphs will wrap in lines by char or if '\\n' character is found. It has effect only when TextView size is assigned.
- };
-
- /**
- * @brief Define how to display the lines when they doesn't fit inside the TextView after the text's paragraphs are wrapped in lines.
- *
- * The default value is \e Original.
- */
- enum ExceedPolicy
- {
- Original, ///< Will display the lines in their original size. If a line, a word or a character is bigger than the TextView size it may exceed its boundary.
- Fade, ///< Will display the lines in their original size. It won't display the part of the line which exceeds the TextView boundary. It fades the text out.
- Split, ///< Will split the lines in a new line(s).
- ShrinkToFit, ///< Will shrink the lines to fit the TextView boundary.
- EllipsizeEnd ///< Will ellipsize the lines by the end.
- };
-
- /**
- * @brief Define how to justify lines inside the text's boundary.
- *
- * The default value is \e Left.
- */
- enum LineJustification
- {
- Left, ///< Justify to the left.
- Center, ///< Centered.
- Right, ///< Justify to the right.
- Justified ///< Line justified.
- };
-
-public:
- /**
- * @brief Create a TextView handle; this can be initialised with TextView::New().
- *
- * Calling member functions with an uninitialised Dali::Object handle is not allowed.
- */
- TextView();
-
- /**
- * @brief Copy constructor.
- *
- * Creates another handle that points to the same real object
- * @param[in] handle The handle to copy from
- */
- TextView( const TextView& handle );
-
- /**
- * @brief Assignment operator.
- *
- * Changes this handle to point to another real object
- * @param[in] handle The handle to copy from
- * @return a reference to this
- */
- TextView& operator=( const TextView& handle );
-
- /**
- * @brief Create a TextView control with no text.
- *
- * @return A handle the TextView control.
- */
- static TextView New();
-
- /**
- * @brief Create a TextView control.
- *
- * @param[in] text to display.
- * @return A handle the TextView control.
- */
- static TextView New( const std::string& text );
-
- /**
- * @brief Create a TextView control with styled text.
- *
- * @param[in] text The text with style to display.
- * @return A handle the TextView control.
- */
- static TextView New( const MarkupProcessor::StyledTextArray& text );
-
- /**
- * @brief Downcast an Object handle to TextView.
- *
- * If handle points to a TextView the
- * downcast produces valid handle. If not the returned handle is left uninitialized.
- * @param[in] handle Handle to an object
- * @return handle to a TextView or an uninitialized handle
- */
- static TextView DownCast( BaseHandle handle );
-
- /**
- * @brief Destructor
- *
- * This is non-virtual since derived Handle types must not contain data or virtual methods.
- */
- ~TextView();
-
- /**
- * @brief Replace the current text with a new text string.
- *
- * @param[in] text to display. The string may contain style tags.
- */
- void SetText( const std::string& text );
-
- /**
- * @brief Replace the current text with a new text string with style.
- *
- * @param[in] text The text with style to display.
- */
- void SetText( const MarkupProcessor::StyledTextArray& text );
-
- /**
- * @brief Inserts the given text in the specified position.
- *
- * @param[in] position Where the given text is going to be added.
- * @param[in] text The text to be added.
- */
- void InsertTextAt( std::size_t position, const std::string& text );
-
- /**
- * @brief Inserts the given text with style in the specified position.
- *
- * @param[in] position Where the given text is going to be added.
- * @param[in] text The text with style to be added.
- */
- void InsertTextAt( std::size_t position, const MarkupProcessor::StyledTextArray& text );
-
- /**
- * @brief Replaces part of the text.
- *
- * It removes the specified number of characters from the given position and inserts the given text in the same specified position.
- *
- * @param[in] position of the first character to be removed and Where the given text is going to be added.
- * @param[in] numberOfCharacters number of characters to be removed.
- * @param[in] text The text to be added.
- */
- void ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text );
-
- /**
- * @brief Replaces part of the text.
- *
- * It removes the specified number of characters from the given position and inserts the given text with style in the same specified position.
- *
- * @param[in] position of the first character to be removed and Where the given text is going to be added.
- * @param[in] numberOfCharacters number of characters to be removed.
- * @param[in] text The text with style to be added.
- */
- void ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text );
-
- /**
- * @brief Removes the specified number of characters from the given position.
- *
- * @param[in] position of the first character to be removed.
- * @param[in] numberOfCharacters number of characters to be removed.
- */
- void RemoveTextFrom( std::size_t position, std::size_t numberOfCharacters );
-
- /**
- * @brief Get the currently displayed text.
- *
- * @return The currently displayed text.
- */
- std::string GetText() const;
-
- /**
- * @brief Sets a line height offset.
- *
- * The line height offset will be added to the font line height.
- * @param [in] offset The height offset in PointSize units.
- */
- void SetLineHeightOffset( PointSize offset );
-
- /**
- * @brief Retrieves the line height offset.
- *
- * @return The line height offset in PointSize units.
- */
- PointSize GetLineHeightOffset() const;
-
- /**
- * @brief Sets the given style to the current text.
- *
- * By default all style settings are applied but a bit mask could be used to modify only certain style settings.
- * @note TextView doesn't store a copy of the given style, it applies the given style to the current text only.
- * Subsequent calls to SetText() will override any style set by this method.
- * @param[in] style The given style
- * @param[in] mask The bit mask.
- */
- void SetStyleToCurrentText( const TextStyle& style, TextStyle::Mask mask = TextStyle::ALL );
-
- /**
- * @brief Set the current text alignment.
- *
- * Default alignment is (HorizontalCenter | VerticalCenter)
- * @param[in] align The new alignment option.
- */
- void SetTextAlignment( Alignment::Type align );
-
- /**
- * @brief Get the current text alignment combined into a single value.
- *
- * The values can be tested by using the & operator
- * and the desired flag. e.g. if (GetTextAlignment() & HorizontalCentre) ...
- * @return the combined alignment
- */
- Alignment::Type GetTextAlignment() const;
-
- /**
- * @brief Sets how to split the paragraphs into lines.
- *
- * @param policy The multi-line policy. \e SplitByNewLineChar is set by default.
- */
- void SetMultilinePolicy( MultilinePolicy policy );
-
- /**
- * @brief Gets the wrap in lines policy.
- *
- * @return The multi-line policy.
- */
- MultilinePolicy GetMultilinePolicy() const;
-
- /**
- * @brief Sets how to display the text inside the TextView when it exceeds the text-view's width.
- *
- * @param policy The exceed policy. Original is set by default.
- */
- void SetWidthExceedPolicy( ExceedPolicy policy );
-
- /**
- * @brief Gets the width exceed policy.
- *
- * @return The exceed policy.
- */
- ExceedPolicy GetWidthExceedPolicy() const;
-
- /**
- * @brief Sets how to display the text inside the TextView when it exceeds the text-view's height.
- *
- * @param policy The exceed policy. Original is set by default.
- */
- void SetHeightExceedPolicy( ExceedPolicy policy );
-
- /**
- * @brief Gets the height exceed policy.
- *
- * @return The exceed policy.
- */
- ExceedPolicy GetHeightExceedPolicy() const;
-
- /**
- * @brief Sets how to justify lines inside the text's boundary.
- *
- * @param justification The line justification. Left is set by default.
- */
- void SetLineJustification( LineJustification justification );
-
- /**
- * @brief Gets the line justification.
- *
- * @return The line justification.
- */
- LineJustification GetLineJustification() const;
-
- /**
- * @brief Sets a fade boundary.
- *
- * @see FadeBoundary.
- *
- * @param[in] fadeBoundary The given fade boundary.
- */
- void SetFadeBoundary( const FadeBoundary& fadeBoundary );
-
- /**
- * @brief Retrieves the fade boundary.
- *
- * @see FadeBoundary.
- *
- * @return The fade boundary.
- */
- const FadeBoundary& GetFadeBoundary() const;
-
- /**
- * @brief Sets the ellipsize text.
- *
- * @param[in] ellipsizeText The new text. The string may contain style tags. By default the ellipsize text is '...'
- */
- void SetEllipsizeText( const std::string& ellipsizeText );
-
- /**
- * @brief Sets the ellipsize text with style.
- *
- * @param[in] ellipsizeText The new text with its style.
- */
- void SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText );
-
- /**
- * @brief Retrieves the ellipsize text.
- *
- * @return The ellipsize text.
- */
- std::string GetEllipsizeText() const;
-
- /**
- * @brief A mechanism to retrieve layout information from the TextView.
- *
- * It produces a vector of CharcterLayoutInfo structures which describe the size and position of each character,
- * two vectors which maps the logical and visual positions of the characters in a bidirectional text, the size
- * of the whole laid-out text and the scroll offset value.
- *
- * @see TextLayoutInfo.
- *
- * @param[out] textLayoutInfo A structure with text layout information.
- */
- void GetTextLayoutInfo( TextLayoutInfo& textLayoutInfo );
-
- /**
- * @brief Allows modification of text-actor's position in the depth sort algorithm.
- *
- * @see Dali::RenderableActor::SetSortModifier()
- * @param [in] depthOffset the offset to be given to the internal text-actors. Positive values pushing it further back.
- */
- void SetSortModifier( float depthOffset );
-
- /**
- * @brief Sets whether text-view renders text using a previously generated snapshot.
- *
- * Rendering long text using a snapshot may increase performance. The default value is \e false (render without using a snapshot).
- *
- * @param[in] enable Whether text-view is using a snapshot to render text.
- */
- void SetSnapshotModeEnabled( bool enable );
-
- /**
- * @brief Retrieves whether text-view is using a snapshot to render text.
- *
- * @return \e true if text-view is using a snapshot to render text, otherwhise it returns \e false.
- */
- bool IsSnapshotModeEnabled() const;
-
- /**
- * @brief Sets whether markup processing should be carried out.
- *
- * To use markup, applications need to SetMarkupProcessingEnabled first, then SetText().
- *
- * @see SetText()
- * @param[in] enable whether markup processing is carried out or not.
- */
- void SetMarkupProcessingEnabled( bool enable );
-
- /**
- * @brief Retrieves whether text-view is processing markup text
- *
- * @return \e true if text-view markup processing is enabled, otherwhise it returns \e false.
- */
- bool IsMarkupProcessingEnabled() const;
-
- /**
- * @brief Enables or disables the text scroll.
- *
- * When scroll is enabled, snapshot mode will be enabled automatically. Equally, if scroll is disabled
- * the snapshot mode is restored to the previous value.
- *
- * @param[in] enable Whether to enable the text scroll.
- */
- void SetScrollEnabled( bool enable );
-
- /**
- * @brief Retrieves whether the text scroll is enabled.
- *
- * @return \e true if the scroll is enabled.
- */
- bool IsScrollEnabled() const;
-
- /**
- * @brief Sets a new scroll position.
- *
- * The new scroll position set could be trimmed if the text doesn't cover the whole text-view.
- * i.e. If a text-view is 100x100 and a text is 200x100 a scroll position beyond 50x0 will be trimmed to 50x0.
- *
- * Call IsScrollPositionTrimmed() to know if the last scroll position set has been trimmed.
- *
- * A signal is emitted. @see ScrolledSignal().
- *
- * @param[in] position The new scroll position.
- */
- void SetScrollPosition( const Vector2& position );
-
- /**
- * @brief Recrieves current scroll position.
- *
- * @return The scroll position.
- */
- const Vector2& GetScrollPosition() const;
-
- /**
- * @brief Whether the last scroll position set was trimmed.
- *
- * @return \e true if the last scroll position set was trimmed, otherwise \e false.
- */
- bool IsScrollPositionTrimmed() const;
-
-public:
- /// @brief Signal types
- typedef Signal< void ( TextView textView, Vector2 scrollDelta ) > ScrolledSignalType;
-
- /**
- * @brief Signal emitted when the text is scrolled inside the text-view.
- *
- * A callback with the following prototype can be connected to this signal.
- *
- * Callback(TextView textView, Vector2 scrollDelta)
- *
- * \e textView is the handle of the text-view emitting the signal.
- * \e scrollDelta is the differente of the current scroll position with the previous one.
- * @return The signal to connect to
- */
- ScrolledSignalType& ScrolledSignal();
-
-public: // Not intended for application developers
-
- /**
- * @brief Creates a handle using the Toolkit::Internal implementation.
- * @note Not intended for application developers
- *
- * @param[in] implementation The Control implementation.
- */
- DALI_INTERNAL TextView( Internal::TextView& implementation );
-
- /**
- * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
- * @note Not intended for application developers
- *
- * @param[in] internal A pointer to the internal CustomActor.
- */
- explicit DALI_INTERNAL TextView( Dali::Internal::CustomActor* internal );
-};
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_ITEM_VIEW_H__
$(public_api_src_dir)/controls/slider/slider.cpp \
$(public_api_src_dir)/controls/super-blur-view/super-blur-view.cpp \
$(public_api_src_dir)/controls/table-view/table-view.cpp \
- $(public_api_src_dir)/controls/text-input/text-input.cpp \
- $(public_api_src_dir)/controls/text-view/text-view.cpp \
+ $(public_api_src_dir)/controls/text-controls/text-label.cpp \
+ $(public_api_src_dir)/controls/text-controls/text-field.cpp \
$(public_api_src_dir)/controls/tool-bar/tool-bar.cpp \
$(public_api_src_dir)/controls/bloom-view/bloom-view.cpp \
$(public_api_src_dir)/controls/cluster/cluster-style.cpp \
$(public_api_src_dir)/focus-manager/focus-manager.cpp \
$(public_api_src_dir)/focus-manager/keyboard-focus-manager.cpp \
$(public_api_src_dir)/focus-manager/keyinput-focus-manager.cpp \
- $(public_api_src_dir)/markup-processor/markup-processor.cpp \
$(public_api_src_dir)/shader-effects/bubble-effect/bubble-effect.cpp \
$(public_api_src_dir)/shader-effects/bubble-effect/color-adjuster.cpp \
$(public_api_src_dir)/shader-effects/alpha-discard-effect.cpp \
$(public_api_src_dir)/shader-effects/swirl-effect.cpp \
$(public_api_src_dir)/shader-effects/water-effect.cpp \
$(public_api_src_dir)/styling/style-manager.cpp \
+ $(public_api_src_dir)/text/bidirectional-support.cpp \
+ $(public_api_src_dir)/text/character-set-conversion.cpp \
+ $(public_api_src_dir)/text/logical-model.cpp \
+ $(public_api_src_dir)/text/multi-language-support.cpp \
+ $(public_api_src_dir)/text/text-script.cpp \
+ $(public_api_src_dir)/text/segmentation.cpp \
+ $(public_api_src_dir)/text/shaper.cpp \
+ $(public_api_src_dir)/text/text-control-interface.cpp \
+ $(public_api_src_dir)/text/text-controller.cpp \
+ $(public_api_src_dir)/text/text-view.cpp \
+ $(public_api_src_dir)/text/text-view-interface.cpp \
+ $(public_api_src_dir)/text/visual-model.cpp \
+ $(public_api_src_dir)/text/decorator/text-decorator.cpp \
+ $(public_api_src_dir)/text/layouts/layout-engine.cpp \
+ $(public_api_src_dir)/text/rendering/text-backend.cpp \
+ $(public_api_src_dir)/text/rendering/text-renderer.cpp \
+ $(public_api_src_dir)/text/rendering/basic/text-basic-renderer.cpp \
+ $(public_api_src_dir)/text/rendering/shaders/text-basic-shader.cpp \
$(public_api_src_dir)/transition-effects/cube-transition-cross-effect.cpp \
$(public_api_src_dir)/transition-effects/cube-transition-effect.cpp \
$(public_api_src_dir)/transition-effects/cube-transition-fold-effect.cpp \
public_api_table_view_header_files = \
$(public_api_src_dir)/controls/table-view/table-view.h
+public_api_text_controls_header_files = \
+ $(public_api_src_dir)/controls/text-controls/text-label.h \
+ $(public_api_src_dir)/controls/text-controls/text-field.h
+
+public_api_text_header_files = \
+ $(public_api_src_dir)/text/bidirectional-line-info-run.h \
+ $(public_api_src_dir)/text/bidirectional-paragraph-info-run.h \
+ $(public_api_src_dir)/text/bidirectional-support.h \
+ $(public_api_src_dir)/text/character-run.h \
+ $(public_api_src_dir)/text/character-set-conversion.h \
+ $(public_api_src_dir)/text/font-run.h \
+ $(public_api_src_dir)/text/line-run.h \
+ $(public_api_src_dir)/text/logical-model.h \
+ $(public_api_src_dir)/text/multi-language-support.h \
+ $(public_api_src_dir)/text/script.h \
+ $(public_api_src_dir)/text/script-run.h \
+ $(public_api_src_dir)/text/segmentation.h \
+ $(public_api_src_dir)/text/shaper.h \
+ $(public_api_src_dir)/text/text-control-interface.h \
+ $(public_api_src_dir)/text/text-controller.h \
+ $(public_api_src_dir)/text/text-definitions.h \
+ $(public_api_src_dir)/text/text-view.h \
+ $(public_api_src_dir)/text/text-view-interface.h \
+ $(public_api_src_dir)/text/visual-model.h
+
+public_api_text_decorator_header_files = \
+ $(public_api_src_dir)/text/decorator/text-decorator.h
+
+public_api_text_layouts_header_files = \
+ $(public_api_src_dir)/text/layouts/layout-engine.h
+
+public_api_text_rendering_header_files = \
+ $(public_api_src_dir)/text/rendering/text-backend.h \
+ $(public_api_src_dir)/text/rendering/text-renderer.h
+
+public_api_text_rendering_basic_header_files = \
+ $(public_api_src_dir)/text/rendering/basic/text-basic-renderer.h
+
+public_api_text_rendering_shaders_header_files = \
+ $(public_api_src_dir)/text/rendering/shaders/text-basic-shader.h
+
public_api_text_input_header_files = \
$(public_api_src_dir)/controls/text-input/text-input.h
$(public_api_src_dir)/focus-manager/keyboard-focus-manager.h \
$(public_api_src_dir)/focus-manager/keyinput-focus-manager.h
-public_api_markup_processor_header_files = \
- $(public_api_src_dir)/markup-processor/markup-processor.h
-
public_api_shader_effects_header_files = \
$(public_api_src_dir)/shader-effects/alpha-discard-effect.h \
$(public_api_src_dir)/shader-effects/bendy-effect.h \
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// HEADER INCLUDE
-#include <dali-toolkit/public-api/markup-processor/markup-processor.h>
-
-// EXTERNAL INCLUDES
-#include <stack>
-#include <sstream>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace MarkupProcessor
-{
-
-namespace
-{
-const std::string WEB_COLOR_TOKEN( "#" );
-const std::string HEX_COLOR_TOKEN( "0x" );
-const std::string ALPHA_ONE( "FF" );
-
-const std::string BLACK_COLOR( "black" );
-const std::string WHITE_COLOR( "white" );
-const std::string RED_COLOR( "red" );
-const std::string GREEN_COLOR( "green" );
-const std::string BLUE_COLOR( "blue" );
-const std::string YELLOW_COLOR( "yellow" );
-const std::string MAGENTA_COLOR( "magenta" );
-const std::string CYAN_COLOR( "cyan" );
-const std::string TRANSPARENT_COLOR( "transparent" );
-
-const std::string XHTML_B_TAG("b");
-const std::string XHTML_I_TAG("i");
-const std::string XHTML_U_TAG("u");
-const std::string XHTML_BR_TAG("br");
-const std::string XHTML_FONT_TAG("font");
-const std::string XHTML_SHADOW_TAG("shadow");
-const std::string XHTML_GLOW_TAG("glow");
-const std::string XHTML_OUTLINE_TAG("outline");
-const std::string XHTML_SMOOTH_EDGE_TAG("smooth");
-const std::string XHTML_SIZE_PROPERTY("size");
-const std::string XHTML_COLOR_PROPERTY("color");
-const std::string XHTML_FACE_PROPERTY("face");
-const std::string XHTML_STYLE_PROPERTY("style");
-const std::string XHTML_PARAM_PROPERTY("param");
-const std::string XHTML_PARAM_X_PROPERTY("paramx");
-const std::string XHTML_PARAM_Y_PROPERTY("paramy");
-
-const char LESS_THAN( '<' );
-const char GREATER_THAN( '>' );
-const char EQUAL( '=' );
-const char QUOTATION_MARK( '\'');
-const char LINE_SEPARATOR_CR( 0x0D ); // Carriage return character CR
-const char LINE_SEPARATOR_LF( 0x0A ); // New line character LF
-const char SLASH( '/' );
-const char BACK_SLASH( '\\' );
-
-const std::string LINE_SEPARATOR_LF_STRING(1 , LINE_SEPARATOR_LF); ///< a string with 1 line separator character
-/**
- * Stores a property pair: name, value.
- */
-struct Property
-{
- Property( const std::string& n, const std::string& v )
- : name( n ),
- value( v )
- {}
-
- std::string name;
- std::string value;
-};
-
-
-/**
- * Compare if two strings are equal.
- *
- * The comparison is case insensitive.
- *
- * @param[in] string1 First of the two strings to be compared.
- * @param[in] string2 Second of the strings to be compared.
- *
- * @return \e true if both strings are equal (case insensitive).
- */
-bool CaseInsensitiveComparison( const std::string& string1, const std::string& string2 )
-{
- const std::size_t stringSize = string1.size();
- if( stringSize != string2.size() )
- {
- // Early return. Strings have different sizes.
- return false;
- }
-
- bool equal = true;
- for( std::size_t index = 0; equal && ( index < stringSize ); ++index )
- {
- if( std::toupper( *( string1.begin() + index ) ) != std::toupper( *( string2.begin() + index ) ) )
- {
- equal = false;
- }
- }
-
- return equal;
-}
-
-/**
- * Converts a string into a float value.
- * @param[in] floatStr A float packed inside a string.
- * @return The float value.
- */
-float StringToFloat( const std::string& floatStr )
-{
- float ret = 0.f;
-
- std::istringstream( floatStr ) >> ret;
-
- return ret;
-}
-
-/**
- * Converts a float into a string.
- * @param[in] value. A float.
- * @return The float packed into a string.
- */
-std::string FloatToString( float value )
-{
- std::ostringstream stream;
- stream << value;
-
- return stream.str();
-}
-
-/**
- * Converts a string into an hexadecimal unsigned int.
- * @param[in] uintStr An hexadecimal unsigned int packed inside a string.
- * @return The hexadecimal value.
- */
-unsigned int StringToHex( const std::string& uintStr )
-{
- unsigned int ret = 0;
-
- std::string str( uintStr );
- if( uintStr.size() <= 8 )
- {
- str.insert( 2, std::string( "ff" ) );
- }
-
- std::istringstream( str ) >> std::hex >> ret;
-
- return ret;
-}
-
-/**
- * Converts an hexadecimal value into a string.
- * @param[in] value. An hexadecimal value.
- * @return The hexadecimal value packed inside a string.
- */
-std::string HexToString( unsigned int value )
-{
- std::ostringstream stream;
- stream << std::hex << value;
- return stream.str();
-}
-
-/**
- * Converts an ARGB color packed in 4 byte unsigned int into a Vector4 color used in Dali.
- * @param[in] color An ARGB color packed in an unsigned int.
- * @param[out] retColor A Vector4 with the converted color.
- */
-void UintColorToVector4( unsigned int color, Vector4& retColor )
-{
- retColor.a = static_cast<float>( ( color & 0xFF000000 ) >> 24 ) / 255.f;
- retColor.r = static_cast<float>( ( color & 0x00FF0000 ) >> 16 ) / 255.f;
- retColor.g = static_cast<float>( ( color & 0x0000FF00 ) >> 8 ) / 255.f;
- retColor.b = static_cast<float>( color & 0x000000FF ) / 255.f;
-}
-
-/**
- * Converts an ARGB Vector4 color into a 4 byte packed inside an unsigned int.
- * @param[in] color A Vector4 with an ARGB color.
- * @return An unsigned int with the converted color.
- */
-unsigned int Vector4ColorToUint( const Vector4& color )
-{
- unsigned int retColor = 0;
-
- retColor = static_cast<unsigned int>( color.a * 255.f ) << 24;
- retColor += static_cast<unsigned int>( color.r * 255.f ) << 16;
- retColor += static_cast<unsigned int>( color.g * 255.f ) << 8;
- retColor += static_cast<unsigned int>( color.b * 255.f );
-
- return retColor;
-}
-
-/**
- * Converts a color packed inside a string into an ARGB Vector4 color.
- * The string color could be in hexadecimal ( 0xFF0000FF ), webcolor ( #0000FF or #00F ) or some constant values:
- * black, white, red, green, blue, yellow, magenta, cyan, transparent.
- * @param[in] colorStr A color packed inside a string..
- * @param[out] retColor A color packed inside a Vector4.
- */
-void ColorStringToVector4( const std::string& colorStr, Vector4& retColor )
-{
- std::string subStr1 = colorStr.substr( 0, 1 );
- std::string subStr2 = colorStr.substr( 0, 2 );
-
- if( WEB_COLOR_TOKEN == subStr1 )
- {
- std::string webColor( colorStr.begin() + 1, colorStr.end() );
- if( 3 == webColor.size() ) // 3 component web color #F00 (red)
- {
- webColor.insert( 2, &( webColor[2] ), 1 );
- webColor.insert( 1, &( webColor[1] ), 1 );
- webColor.insert( 0, &( webColor[0] ), 1 );
- webColor.insert( 0, ALPHA_ONE );
- }
- else if( 6 == webColor.size() ) // 6 component web color #FF0000 (red)
- {
- webColor.insert( 0, ALPHA_ONE );
- }
- webColor.insert( 0, HEX_COLOR_TOKEN );
-
- UintColorToVector4( StringToHex( webColor ), retColor );
- }
- else if( CaseInsensitiveComparison( HEX_COLOR_TOKEN, subStr2 ) )
- {
- UintColorToVector4( StringToHex( colorStr ), retColor );
- }
- else if( CaseInsensitiveComparison( BLACK_COLOR, colorStr ) )
- {
- retColor = Color::BLACK;
- }
- else if( CaseInsensitiveComparison( WHITE_COLOR, colorStr ) )
- {
- retColor = Color::WHITE;
- }
- else if( CaseInsensitiveComparison( RED_COLOR, colorStr ) )
- {
- retColor = Color::RED;
- }
- else if( CaseInsensitiveComparison( GREEN_COLOR, colorStr ) )
- {
- retColor = Color::GREEN;
- }
- else if( CaseInsensitiveComparison( BLUE_COLOR, colorStr ) )
- {
- retColor = Color::BLUE;
- }
- else if( CaseInsensitiveComparison( YELLOW_COLOR, colorStr ) )
- {
- retColor = Color::YELLOW;
- }
- else if( CaseInsensitiveComparison( MAGENTA_COLOR, colorStr ) )
- {
- retColor = Color::MAGENTA;
- }
- else if( CaseInsensitiveComparison( CYAN_COLOR, colorStr ) )
- {
- retColor = Color::CYAN;
- }
- else if( CaseInsensitiveComparison( TRANSPARENT_COLOR, colorStr ) )
- {
- retColor = Color::TRANSPARENT;
- }
-}
-
-/**
- * Converts a color packed inside a Vector4 into a string.
- * The string color could be in hexadecimal ( 0xFF0000FF ), webcolor ( #0000FF or #00F ) or some constant values:
- * black, white, red, green, blue, yellow, magenta, cyan, transparent.
- * @param[in] color A color packed inside a Vector4
- * @return The color packed inside a string.
- */
-std::string Vector4ToColorString( const Vector4& color )
-{
- std::string colorStr;
-
- if( Color::BLACK == color )
- {
- colorStr = BLACK_COLOR;
- }
- else if( Color::WHITE == color )
- {
- colorStr = WHITE_COLOR;
- }
- else if( Color::RED == color )
- {
- colorStr = RED_COLOR;
- }
- else if( Color::GREEN == color )
- {
- colorStr = GREEN_COLOR;
- }
- else if( Color::BLUE == color )
- {
- colorStr = BLUE_COLOR;
- }
- else if( Color::YELLOW == color )
- {
- colorStr = YELLOW_COLOR;
- }
- else if( Color::MAGENTA == color )
- {
- colorStr = MAGENTA_COLOR;
- }
- else if( Color::CYAN == color )
- {
- colorStr = CYAN_COLOR;
- }
- else if( Color::TRANSPARENT == color )
- {
- colorStr = TRANSPARENT_COLOR;
- }
- else
- {
- colorStr = HEX_COLOR_TOKEN + HexToString( Vector4ColorToUint( color ) );
- }
-
- return colorStr;
-}
-
-/**
- * Skips any unnecessary white space.
- * @param[in,out] it Iterator pointing to the current character of the markup string which is being parsed.
- * @param[in] endIt Iterator pointing to the end of the markup string.
- */
-void SkipWhiteSpace( std::string::const_iterator& it, const std::string::const_iterator& endIt )
-{
- bool found = false;
- for( ; ( !found ) && ( it != endIt ); ++it )
- {
- if( !isspace( *it ) )
- {
- found = true;
- --it;
- }
- }
-}
-
-/**
- * Adds a line separator 'LF' character to the given styled text array.
- * @param[in] style The current style.
- * @param[in,out] styledTextArray The given styled text array.
- */
-void AddNewLineChar( const TextStyle& style, StyledTextArray& styledTextArray )
-{
- const Text text( LINE_SEPARATOR_LF_STRING );
- styledTextArray.push_back( StyledText( text, style ) );
-}
-
-/**
- * Adds text to the given styled text array.
- * It splits the text in characters.
- * @param[in] textToBeStored The text to be stored.
- * @param[in] styleToBeStored The current style.
- * @param[in,out] styledTextArray The given styled text array.
- */
-void AddText( const std::string& textToBeStored, const TextStyle& styleToBeStored, StyledTextArray& styledTextArray )
-{
- const Text text( textToBeStored );
- for( size_t i = 0, length = text.GetLength(); i < length; ++i )
- {
- styledTextArray.push_back( StyledText( Text( text[i] ), styleToBeStored ) );
- }
-}
-
-/**
- * Splits the tag string into the tag name and its properties.
- * @param[in] tag The tag string with its pairs property, value.
- * @param[out] tagName The name of the tag.
- * @param[out] properties Vector of properties.
- */
-void ParseProperties( const std::string& tag, std::string& tagName, std::vector<Property>& properties )
-{
- // Find first the tag name.
- bool found = false;
- bool isQuotationOpen = false;
- std::string::const_iterator it, endIt;
- for( it = tag.begin(), endIt = tag.end(); ( !found ) && ( it != endIt ); ++it )
- {
- const char character( *it );
- if( !isspace( character ) )
- {
- tagName += character;
- }
- else
- {
- found = true;
- }
- }
- SkipWhiteSpace( it, endIt );
-
- // Find the properties.
- std::string name;
- std::string value;
- bool addToNameValue = true;
- for( ; it != endIt; ++it )
- {
- const char character( *it );
- if( isspace( character ) && !isQuotationOpen )
- {
- if( !name.empty() && !value.empty() )
- {
- // Every time a white space is found, a new property is created and stored in the properties vector.
- properties.push_back( Property( name, value ) );
- name .clear();
- value.clear();
- addToNameValue = true; // next read characters will be added to the name.
- }
- }
- else if( EQUAL == character ) // '='
- {
- addToNameValue = false; // next read characters will be added to the value.
- SkipWhiteSpace( it, endIt );
- }
- else if( QUOTATION_MARK == character ) // '\''
- {
- // Do not add quotation marks to neither name nor value.
- isQuotationOpen = !isQuotationOpen;
- }
- else
- {
- // Adds characters to the name or the value.
- if( addToNameValue )
- {
- name += character;
- }
- else
- {
- value += character;
- }
- }
- }
- if( !name.empty() && !value.empty() )
- {
- // Checks if the last property needs to be added.
- properties.push_back( Property( name, value ) );
- }
-}
-
-/**
- * It parses a tag and its properties if the given iterator \e it is pointing at a tag beginning.
- * @param[in,out] it Iterator pointing to the current character of the markup string which is being parsed.
- * @param[in] endIt Iterator pointing to the end of the markup string.
- * @param[out] tag Name of the tag.
- * @param[out] isEndTag Whether the tag is and end tag i.e </tag_name> or not.
- * @param[out] properties The vector with tag properties.
- * @return \e true if the iterator \e it is pointing a markup tag. Otherwise \e false.
- */
-bool IsTag( std::string::const_iterator& it, const std::string::const_iterator& endIt, std::string& tag, bool& isEndTag, std::vector<Property>& properties )
-{
- bool isTag = false;
- bool isQuotationOpen = false;
- bool propertiesFound = false;
- std::string tagString;
-
- const char character( *it );
- if( LESS_THAN == character ) // '<'
- {
- // if the iterator is pointing to a '<' character, then check if it's a markup tag is needed.
- ++it;
- if( it != endIt )
- {
- SkipWhiteSpace( it, endIt );
-
- for( ; ( !isTag ) && ( it != endIt ); ++it )
- {
- const char character( *it );
-
- if( SLASH == character ) // '/'
- {
- // if the tag has a '/' then it's an end or empty tag.
- isEndTag = true;
-
- if( ( it + 1 != endIt ) && ( isspace( *( it + 1 ) ) ) && ( !isQuotationOpen ) )
- {
- ++it;
- SkipWhiteSpace( it, endIt );
- --it;
- }
- }
- else if( GREATER_THAN == character ) // '>'
- {
- isTag = true;
- }
- else if(QUOTATION_MARK == character)
- {
- isQuotationOpen = !isQuotationOpen;
- tagString += character;
- }
- else if( isspace( character ) ) // ' '
- {
- // If the tag contains white spaces then it may have properties.
- if ( !isQuotationOpen )
- {
- propertiesFound = true;
- }
- tagString += character;
- }
- else
- {
- // If it's not any of the 'special' characters then just add it to the tag string.
- tagString += character;
- }
- }
- --it;
- }
- }
-
- // If the tag string has white spaces, then parse the properties is needed.
- if( propertiesFound )
- {
- ParseProperties( tagString, tag, properties );
- }
- else
- {
- tag = tagString;
- }
-
- return isTag;
-}
-
-} // namespace
-
-void GetStyledTextArray( const std::string& markupString, StyledTextArray& styledTextArray, bool scanForMarkup )
-{
- styledTextArray.clear();
-
- if ( !scanForMarkup )
- {
- const Text text( markupString );
- const std::size_t size = text.GetLength();
-
- styledTextArray.resize( size, StyledText( Text(), TextStyle() ) );
-
- std::size_t index = 0;
- for( StyledTextArray::iterator it = styledTextArray.begin(), endIt = styledTextArray.end(); it != endIt; ++it, ++index )
- {
- StyledText& styledText( *it );
-
- styledText.mText.Append( text[index] );
- }
- return;
- }
-
- TextStyle defaultStyle;
- std::stack<TextStyle> styleStack;
-
- styleStack.push( defaultStyle );
- TextStyle currentStyle = styleStack.top();
- std::string textToBeStored;
- TextStyle styleToBeStored( currentStyle );
- for( std::string::const_iterator it = markupString.begin(), endIt = markupString.end(); it != endIt; ++it )
- {
- std::string tag;
- bool isEndTag = false;
- std::vector<Property> tagProperties;
- if( IsTag( it, endIt, tag, isEndTag, tagProperties ) )
- {
- if( CaseInsensitiveComparison( XHTML_I_TAG, tag ) )
- {
- if( !isEndTag )
- {
- TextStyle newStyle( currentStyle );
- newStyle.SetItalics( true );
- styleStack.push( newStyle );
- currentStyle = styleStack.top();
- }
- else
- {
- styleStack.pop();
- currentStyle = styleStack.top();
- }
- } // <i></i>
- else if( CaseInsensitiveComparison( XHTML_U_TAG, tag ) )
- {
- if( !isEndTag )
- {
- TextStyle newStyle( currentStyle );
- newStyle.SetUnderline( true );
- styleStack.push( newStyle );
- currentStyle = styleStack.top();
- }
- else
- {
- styleStack.pop();
- currentStyle = styleStack.top();
- }
- } // <u></u>
- else if( CaseInsensitiveComparison( XHTML_B_TAG, tag ) )
- {
- if( !isEndTag )
- {
- TextStyle newStyle( currentStyle );
- newStyle.SetWeight( TextStyle::BOLD );
- styleStack.push( newStyle );
- currentStyle = styleStack.top();
- }
- else
- {
- styleStack.pop();
- currentStyle = styleStack.top();
- }
- } // <b></b>
- else if( CaseInsensitiveComparison( XHTML_BR_TAG, tag ) )
- {
- if( isEndTag )
- {
- AddText( textToBeStored, styleToBeStored, styledTextArray );
- AddNewLineChar( currentStyle, styledTextArray );
- textToBeStored.clear();
- }
- } // <br/>
- else if( CaseInsensitiveComparison( XHTML_FONT_TAG, tag ) )
- {
- if( !isEndTag )
- {
- TextStyle newStyle( currentStyle );
- for( std::vector<Property>::const_iterator it = tagProperties.begin(), endIt = tagProperties.end(); it != endIt; ++it )
- {
- const Property& property( *it );
- if( CaseInsensitiveComparison( XHTML_FACE_PROPERTY, property.name ) )
- {
- newStyle.SetFontName( property.value );
- }
- else if( CaseInsensitiveComparison( XHTML_STYLE_PROPERTY, property.name ) )
- {
- newStyle.SetFontStyle( property.value );
- }
- else if( CaseInsensitiveComparison( XHTML_COLOR_PROPERTY, property.name ) )
- {
- Vector4 color;
- ColorStringToVector4( property.value, color );
- newStyle.SetTextColor( color );
- }
- else if( CaseInsensitiveComparison( XHTML_SIZE_PROPERTY, property.name ) )
- {
- newStyle.SetFontPointSize( PointSize( StringToFloat( property.value ) ) );
- }
- }
- styleStack.push( newStyle );
- currentStyle = styleStack.top();
- }
- else
- {
- styleStack.pop();
- currentStyle = styleStack.top();
- }
- } // <font></font>
- else if( CaseInsensitiveComparison( XHTML_SHADOW_TAG, tag ) )
- {
- if( !isEndTag )
- {
- TextStyle newStyle( currentStyle );
- Vector4 color( TextStyle::DEFAULT_SHADOW_COLOR );
- Vector2 offset( TextStyle::DEFAULT_SHADOW_OFFSET );
- for( std::vector<Property>::const_iterator it = tagProperties.begin(), endIt = tagProperties.end(); it != endIt; ++it )
- {
- const Property& property( *it );
- if( CaseInsensitiveComparison( XHTML_PARAM_X_PROPERTY, property.name ) )
- {
- offset.x = StringToFloat( property.value );
- }
- else if( CaseInsensitiveComparison( XHTML_PARAM_Y_PROPERTY, property.name ) )
- {
- offset.y = StringToFloat( property.value );
- }
- else if( CaseInsensitiveComparison( XHTML_COLOR_PROPERTY, property.name ) )
- {
- ColorStringToVector4( property.value, color );
- }
- }
- newStyle.SetShadow( true, color, offset );
- styleStack.push( newStyle );
- currentStyle = styleStack.top();
- }
- else
- {
- styleStack.pop();
- currentStyle = styleStack.top();
- }
- } // <shadow></shadow>
- else if( CaseInsensitiveComparison( XHTML_GLOW_TAG, tag ) )
- {
- if( !isEndTag )
- {
- TextStyle newStyle( currentStyle );
- Vector4 color( TextStyle::DEFAULT_GLOW_COLOR );
- float intensity = TextStyle::DEFAULT_GLOW_INTENSITY;
- for( std::vector<Property>::const_iterator it = tagProperties.begin(), endIt = tagProperties.end(); it != endIt; ++it )
- {
- const Property& property( *it );
- if( CaseInsensitiveComparison( XHTML_PARAM_PROPERTY, property.name ) )
- {
- intensity = StringToFloat( property.value );
- }
- else if( CaseInsensitiveComparison( XHTML_COLOR_PROPERTY, property.name ) )
- {
- ColorStringToVector4( property.value, color );
- }
- }
- newStyle.SetGlow( true, color, intensity );
- styleStack.push( newStyle );
- currentStyle = styleStack.top();
- }
- else
- {
- styleStack.pop();
- currentStyle = styleStack.top();
- }
- } // <glow></glow>
- else if( CaseInsensitiveComparison( XHTML_OUTLINE_TAG, tag ) )
- {
- if( !isEndTag )
- {
- TextStyle newStyle( currentStyle );
- Vector4 color( TextStyle::DEFAULT_OUTLINE_COLOR );
- Vector2 thickness( TextStyle::DEFAULT_OUTLINE_THICKNESS );
- for( std::vector<Property>::const_iterator it = tagProperties.begin(), endIt = tagProperties.end(); it != endIt; ++it )
- {
- const Property& property( *it );
- if( CaseInsensitiveComparison( XHTML_PARAM_X_PROPERTY, property.name ) )
- {
- thickness.x = StringToFloat( property.value );
- }
- else if( CaseInsensitiveComparison( XHTML_PARAM_Y_PROPERTY, property.name ) )
- {
- thickness.y = StringToFloat( property.value );
- }
- else if( CaseInsensitiveComparison( XHTML_COLOR_PROPERTY, property.name ) )
- {
- ColorStringToVector4( property.value, color );
- }
- }
- newStyle.SetOutline( true, color, thickness );
- styleStack.push( newStyle );
- currentStyle = styleStack.top();
- }
- else
- {
- styleStack.pop();
- currentStyle = styleStack.top();
- }
- } // <outline></outline>
- else if( CaseInsensitiveComparison( XHTML_SMOOTH_EDGE_TAG, tag ) )
- {
- if( !isEndTag )
- {
- TextStyle newStyle( currentStyle );
- for( std::vector<Property>::const_iterator it = tagProperties.begin(), endIt = tagProperties.end(); it != endIt; ++it )
- {
- const Property& property( *it );
- if( CaseInsensitiveComparison( XHTML_PARAM_PROPERTY, property.name ) )
- {
- newStyle.SetSmoothEdge( StringToFloat( property.value ) );
- }
- }
- styleStack.push( newStyle );
- currentStyle = styleStack.top();
- }
- else
- {
- styleStack.pop();
- currentStyle = styleStack.top();
- }
- } // <smooth></smooth>
- } // end if( IsTag() )
- else
- {
- char character( *it );
-
- // Adding < or > special character.
- if( ( BACK_SLASH == character ) && ( it + 1 != endIt ) )
- {
- const char nextChar( *( it + 1 ) );
- if( ( LESS_THAN == nextChar ) || ( GREATER_THAN == nextChar ) )
- {
- character = nextChar;
- ++it;
- }
- }
- else if( ( LINE_SEPARATOR_CR == character ) && ( it + 1 != endIt ) )
- {
- if( LINE_SEPARATOR_LF == *( it + 1 ) )
- {
- character = LINE_SEPARATOR_LF;
- ++it;
- }
- }
-
- if( styleToBeStored != currentStyle )
- {
- if( !textToBeStored.empty() )
- {
- AddText( textToBeStored, styleToBeStored, styledTextArray );
- textToBeStored.clear();
- }
- styleToBeStored = currentStyle;
- }
- textToBeStored.insert( textToBeStored.end(), character );
- }
- }
- if( !textToBeStored.empty() )
- {
- AddText( textToBeStored, styleToBeStored, styledTextArray );
- textToBeStored.clear();
- }
-}
-
-void GetPlainString( const StyledTextArray& styledTextArray, std::string& plainString )
-{
- // First step is put all simultaneous characters with same style together.
- for( StyledTextArray::const_iterator it = styledTextArray.begin(), endIt = styledTextArray.end(); it != endIt; ++it )
- {
- const StyledText& styledText( *it );
- plainString += styledText.mText.GetText();
- }
-}
-
-void GetMarkupString( const StyledTextArray& styledTextArray, std::string& markupString )
-{
- const std::string WHITE_SPACE( " " );
-
- TextStyle previousStyle;
- StyledText newStyledText;
- StyledTextArray compressedStyledTextArray;
-
- markupString.clear();
-
- // First step is put all simultaneous characters with same style together.
- for( StyledTextArray::const_iterator it = styledTextArray.begin(), endIt = styledTextArray.end(); it != endIt; ++it )
- {
- const StyledText& styledText( *it );
-
- if( previousStyle != styledText.mStyle )
- {
- if( !newStyledText.mText.IsEmpty() )
- {
- compressedStyledTextArray.push_back( newStyledText );
- }
- newStyledText = StyledText();
- newStyledText.mStyle = styledText.mStyle;
- }
-
- if( !styledText.mText.IsEmpty() )
- {
- const char character = styledText.mText.GetText()[0];
- if( ( character == LESS_THAN ) || ( character == GREATER_THAN ) )
- {
- newStyledText.mText.Append( Text( std::string( &BACK_SLASH, 1 ) ) );
- }
- }
-
- newStyledText.mText.Append( styledText.mText );
-
- previousStyle = newStyledText.mStyle;
- }
-
- //Add the last characters.
- if( !newStyledText.mText.IsEmpty() )
- {
- compressedStyledTextArray.push_back( newStyledText );
- }
-
- // Write markup string.
- const std::string lineSeparatorStr( &LINE_SEPARATOR_LF );
- const Text lineSeparator( lineSeparatorStr );
-
- const TextStyle defaultStyle;
- for( StyledTextArray::const_iterator it = compressedStyledTextArray.begin(), endIt = compressedStyledTextArray.end(); it != endIt; ++it )
- {
- const StyledText& styledText( *it );
-
- bool isItalics = styledText.mStyle.IsItalicsEnabled();
- bool isBold = defaultStyle.GetWeight() != styledText.mStyle.GetWeight();
- bool isUnderline = styledText.mStyle.IsUnderlineEnabled();
- bool hasFontFace = defaultStyle.GetFontName() != styledText.mStyle.GetFontName();
- bool hasFontStyle = defaultStyle.GetFontStyle() != styledText.mStyle.GetFontStyle();
- bool hasFontSize = fabsf( defaultStyle.GetFontPointSize() - styledText.mStyle.GetFontPointSize() ) > GetRangedEpsilon( defaultStyle.GetFontPointSize(), styledText.mStyle.GetFontPointSize() );
- bool hasFontColor = defaultStyle.GetTextColor() != styledText.mStyle.GetTextColor();
-
- bool hasSmooth = fabsf( defaultStyle.GetSmoothEdge() - styledText.mStyle.GetSmoothEdge() ) > GetRangedEpsilon( defaultStyle.GetSmoothEdge(), styledText.mStyle.GetSmoothEdge() );
- bool hasShadowColor = defaultStyle.GetShadowColor() != styledText.mStyle.GetShadowColor();
- bool hasShadowParams = defaultStyle.GetShadowOffset() != styledText.mStyle.GetShadowOffset();
- bool hasGlowColor = defaultStyle.GetGlowColor() != styledText.mStyle.GetGlowColor();
- bool hasGlowParams = fabsf( defaultStyle.GetGlowIntensity() - styledText.mStyle.GetGlowIntensity() ) > GetRangedEpsilon( defaultStyle.GetGlowIntensity(), styledText.mStyle.GetGlowIntensity() );
- bool hasOutlineColor = defaultStyle.GetOutlineColor() != styledText.mStyle.GetOutlineColor();
- bool hasOutlineParams = defaultStyle.GetOutlineThickness() != styledText.mStyle.GetOutlineThickness();
-
- // Write font info.
- if( hasFontFace || hasFontStyle || hasFontSize || hasFontColor )
- {
- markupString += LESS_THAN + XHTML_FONT_TAG;
-
- if( hasFontFace )
- {
- markupString += WHITE_SPACE + XHTML_FACE_PROPERTY + EQUAL + QUOTATION_MARK + styledText.mStyle.GetFontName() + QUOTATION_MARK; // face=''
- }
-
- if( hasFontStyle )
- {
- markupString += WHITE_SPACE + XHTML_STYLE_PROPERTY + EQUAL + QUOTATION_MARK + styledText.mStyle.GetFontStyle() + QUOTATION_MARK; // style=''
- }
-
- if( hasFontSize )
- {
- markupString += WHITE_SPACE + XHTML_SIZE_PROPERTY + EQUAL + QUOTATION_MARK + FloatToString( styledText.mStyle.GetFontPointSize() ) + QUOTATION_MARK; // size=''
- }
-
- if( hasFontColor )
- {
- markupString += WHITE_SPACE + XHTML_COLOR_PROPERTY + EQUAL + QUOTATION_MARK + Vector4ToColorString( styledText.mStyle.GetTextColor() ) + QUOTATION_MARK; // color=''
- }
-
- markupString += GREATER_THAN;
- } // <font>
-
- // Write italics.
- if( isItalics )
- {
- markupString += LESS_THAN + XHTML_I_TAG + GREATER_THAN;
- } // <i>
-
- // Write bold.
- if( isBold )
- {
- markupString += LESS_THAN + XHTML_B_TAG + GREATER_THAN;
- } // <b>
-
- // Write underline.
- if( isUnderline )
- {
- markupString += LESS_THAN + XHTML_U_TAG + GREATER_THAN;
- } // <u>
-
- // Write smooth.
- if( hasSmooth )
- {
- markupString += LESS_THAN + XHTML_SMOOTH_EDGE_TAG + WHITE_SPACE + XHTML_PARAM_PROPERTY + EQUAL + QUOTATION_MARK + FloatToString( styledText.mStyle.GetSmoothEdge() ) + QUOTATION_MARK + GREATER_THAN;
- }
-
- // Write shadow.
- if( styledText.mStyle.IsShadowEnabled() )
- {
- markupString += LESS_THAN + XHTML_SHADOW_TAG;
-
- if( hasShadowColor )
- {
- markupString += WHITE_SPACE + XHTML_COLOR_PROPERTY + EQUAL + QUOTATION_MARK + Vector4ToColorString( styledText.mStyle.GetShadowColor() ) + QUOTATION_MARK;
- }
-
- if( hasShadowParams )
- {
- markupString += WHITE_SPACE + XHTML_PARAM_X_PROPERTY + EQUAL + QUOTATION_MARK + FloatToString( styledText.mStyle.GetShadowOffset().x ) + QUOTATION_MARK;
- markupString += WHITE_SPACE + XHTML_PARAM_Y_PROPERTY + EQUAL + QUOTATION_MARK + FloatToString( styledText.mStyle.GetShadowOffset().y ) + QUOTATION_MARK;
- }
-
- markupString += GREATER_THAN;
- }
-
- // Write glow.
- if( styledText.mStyle.IsGlowEnabled() )
- {
- markupString += LESS_THAN + XHTML_GLOW_TAG;
-
- if( hasGlowColor )
- {
- markupString += WHITE_SPACE + XHTML_COLOR_PROPERTY + EQUAL + QUOTATION_MARK + Vector4ToColorString( styledText.mStyle.GetGlowColor() ) + QUOTATION_MARK; // color=''
- }
-
- if( hasGlowParams )
- {
- markupString += WHITE_SPACE + XHTML_PARAM_PROPERTY + EQUAL + QUOTATION_MARK + FloatToString( styledText.mStyle.GetGlowIntensity() ) + QUOTATION_MARK; // param=''
- }
-
- markupString += GREATER_THAN;
- } // <glow>
-
- // Write outline.
- if( styledText.mStyle.IsOutlineEnabled() )
- {
- markupString += LESS_THAN + XHTML_OUTLINE_TAG;
-
- if( hasOutlineColor )
- {
- markupString += WHITE_SPACE + XHTML_COLOR_PROPERTY + EQUAL + QUOTATION_MARK + Vector4ToColorString( styledText.mStyle.GetOutlineColor() ) + QUOTATION_MARK; // color = ''
- }
-
- if( hasOutlineParams )
- {
- markupString += WHITE_SPACE + XHTML_PARAM_X_PROPERTY + EQUAL + QUOTATION_MARK + FloatToString( styledText.mStyle.GetOutlineThickness().x ) + QUOTATION_MARK; // paramx=''
- markupString += WHITE_SPACE + XHTML_PARAM_Y_PROPERTY + EQUAL + QUOTATION_MARK + FloatToString( styledText.mStyle.GetOutlineThickness().y ) + QUOTATION_MARK; // paramy=''
- }
-
- markupString += GREATER_THAN;
- } // <outline>
-
- // Write text.
- if( styledText.mText[0] == lineSeparator[0] )
- {
- markupString += LESS_THAN + XHTML_BR_TAG + WHITE_SPACE + SLASH + GREATER_THAN; // <br />
- }
- else
- {
- markupString += styledText.mText.GetText();
- }
-
- // Write outline close tag.
- if( styledText.mStyle.IsOutlineEnabled() )
- {
- markupString += LESS_THAN + ( SLASH + XHTML_OUTLINE_TAG + GREATER_THAN ); // </outline>
- }
-
- // Write glow close tag.
- if( styledText.mStyle.IsGlowEnabled() )
- {
- markupString += LESS_THAN + ( SLASH + XHTML_GLOW_TAG + GREATER_THAN ); // </glow>
- }
-
- // Write shadow close tag.
- if( styledText.mStyle.IsShadowEnabled() )
- {
- markupString += LESS_THAN + ( SLASH + XHTML_SHADOW_TAG + GREATER_THAN ); // </shadow>
- }
-
- // Write smooth close tag.
- if( hasSmooth )
- {
- markupString += LESS_THAN + ( SLASH + XHTML_SMOOTH_EDGE_TAG + GREATER_THAN ); // </smooth>
- }
-
- // Write underline close tag.
- if( isUnderline )
- {
- markupString += LESS_THAN + ( SLASH + XHTML_U_TAG + GREATER_THAN ); // </u>
- }
-
- // Write bold close tag.
- if( isBold )
- {
- markupString += LESS_THAN + ( SLASH + XHTML_B_TAG + GREATER_THAN ); // </b>
- }
-
- // Write italics close tag.
- if( isItalics )
- {
- markupString += LESS_THAN + ( SLASH + XHTML_I_TAG + GREATER_THAN ); // </i>
- }
-
- // Write font close tag.
- if( hasFontFace || hasFontStyle || hasFontSize || hasFontColor )
- {
- markupString += LESS_THAN + ( SLASH + XHTML_FONT_TAG + GREATER_THAN ); // </font>
- }
- }
-}
-
-void SetTextStyle( StyledTextArray& styledTextArray, const TextStyle& style, TextStyle::Mask mask )
-{
- if( !styledTextArray.empty() )
- {
- const size_t size = styledTextArray.size() - 1;
- SetTextStyleToRange( styledTextArray, style, mask, 0, size );
- }
-}
-
-void SetTextStyle( const Text& text, StyledTextArray& styledTextArray, const TextStyle& style, TextStyle::Mask mask )
-{
- if( !text.IsEmpty() )
- {
- const size_t size = text.GetLength();
-
- for( size_t i = 0; i < size; ++i )
- {
- StyledText styledText;
- styledText.mText = Text( text[i] );
- styledText.mStyle = style;
-
- styledTextArray.push_back( styledText );
- }
-
- SetTextStyleToRange( styledTextArray, style, mask, 0, size - 1 );
- }
-}
-
-void SetTextStyleToRange( StyledTextArray& styledTextArray, const TextStyle& style, TextStyle::Mask mask, std::size_t begin, std::size_t end )
-{
- const size_t size = styledTextArray.size();
- DALI_ASSERT_ALWAYS( begin < size );
- DALI_ASSERT_ALWAYS( end < size );
-
- for( StyledTextArray::iterator it = styledTextArray.begin() + std::min(begin, end), endIt = styledTextArray.begin() + std::max(begin, end) + 1; it != endIt; ++it )
- {
- StyledText& styledText( *it );
-
- styledText.mStyle.Copy( style, mask );
- } // for loop
-}
-
-} // namespace MarkupProcessor
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_MARKUP_PROCESSOR_H__
-#define __DALI_TOOLKIT_MARKUP_PROCESSOR_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/common/vector-wrapper.h>
-#include <dali/public-api/text/text.h>
-#include <dali/public-api/text/text-style.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-/**
- * @brief Markup Processor enumerations, structures and functions.
- *
- * See the \link markup-processor Markup Processor \endlink page in the Programming Guide.
- */
-namespace MarkupProcessor
-{
-
-/**
- * @brief A pair of Dali::Text and Dali::TextStyle.
- *
- * mText is a Dali::Text object which can store text in different
- * languages. mStyle is a Dali::TextStyle object which can store all
- * text styling features provided by Dali::TextActor.
- */
-struct StyledText
-{
- /**
- * @brief Constructor
- */
- StyledText()
- : mText(),
- mStyle()
- {
- }
-
- /**
- * @brief Constructor
- *
- * @param[in] text A Text object
- * @param[in] style A Style object
- */
- StyledText( const Text& text, const TextStyle& style )
- : mText( text ),
- mStyle( style )
- {
- }
-
- Text mText; ///< Store text. Could be a mix of different languages.
- TextStyle mStyle; ///< Store the style for the text.
-};
-
-/**
- * @brief This type defines a vector of StyledText.
- *
- * It's used to store a whole text with its style and set it to a
- * Dali::Toolkit::TextView. It could be used in other UI
- * Dali::Toolkit::Control classes which need text with style.
- */
-typedef std::vector<StyledText> StyledTextArray;
-
-/**
- * @brief Creates a text array with its style from a markup string.
- *
- * Refer to the \link markup-processor Markup Processor \endlink page in the Programming Guide
- * to see the html-ish sintax and some examples.
- *
- * @param [in] markupString A string with style.
- * @param [out] styledTextArray A text array split in characters, each one with its style.
- * @param [in] scanForMarkup If true will check to see string contains markup, else assume not
- */
-DALI_IMPORT_API void GetStyledTextArray( const std::string& markupString, StyledTextArray& styledTextArray, bool scanForMarkup );
-
-/**
- * @brief Creates a plain string from a text array (thus stripping the style meta).
- *
- * @param [in] styledTextArray A text array split in characters, each one with its style.
- * @param [out] plainString A string without style.
- */
-DALI_IMPORT_API void GetPlainString( const StyledTextArray& styledTextArray, std::string& plainString );
-
-/**
- * @brief Creates a markup string from a text array with its style.
- *
- * @param [in] styledTextArray A text array split in characters, each one with its style.
- * @param [out] markupString A string with style.
- */
-DALI_IMPORT_API void GetMarkupString( const StyledTextArray& styledTextArray, std::string& markupString );
-
-/**
- * @brief Sets a text style to the given text.
- *
- * By default all style settings are applied but a bit mask could be used to modify only certain style settings.
- * @param[in,out] styledTextArray The given text
- * @param[in] style The given style
- * @param[in] mask The bit mask.
- */
-DALI_IMPORT_API void SetTextStyle( StyledTextArray& styledTextArray, const TextStyle& style, TextStyle::Mask mask = TextStyle::ALL );
-
-/**
- * @brief Sets a text style to the given text.
- *
- * @see SetTextStyle( StyledTextArray& styledTextArray, const TextStyle& style, TextStyle::Mask mask )
- *
- * @param[in] text The input text.
- * @param[out] styledTextArray The input text with the given style.
- * @param[in] style The given style.
- * @param[in] mask The bit mask.
- */
-DALI_IMPORT_API void SetTextStyle( const Text& text, StyledTextArray& styledTextArray, const TextStyle& style, TextStyle::Mask mask = TextStyle::ALL );
-
-/**
- * @brief Sets a text style to a range of characters of the given text.
- *
- * By default all style settings are applied but a bit mask could be used to modify only certain style settings.
- * @param[in,out] styledTextArray The given text
- * @param[in] style The given style
- * @param[in] mask The bit mask.
- * @param[in] begin The first character of the range.
- * @param[in] end The last character of the range.
- * @note It will assert if begin or end are out of range, or if begin > end.
- */
-DALI_IMPORT_API void SetTextStyleToRange( StyledTextArray& styledTextArray, const TextStyle& style, TextStyle::Mask mask, std::size_t begin, std::size_t end );
-
-} // namespace MarkupProcessor
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_MARKUP_PROCESSOR_H__
ShaderEffect shaderEffectCustom = ShaderEffect::New(vertexShader,
"",
- GeometryType( GEOMETRY_TYPE_IMAGE | GEOMETRY_TYPE_TEXT ),
+ GeometryType( GEOMETRY_TYPE_IMAGE ),
ShaderEffect::GeometryHints( ShaderEffect::HINT_GRID | ShaderEffect::HINT_DEPTH_BUFFER ));
// Pass ownership to CarouselEffect through overloaded constructor, So that it now has access to the
// Create the implementation, temporarily owned on stack
Dali::ShaderEffect shaderEffect = Dali::ShaderEffect::New(
- vertexShader, imageFragmentShader, vertexShader, "", GeometryHints(HINT_GRID) );
+ vertexShader, imageFragmentShader, GeometryType(GEOMETRY_TYPE_IMAGE), GeometryHints(HINT_GRID) );
/* Pass ownership to RippleEffect through overloaded constructor, So that it now has access to the
Dali::ShaderEffect implementation */
ShaderEffect shaderEffectCustom = Dali::ShaderEffect::New(
vertexShader,
"",
- GeometryType( GEOMETRY_TYPE_IMAGE | GEOMETRY_TYPE_TEXT ),
+ GeometryType( GEOMETRY_TYPE_IMAGE ),
GeometryHints( HINT_GRID ));
// Pass ownership to ShearEffect through overloaded constructor, So that it now has access to the
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_BIDIRECTIONAL_LINE_INFO_RUN_H__
+#define __DALI_TOOLKIT_TEXT_BIDIRECTIONAL_LINE_INFO_RUN_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/character-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief BidirectionalLineInfoRun
+ */
+struct BidirectionalLineInfoRun
+{
+ CharacterRun characterRun; ///< The initial character index within the whole text and the number of characters of the run.
+ CharacterIndex* visualToLogicalMap; ///< Pointer to the visual to logical map table.
+ CharacterIndex* logicalToVisualMap; ///< Pointer to the logical to visual map table.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_BIDIRECTIONAL_LINE_INFO_RUN_H__
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_BIDIRECTIONAL_PARAGRAPH_INFO_RUN_H__
+#define __DALI_TOOLKIT_TEXT_BIDIRECTIONAL_PARAGRAPH_INFO_RUN_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/character-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief BidirectionalParagraphInfoRun
+ *
+ * In terms of the bidirectional algorithm, a 'paragraph' is understood as a run of characters between Paragraph Separators or appropriate Newline Functions.
+ * A 'paragraph' may also be determined by higher-level protocols like a mark-up tag.
+ */
+struct BidirectionalParagraphInfoRun
+{
+ CharacterRun characterRun; ///< The initial character index within the whole text and the number of characters of the run.
+ BidiInfoIndex bidirectionalInfoIndex; ///< Index to the table with the bidirectional info per paragraph.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_BIDIRECTIONAL_PARAGRAPH_INFO_RUN_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/public-api/text/bidirectional-support.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+void SetBidirectionalInfo( const Vector<Character>& text,
+ const Vector<LineBreakInfo>& lineBreakInfo,
+ Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo )
+{
+}
+
+void ReplaceBidirectionalInfo( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert )
+{
+}
+
+void ReorderLines( const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
+ const Vector<CharacterRun>& lineRuns,
+ Vector<BidirectionalLineInfoRun>& lineInfoRuns )
+{
+}
+
+void ReorderLines( LogicalModel& logicalModel,
+ const VisualModel& visualModel,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert )
+{
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_BIDIRECTIONAL_SUPPORT_H__
+#define __DALI_TOOLKIT_TEXT_BIDIRECTIONAL_SUPPORT_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <dali-toolkit/public-api/text/bidirectional-line-info-run.h>
+#include <dali-toolkit/public-api/text/bidirectional-paragraph-info-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+class LogicalModel;
+class VisualModel;
+
+/**
+ * Sets the bidirectional info into the logical model.
+ *
+ * @param[in] text Vector of UTF-32 characters.
+ * @param[in] lineBreakInfo The line break info.
+ * @param[out] bidirectionalInfo Vector with the bidirectional infor for each paragraph.
+ */
+void SetBidirectionalInfo( const Vector<Character>& text,
+ const Vector<LineBreakInfo>& lineBreakInfo,
+ Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo );
+
+/**
+ * Replaces the bidirectional info from the logical model.
+ *
+ * @pre The @p model needs to have a text set.
+ * @pre The @p model needs to have the line break info set.
+ *
+ * If the @p numberOfCharactersToRemove is zero, this operation is like an insert.
+ * If the @p numberOfCharactersToInsert is zero, this operation is like a remove.
+ *
+ * @param[in,out] model The text's logical model.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharactersToRemove The number of characters removed from the text.
+ * @param[in] numberOfCharactersToInsert The number of characters inserted in the text.
+ */
+void ReplaceBidirectionalInfo( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert );
+
+/**
+ * Sets the visual to logical and logical to visual map tables.
+ *
+ * Any map tables previously set are removed.
+ *
+ * @pre The @p logicalModel needs to have a text set.
+ * @pre The @p logicalModel needs to have the bidirectional info indices for each paragraph set.
+ * @pre The @p visualModel needs to have the laid-out lines info set.
+ *
+ * @param[in] bidirectionalInfo Vector with the bidirectional infor for each paragraph.
+ * @param[in] lineRuns The line runs converted to characters.
+ * @param[out] lineInfoRuns line runs with the visual to logical and logical to visual conversion maps.
+ */
+void ReorderLines( const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
+ const Vector<CharacterRun>& lineRuns,
+ Vector<BidirectionalLineInfoRun>& lineInfoRuns );
+
+/**
+ * Replaces the visual to logical and logical to visual map tables.
+ *
+ * @pre The @p logicalModel needs to have a text set.
+ * @pre The @p logicalModel needs to have the line break info set.
+ * @pre The @p visualModel needs to have the laid-out lines info set.
+ *
+ * If the @p numberOfCharactersToRemove is zero, this operation is like an insert.
+ * If the @p numberOfCharactersToInsert is zero, this operation is like a remove.
+ *
+ * @param[in,out] logicalModel The text's logical model.
+ * @param[in] visualModel The text's visual model.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharactersToRemove The number of characters removed from the text.
+ * @param[in] numberOfCharactersToInsert The number of characters inserted in the text.
+ */
+void ReorderLines( LogicalModel& logicalModel,
+ const VisualModel& visualModel,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_BIDIRECTIONAL_SUPPORT_H__
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_CHARACTER_RUN_H__
+#define __DALI_TOOLKIT_TEXT_CHARACTER_RUN_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief A run of consecutive characters.
+ */
+struct CharacterRun
+{
+ CharacterIndex characterIndex; ///< Index to the first character.
+ Length numberOfCharacters; ///< Number of characters in the run.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_CHARACTER_RUN_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/public-api/text/character-set-conversion.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace
+{
+ const static uint8_t U1 = 1u;
+ const static uint8_t U2 = 2u;
+ const static uint8_t U3 = 3u;
+ const static uint8_t U4 = 4u;
+ const static uint8_t U0 = 0u;
+ const static uint8_t UTF8_LENGTH[256] = {
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, // lead byte = 0xxx xxxx (U+0000 - U+007F + some extended ascii characters)
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
+ U1, U1, //
+
+ U2, U2, U2, U2, U2, U2, U2, U2, U2, U2, //
+ U2, U2, U2, U2, U2, U2, U2, U2, U2, U2, // lead byte = 110x xxxx (U+0080 - U+07FF)
+ U2, U2, U2, U2, U2, U2, U2, U2, U2, U2, //
+ U2, U2, //
+
+ U3, U3, U3, U3, U3, U3, U3, U3, U3, U3, // lead byte = 1110 xxxx (U+0800 - U+FFFF)
+ U3, U3, U3, U3, U3, U3, //
+
+ U4, U4, U4, U4, U4, U4, U4, U4, // lead byte = 1111 0xxx (U+10000 - U+1FFFFF)
+
+ U0, U0, U0, U0, // Non valid.
+ U0, U0, U0, U0, // Non valid.
+ };
+} // namespace
+
+uint32_t GetNumberOfUtf8Characters( const uint8_t* const utf8, uint32_t length )
+{
+ uint32_t numberOfCharacters = 0u;
+
+ const uint8_t* begin = utf8;
+ const uint8_t* end = utf8 + length;
+
+ for( ; begin < end ; begin += UTF8_LENGTH[*begin], ++numberOfCharacters );
+
+ return numberOfCharacters;
+}
+
+uint32_t GetNumberOfUtf8Bytes( const uint32_t* const utf32, uint32_t numberOfCharacters )
+{
+ uint32_t numberOfBytes = 0u;
+
+ const uint32_t* begin = utf32;
+ const uint32_t* end = utf32 + numberOfCharacters;
+
+ for( ; begin < end; ++begin )
+ {
+ const uint32_t code = *begin;
+
+ if( code < 0x80u )
+ {
+ ++numberOfBytes;
+ }
+ else if( code < 0x800u )
+ {
+ numberOfBytes += U2;
+ }
+ else if( code < 0x10000u )
+ {
+ numberOfBytes += U3;
+ }
+ else if( code < 0x200000u )
+ {
+ numberOfBytes += U4;
+ }
+ }
+
+ return numberOfBytes;
+}
+
+uint32_t Utf8ToUtf32( const uint8_t* const utf8, uint32_t length, uint32_t* utf32 )
+{
+ uint32_t numberOfCharacters = 0u;
+
+ const uint8_t* begin = utf8;
+ const uint8_t* end = utf8 + length;
+
+ for( ; begin < end ; ++numberOfCharacters )
+ {
+ const uint8_t leadByte = *begin;
+
+ switch( UTF8_LENGTH[leadByte] )
+ {
+ case U1:
+ {
+ *utf32++ = leadByte;
+ begin++;
+ break;
+ }
+
+ case U2:
+ {
+ uint32_t& code = *utf32++;
+ code = leadByte & 0x1fu;
+ begin++;
+ code <<= 6u;
+ code |= *begin++ & 0x3fu;
+ break;
+ }
+
+ case U3:
+ {
+ uint32_t& code = *utf32++;
+ code = leadByte & 0x1fu;
+ begin++;
+ code <<= 6u;
+ code |= *begin++ & 0x3fu;
+ code <<= 6u;
+ code |= *begin++ & 0x3fu;
+ break;
+ }
+
+ case U4:
+ {
+ uint32_t& code = *utf32++;
+ code = leadByte & 0x1fu;
+ begin++;
+ code <<= 6u;
+ code |= *begin++ & 0x3fu;
+ code <<= 6u;
+ code |= *begin++ & 0x3fu;
+ code <<= 6u;
+ code |= *begin++ & 0x3fu;
+ break;
+ }
+ }
+ }
+
+ return numberOfCharacters;
+}
+
+void Utf32ToUtf8( const uint32_t* const utf32, uint32_t numberOfCharacters, uint8_t* utf8 )
+{
+ const uint32_t* begin = utf32;
+ const uint32_t* end = utf32 + numberOfCharacters;
+
+ for( ; begin < end; ++begin )
+ {
+ const uint32_t code = *begin;
+
+ if( code < 0x80u )
+ {
+ *utf8++ = code;
+ }
+ else if( code < 0x800u )
+ {
+ *utf8++ = static_cast<uint8_t>( code >> 6u ) | 0xc0u; // lead byte for 2 byte sequence
+ *utf8++ = static_cast<uint8_t>( code & 0x3f ) | 0x80u; // continuation byte
+ }
+ else if( code < 0x10000u )
+ {
+ *utf8++ = static_cast<uint8_t>( code >> 12u ) | 0xe0u; // lead byte for 2 byte sequence
+ *utf8++ = static_cast<uint8_t>( ( code >> 6u ) & 0x3f ) | 0x80u; // continuation byte
+ *utf8++ = static_cast<uint8_t>( code & 0x3f ) | 0x80u; // continuation byte
+ }
+ else if( code < 0x200000u )
+ {
+ *utf8++ = static_cast<uint8_t>( code >> 18u ) | 0xf0u; // lead byte for 2 byte sequence
+ *utf8++ = static_cast<uint8_t>( ( code >> 12u ) & 0x3f ) | 0x80u; // continuation byte
+ *utf8++ = static_cast<uint8_t>( ( code >> 6u ) & 0x3f ) | 0x80u; // continuation byte
+ *utf8++ = static_cast<uint8_t>( code & 0x3f ) | 0x80u; // continuation byte
+ }
+ }
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_CHARACTER_SET_CONVERSION_H__
+#define __DALI_TOOLKIT_CHARACTER_SET_CONVERSION_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+
+// EXTERNAL INCLUDES
+#include <stdint.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+/**
+ * @brief Retrieves the number of characters of the text array encoded in UTF8
+ *
+ * @param[in] utf8 The pointer to the UTF8 array.
+ * @param[in] length The length of the UTF8 array.
+ *
+ * @return The number of characters.
+ */
+DALI_IMPORT_API uint32_t GetNumberOfUtf8Characters( const uint8_t* const utf8, uint32_t length );
+
+/**
+ * @brief Retrieves the number of bytes needed to encode in UTF8 the given text array encoded in UTF32.
+ *
+ * @param[in] utf32 The pointer to the UTF32 array.
+ * @param[in] numberOfCharacters The number of characters of the UTF32 array.
+ *
+ * @return The number of bytes.
+ */
+DALI_IMPORT_API uint32_t GetNumberOfUtf8Bytes( const uint32_t* const utf32, uint32_t numberOfCharacters );
+
+/**
+ * @brief Converts a text array encoded in UTF8 into a text array encoded in UTF32.
+ *
+ * The @p utf32 buffer needs to be big enough to store all the characters.
+ *
+ * @param[in] utf8 The pointer to the UTF8 array.
+ * @param[in] length The length of the UTF8 array.
+ * @param[out] utf32 The pointer to the UTF32 array.
+ *
+ * @return The number of characters.
+ */
+DALI_IMPORT_API uint32_t Utf8ToUtf32( const uint8_t* const utf8, uint32_t length, uint32_t* utf32 );
+
+/**
+ * @brief Converts a text array encoded in UTF32 into a text array encoded in UTF8.
+ *
+ * The @p utf8 buffer needs to be big enough to store all the characters.
+ *
+ * @param[in] utf32 The pointer to the UTF32 array.
+ * @param[in] numberOfCharacters The number of characters of the UTF32 array.
+ * @param[out] utf8 The pointer to the UTF8 array.
+ */
+DALI_IMPORT_API void Utf32ToUtf8( const uint32_t* const utf32, uint32_t numberOfCharacters, uint32_t* utf8 );
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_CHARACTER_SET_CONVERSION_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/decorator/text-decorator.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/adaptor-framework/timer.h>
+#include <dali/public-api/actors/image-actor.h>
+#include <dali/public-api/actors/layer.h>
+#include <dali/public-api/common/constants.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/events/tap-gesture.h>
+#include <dali/public-api/events/tap-gesture-detector.h>
+#include <dali/public-api/events/pan-gesture.h>
+#include <dali/public-api/events/pan-gesture-detector.h>
+#include <dali/public-api/images/resource-image.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/math/vector4.h>
+#include <dali/public-api/signals/connection-tracker.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+
+#ifdef DEBUG_ENABLED
+#define DECORATOR_DEBUG
+#endif
+
+// Local Data
+namespace
+{
+
+const char* DEFAULT_GRAB_HANDLE_IMAGE( DALI_IMAGE_DIR "insertpoint-icon.png" );
+const char* DEFAULT_SELECTION_HANDLE_ONE( DALI_IMAGE_DIR "text-input-selection-handle-left.png" );
+const char* DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
+//const char* DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" );
+//const char* DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" );
+const char* DEFAULT_CURSOR_IMAGE( DALI_IMAGE_DIR "decorator-cursor.png");
+
+const Dali::Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SIZE( 1.5f, 2.0f, 1.0f );
+const Dali::Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE( 1.5f, 1.5f, 1.0f );
+
+const std::size_t CURSOR_BLINK_INTERVAL = 500; // Cursor blink interval
+const std::size_t MILLISECONDS = 1000;
+
+} // end of namespace
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct Decorator::Impl : public ConnectionTracker
+{
+ struct CursorImpl
+ {
+ CursorImpl()
+ : x(0.0f),
+ y(0.0f),
+ height(0.0f),
+ color(Dali::Color::WHITE)
+ {
+ }
+
+ float x;
+ float y;
+ float height;
+
+ Vector4 color;
+ };
+
+ struct SelectionHandleImpl
+ {
+ SelectionHandleImpl()
+ : x(0.0f),
+ y(0.0f),
+ cursorHeight(0.0f),
+ flipped(false)
+ {
+ }
+
+ float x;
+ float y;
+ float cursorHeight; ///< Not the handle height
+ bool flipped;
+
+ ImageActor actor;
+ Actor grabArea;
+
+ Image pressedImage;
+ Image releasedImage;
+ };
+
+ Impl( Dali::Toolkit::Internal::Control& parent, Observer& observer )
+ : mParent(parent),
+ mObserver(observer),
+ mActiveCursor(ACTIVE_CURSOR_NONE),
+ mActiveGrabHandle(false),
+ mActiveSelection( false ),
+ mCursorBlinkInterval( CURSOR_BLINK_INTERVAL ),
+ mCursorBlinkDuration( 0.0f ),
+ mCursorBlinkStatus( true ),
+ mGrabDisplacementX( 0.0f ),
+ mGrabDisplacementY( 0.0f ),
+ mBoundingBox( Rect<int>() )
+ {
+ }
+
+ /**
+ * Relayout of the decorations owned by the decorator.
+ * @param[in] size The Size of the UI control the decorater is adding it's decorations to.
+ */
+ void Relayout( const Vector2& size )
+ {
+ SetCursors();
+
+ // Show or hide the grab handle
+ if( mActiveGrabHandle )
+ {
+ SetupTouchEvents();
+
+ CreateActiveLayer();
+ CreateGrabHandle();
+
+ mGrabHandle.SetPosition( mCursor[PRIMARY_CURSOR].x, mCursor[PRIMARY_CURSOR].y + mCursor[PRIMARY_CURSOR].height );
+ }
+ else if( mGrabHandle )
+ {
+ UnparentAndReset( mGrabHandle );
+ }
+
+ // Show or hide the selection handles/highlight
+ if( mActiveSelection )
+ {
+ SetupTouchEvents();
+
+ CreateActiveLayer();
+ CreateSelectionHandles();
+
+ SelectionHandleImpl& primary = mSelectionHandle[ PRIMARY_SELECTION_HANDLE ];
+ primary.actor.SetPosition( primary.x, primary.y + primary.cursorHeight );
+
+ SelectionHandleImpl& secondary = mSelectionHandle[ SECONDARY_SELECTION_HANDLE ];
+ secondary.actor.SetPosition( secondary.x, secondary.y + secondary.cursorHeight );
+
+ //CreateHighlight(); TODO
+ }
+ else
+ {
+ UnparentAndReset( mSelectionHandle[ PRIMARY_SELECTION_HANDLE ].actor );
+ UnparentAndReset( mSelectionHandle[ SECONDARY_SELECTION_HANDLE ].actor );
+ }
+ }
+
+ /**
+ * Creates a cursor
+ */
+ void CreateCursor( ImageActor& cursor )
+ {
+ if ( !mCursorImage )
+ {
+ mCursorImage = ResourceImage::New( DEFAULT_CURSOR_IMAGE );
+ }
+ cursor = ImageActor::New( mCursorImage );
+ cursor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ }
+
+ /**
+ * Add / Remove cursor(s) from parent
+ */
+ void SetCursors()
+ {
+ Actor parent = mParent.Self();
+ /* Create Primary and or Secondary Cursor(s) if active and add to parent */
+ if ( mActiveCursor == ACTIVE_CURSOR_PRIMARY )
+ {
+ if ( !mPrimaryCursor )
+ {
+ CreateCursor( mPrimaryCursor );
+#ifdef DECORATOR_DEBUG
+ mPrimaryCursor.SetName( "PrimaryCursorActor" );
+#endif
+ parent.Add( mPrimaryCursor);
+ }
+
+ mPrimaryCursor.SetPosition( mCursor[PRIMARY_CURSOR].x, mCursor[PRIMARY_CURSOR].y );
+ }
+ else if ( mActiveCursor == ACTIVE_CURSOR_BOTH )
+ {
+ if ( !mSecondaryCursor )
+ {
+ CreateCursor( mSecondaryCursor );
+#ifdef DECORATOR_DEBUG
+ mSecondaryCursor.SetName( "SecondaryCursorActor" );
+#endif
+ parent.Add( mSecondaryCursor);
+ }
+ }
+ else
+ {
+ /* ACTIVE_CURSOR_NONE so unparent cursors*/
+ if ( mPrimaryCursor )
+ {
+ UnparentAndReset( mPrimaryCursor );
+ }
+
+ if ( mSecondaryCursor )
+ {
+ UnparentAndReset( mSecondaryCursor );
+ }
+ }
+ }
+
+ bool OnCursorBlinkTimerTick()
+ {
+ // Cursor blinking
+ if ( ACTIVE_CURSOR_PRIMARY )
+ {
+ mPrimaryCursor.SetVisible( mCursorBlinkStatus );
+ }
+ else if ( ACTIVE_CURSOR_BOTH )
+ {
+ mPrimaryCursor.SetVisible( mCursorBlinkStatus );
+ mSecondaryCursor.SetVisible( mCursorBlinkStatus );
+ }
+
+ mCursorBlinkStatus = !mCursorBlinkStatus;
+
+ return true;
+ }
+
+ void SetupTouchEvents()
+ {
+ if ( !mTapDetector )
+ {
+ mTapDetector = TapGestureDetector::New();
+ mTapDetector.DetectedSignal().Connect( this, &Decorator::Impl::OnTap );
+ }
+
+ if ( !mPanGestureDetector )
+ {
+ mPanGestureDetector = PanGestureDetector::New();
+ mPanGestureDetector.DetectedSignal().Connect( this, &Decorator::Impl::OnPan );
+ }
+ }
+
+ void CreateActiveLayer()
+ {
+ if( !mActiveLayer )
+ {
+ Actor parent = mParent.Self();
+
+ mActiveLayer = Layer::New();
+#ifdef DECORATOR_DEBUG
+ mActiveLayer.SetName ( "ActiveLayerActor" );
+#endif
+
+ mActiveLayer.SetAnchorPoint( AnchorPoint::CENTER);
+ mActiveLayer.SetParentOrigin( ParentOrigin::CENTER);
+ mActiveLayer.SetSizeMode( SIZE_EQUAL_TO_PARENT );
+ mActiveLayer.SetPositionInheritanceMode( USE_PARENT_POSITION );
+
+ parent.Add( mActiveLayer );
+ }
+
+ mActiveLayer.RaiseToTop();
+ }
+
+ void CreateGrabHandle()
+ {
+ if( !mGrabHandle )
+ {
+ if ( !mGrabHandleImage )
+ {
+ mGrabHandleImage = ResourceImage::New( DEFAULT_GRAB_HANDLE_IMAGE );
+ }
+
+ mGrabHandle = ImageActor::New( mGrabHandleImage );
+#ifdef DECORATOR_DEBUG
+ mGrabHandle.SetName( "GrabHandleActor" );
+#endif
+ mGrabHandle.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ mGrabHandle.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ mGrabHandle.SetDrawMode( DrawMode::OVERLAY );
+
+ mGrabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
+#ifdef DECORATOR_DEBUG
+ mGrabArea.SetName( "GrabArea" );
+#endif
+ mGrabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
+ mGrabArea.SetSizeMode( SIZE_RELATIVE_TO_PARENT );
+ mGrabArea.SetSizeModeFactor( DEFAULT_GRAB_HANDLE_RELATIVE_SIZE );
+ mGrabHandle.Add(mGrabArea);
+
+ mTapDetector.Attach( mGrabArea );
+ mPanGestureDetector.Attach( mGrabArea );
+
+ mActiveLayer.Add(mGrabHandle);
+ }
+ }
+
+ void CreateSelectionHandles()
+ {
+ SelectionHandleImpl& primary = mSelectionHandle[ PRIMARY_SELECTION_HANDLE ];
+ if ( !primary.actor )
+ {
+ if ( !primary.releasedImage )
+ {
+ primary.releasedImage = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE );
+ }
+
+ primary.actor = ImageActor::New( primary.releasedImage );
+#ifdef DECORATOR_DEBUG
+ primary.actor.SetName("SelectionHandleOne");
+#endif
+ primary.actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ primary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text.
+ primary.actor.SetDrawMode( DrawMode::OVERLAY ); // ensure grab handle above text
+ primary.flipped = false;
+
+ primary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
+#ifdef DECORATOR_DEBUG
+ primary.grabArea.SetName("SelectionHandleOneGrabArea");
+#endif
+ primary.grabArea.SetSizeMode( SIZE_RELATIVE_TO_PARENT );
+ primary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
+ primary.grabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
+
+ mTapDetector.Attach( primary.grabArea );
+ mPanGestureDetector.Attach( primary.grabArea );
+ primary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched );
+
+ primary.actor.Add( primary.grabArea );
+ mActiveLayer.Add( primary.actor );
+ }
+
+ SelectionHandleImpl& secondary = mSelectionHandle[ SECONDARY_SELECTION_HANDLE ];
+ if ( !secondary.actor )
+ {
+ if ( !secondary.releasedImage )
+ {
+ secondary.releasedImage = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO );
+ }
+
+ secondary.actor = ImageActor::New( secondary.releasedImage );
+#ifdef DECORATOR_DEBUG
+ secondary.actor.SetName("SelectionHandleTwo");
+#endif
+ secondary.actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ secondary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text.
+ secondary.actor.SetDrawMode( DrawMode::OVERLAY ); // ensure grab handle above text
+ secondary.flipped = false;
+
+ secondary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
+#ifdef DECORATOR_DEBUG
+ secondary.grabArea.SetName("SelectionHandleTwoGrabArea");
+#endif
+ secondary.grabArea.SetSizeMode( SIZE_RELATIVE_TO_PARENT );
+ secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
+ secondary.grabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
+
+ mTapDetector.Attach( secondary.grabArea );
+ mPanGestureDetector.Attach( secondary.grabArea );
+ secondary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched );
+
+ secondary.actor.Add( secondary.grabArea );
+ mActiveLayer.Add( secondary.actor );
+ }
+
+ //SetUpHandlePropertyNotifications(); TODO
+ }
+
+ void OnTap( Actor actor, const TapGesture& tap )
+ {
+ if( actor == mGrabHandle )
+ {
+ // TODO
+ }
+ }
+
+ void OnPan( Actor actor, const PanGesture& gesture )
+ {
+ if( actor == mGrabArea )
+ {
+ if( Gesture::Started == gesture.state )
+ {
+ mGrabDisplacementX = mGrabDisplacementY = 0;
+ }
+
+ mGrabDisplacementX += gesture.displacement.x;
+ mGrabDisplacementY += gesture.displacement.y;
+
+ float x = mCursor[PRIMARY_CURSOR].x + mGrabDisplacementX;
+ float y = mCursor[PRIMARY_CURSOR].y + mCursor[PRIMARY_CURSOR].height*0.5f + mGrabDisplacementY;
+
+ if( Gesture::Started == gesture.state ||
+ Gesture::Continuing == gesture.state )
+ {
+ mObserver.GrabHandleEvent( GRAB_HANDLE_PRESSED, x, y );
+ }
+ else if( Gesture::Finished == gesture.state ||
+ Gesture::Cancelled == gesture.state )
+ {
+ mObserver.GrabHandleEvent( GRAB_HANDLE_RELEASED, x, y );
+ }
+ }
+ }
+
+ bool OnHandleOneTouched( Actor actor, const TouchEvent& touch )
+ {
+ // TODO
+ return false;
+ }
+
+ bool OnHandleTwoTouched( Actor actor, const TouchEvent& touch )
+ {
+ // TODO
+ return false;
+ }
+
+ Internal::Control& mParent;
+ Observer& mObserver;
+
+ Layer mActiveLayer; // Layer for active handles and alike that ensures they are above all else.
+
+ unsigned int mActiveCursor;
+ bool mActiveGrabHandle;
+ bool mActiveSelection;
+
+ CursorImpl mCursor[CURSOR_COUNT];
+
+ Timer mCursorBlinkTimer; // Timer to signal cursor to blink
+ unsigned int mCursorBlinkInterval;
+ float mCursorBlinkDuration;
+ bool mCursorBlinkStatus; // Flag to switch between blink on and blink off
+
+ ImageActor mPrimaryCursor;
+ ImageActor mSecondaryCursor;
+
+ ImageActor mGrabHandle;
+ Actor mGrabArea;
+ float mGrabDisplacementX;
+ float mGrabDisplacementY;
+
+ SelectionHandleImpl mSelectionHandle[SELECTION_HANDLE_COUNT];
+
+ Image mCursorImage;
+ Image mGrabHandleImage;
+
+ TapGestureDetector mTapDetector;
+ PanGestureDetector mPanGestureDetector;
+
+ Rect<int> mBoundingBox;
+};
+
+DecoratorPtr Decorator::New( Internal::Control& parent, Observer& observer )
+{
+ return DecoratorPtr( new Decorator(parent, observer) );
+}
+
+void Decorator::SetBoundingBox( const Rect<int>& boundingBox )
+{
+ mImpl->mBoundingBox = boundingBox;
+}
+
+const Rect<int>& Decorator::GetBoundingBox() const
+{
+ return mImpl->mBoundingBox;
+}
+
+void Decorator::Relayout( const Vector2& size )
+{
+ mImpl->Relayout( size );
+}
+
+/** Cursor **/
+
+void Decorator::SetActiveCursor( ActiveCursor activeCursor )
+{
+ mImpl->mActiveCursor = activeCursor;
+}
+
+unsigned int Decorator::GetActiveCursor() const
+{
+ return mImpl->mActiveCursor;
+}
+
+void Decorator::SetPosition( Cursor cursor, float x, float y, float height )
+{
+ // Adjust grab handle displacement
+ mImpl->mGrabDisplacementX -= x - mImpl->mCursor[cursor].x;
+ mImpl->mGrabDisplacementY -= y - mImpl->mCursor[cursor].y;
+
+ mImpl->mCursor[cursor].x = x;
+ mImpl->mCursor[cursor].y = y;
+ mImpl->mCursor[cursor].height = height;
+}
+
+void Decorator::GetPosition( Cursor cursor, float& x, float& y, float& height ) const
+{
+ x = mImpl->mCursor[cursor].x;
+ y = mImpl->mCursor[cursor].y;
+ height = mImpl->mCursor[cursor].height;
+}
+
+void Decorator::SetCursorImage( Dali::Image image )
+{
+ mImpl->mCursorImage = image;
+}
+
+Dali::Image Decorator::GetCursorImage() const
+{
+ return mImpl->mCursorImage;
+}
+
+void Decorator::SetColor( Cursor cursor, const Dali::Vector4& color )
+{
+ mImpl->mCursor[cursor].color = color;
+}
+
+const Dali::Vector4& Decorator::GetColor( Cursor cursor ) const
+{
+ return mImpl->mCursor[cursor].color;
+}
+
+void Decorator::StartCursorBlink()
+{
+ if ( !mImpl->mCursorBlinkTimer )
+ {
+ mImpl->mCursorBlinkTimer = Timer::New( mImpl->mCursorBlinkInterval );
+ mImpl->mCursorBlinkTimer.TickSignal().Connect( mImpl, &Decorator::Impl::OnCursorBlinkTimerTick );
+ }
+
+ if ( !mImpl->mCursorBlinkTimer.IsRunning() )
+ {
+ mImpl->mCursorBlinkTimer.Start();
+ }
+}
+
+void Decorator::StopCursorBlink()
+{
+ if ( mImpl->mCursorBlinkTimer )
+ {
+ mImpl->mCursorBlinkTimer.Stop();
+ }
+}
+
+void Decorator::SetCursorBlinkInterval( float seconds )
+{
+ mImpl->mCursorBlinkInterval = seconds*MILLISECONDS; // Convert to milliseconds
+}
+
+float Decorator::GetCursorBlinkInterval() const
+{
+ return mImpl->mCursorBlinkInterval;
+}
+
+void Decorator::SetCursorBlinkDuration( float seconds )
+{
+ mImpl->mCursorBlinkDuration = seconds;
+}
+
+float Decorator::GetCursorBlinkDuration() const
+{
+ return mImpl->mCursorBlinkDuration;
+}
+
+/** GrabHandle **/
+
+void Decorator::SetGrabHandleActive( bool active )
+{
+ mImpl->mActiveGrabHandle = active;
+}
+
+bool Decorator::IsGrabHandleActive() const
+{
+ return mImpl->mActiveGrabHandle;
+}
+
+void Decorator::SetGrabHandleImage( Dali::Image image )
+{
+ mImpl->mGrabHandleImage = image;
+}
+
+Dali::Image Decorator::GetGrabHandleImage() const
+{
+ return mImpl->mGrabHandleImage;
+}
+
+/** Selection **/
+
+void Decorator::SetSelectionActive( bool active )
+{
+ mImpl->mActiveSelection = active;
+}
+
+bool Decorator::IsSelectionActive() const
+{
+ return mImpl->mActiveSelection;
+}
+
+void Decorator::SetPosition( SelectionHandle handle, float x, float y, float height )
+{
+ mImpl->mSelectionHandle[handle].x = x;
+ mImpl->mSelectionHandle[handle].y = y;
+ mImpl->mSelectionHandle[handle].cursorHeight = height;
+}
+
+void Decorator::GetPosition( SelectionHandle handle, float& x, float& y, float& height ) const
+{
+ x = mImpl->mSelectionHandle[handle].x;
+ y = mImpl->mSelectionHandle[handle].y;
+ height = mImpl->mSelectionHandle[handle].cursorHeight;
+}
+
+void Decorator::SetImage( SelectionHandle handle, SelectionHandleState state, Dali::Image image )
+{
+ if( SELECTION_HANDLE_PRESSED == state )
+ {
+ mImpl->mSelectionHandle[handle].pressedImage = image;
+ }
+ else
+ {
+ mImpl->mSelectionHandle[handle].releasedImage = image;
+ }
+}
+
+Dali::Image Decorator::GetImage( SelectionHandle handle, SelectionHandleState state ) const
+{
+ if( SELECTION_HANDLE_PRESSED == state )
+ {
+ return mImpl->mSelectionHandle[handle].pressedImage;
+ }
+
+ return mImpl->mSelectionHandle[handle].releasedImage;
+}
+
+Decorator::~Decorator()
+{
+ delete mImpl;
+}
+
+Decorator::Decorator( Dali::Toolkit::Internal::Control& parent, Observer& observer )
+: mImpl( NULL )
+{
+ mImpl = new Decorator::Impl( parent, observer );
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_DECORATOR_H__
+#define __DALI_TOOLKIT_TEXT_DECORATOR_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/math/rect.h>
+
+namespace Dali
+{
+
+class Image;
+class Vector2;
+class Vector4;
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+class Control;
+}
+
+namespace Text
+{
+
+class Decorator;
+typedef IntrusivePtr<Decorator> DecoratorPtr;
+
+// Used to set the cursor positions etc.
+enum Cursor
+{
+ PRIMARY_CURSOR, ///< The primary cursor for bidirectional text (or the regular cursor for single-direction text)
+ SECONDARY_CURSOR, ///< The secondary cursor for bidirectional text
+ CURSOR_COUNT
+};
+
+// Determines which of the cursors are active (if any).
+enum ActiveCursor
+{
+ ACTIVE_CURSOR_NONE, ///< Neither primary nor secondary cursor are active
+ ACTIVE_CURSOR_PRIMARY, ///< Primary cursor is active (only)
+ ACTIVE_CURSOR_BOTH ///< Both primary and secondary cursor are active
+};
+
+// The state information for grab handle events
+enum GrabHandleState
+{
+ GRAB_HANDLE_TAPPED,
+ GRAB_HANDLE_PRESSED,
+ GRAB_HANDLE_RELEASED
+};
+
+// The set the selection-handle positions etc.
+enum SelectionHandle
+{
+ PRIMARY_SELECTION_HANDLE,
+ SECONDARY_SELECTION_HANDLE,
+ SELECTION_HANDLE_COUNT
+};
+
+enum SelectionHandleState
+{
+ SELECTION_HANDLE_PRESSED,
+ SELECTION_HANDLE_RELEASED
+};
+
+/**
+ * @brief A Text Decorator is used to display cursors, handles, selection highlights and pop-ups.
+ *
+ * The decorator is responsible for clipping decorations which are positioned outside of the parent area.
+ * In some cases the decorations will be moved or flipped around, to maintain visibility on-screen.
+ *
+ * Decorator components forward input events to a controller class through an observer interface.
+ * The controller is responsible for selecting which components are active.
+ */
+class Decorator : public RefObject
+{
+public:
+
+ class Observer
+ {
+ public:
+
+ /**
+ * @brief Constructor.
+ */
+ Observer() {};
+
+ /**
+ * @brief Virtual destructor.
+ */
+ virtual ~Observer() {};
+
+ /**
+ * @brief An input event from the grab handle.
+ *
+ * @param[in] state The grab handle state.
+ * @param[in] x The x position relative to the top-left of the parent control.
+ * @param[in] y The y position relative to the top-left of the parent control.
+ */
+ virtual void GrabHandleEvent( GrabHandleState state, float x, float y ) = 0;
+ };
+
+ /**
+ * @brief Create a new instance of a Decorator.
+ *
+ * @param[in] parent Decorations will be added to this parent control.
+ * @param[in] observer A class which receives input events from Decorator components.
+ * @return A pointer to a new Decorator.
+ */
+ static DecoratorPtr New( Dali::Toolkit::Internal::Control& parent, Observer& observer );
+
+ /**
+ * @brief Set the bounding box which handles, popup and similar decorations will not exceed.
+ *
+ * The default value is the width and height of the stage from the top left origin.
+ * If a title bar for example is on the top of the screen then the y should be the title's height and
+ * the boundary height the stage height minus the title's height.
+ * Restrictions - The boundary box should be set up with a fixed z position for the text-input and the default camera.
+ *
+ * ------------------------------------------
+ * |(x,y) |
+ * |o---------------------------------------|
+ * || ||
+ * || Bounding Box || boundary height
+ * || ||
+ * |----------------------------------------|
+ * ------------------------------------------
+ * boundary width
+ *
+ * @param[in] boundingBox Vector( x coordinate, y coordinate, width, height )
+ */
+ void SetBoundingBox( const Rect<int>& boundingBox );
+
+ /**
+ * @brief Retrieve the bounding box origin and dimensions.
+ *
+ * default is set once control is added to stage, before this the return vector will be Vector4:ZERO
+ * @return Rect<int> the bounding box origin, width and height
+ */
+ const Rect<int>& GetBoundingBox() const;
+
+ /**
+ * @brief The decorator waits until a relayout before creating actors etc.
+ *
+ * @param[in] size The size of the parent control after size-negotiation.
+ */
+ void Relayout( const Dali::Vector2& size );
+
+ /**
+ * @brief Sets which of the cursors are active.
+ *
+ * @note Cursor will only be visible if within the parent area.
+ * @param[in] activeCursor Which of the cursors should be active (if any).
+ */
+ void SetActiveCursor( ActiveCursor activeCursor );
+
+ /**
+ * @brief Query which of the cursors are active.
+ *
+ * @return Which of the cursors are active (if any).
+ */
+ unsigned int GetActiveCursor() const;
+
+ /**
+ * @brief Sets the position of a cursor.
+ *
+ * @param[in] cursor The cursor to set.
+ * @param[in] x The x position relative to the top-left of the parent control.
+ * @param[in] y The y position relative to the top-left of the parent control.
+ * @param[in] height The logical height of the cursor.
+ */
+ void SetPosition( Cursor cursor, float x, float y, float height );
+
+ /**
+ * @brief Retrieves the position of a cursor.
+ *
+ * @param[in] cursor The cursor to get.
+ * @param[out] x The x position relative to the top-left of the parent control.
+ * @param[out] y The y position relative to the top-left of the parent control.
+ * @param[out] height The logical height of the cursor.
+ */
+ void GetPosition( Cursor cursor, float& x, float& y, float& height ) const;
+
+ /**
+ * @brief Sets the image for a cursor.
+ *
+ * @param[in] image The image to use.
+ */
+ void SetCursorImage( Dali::Image image );
+
+ /**
+ * @brief Retrieves the image for a cursor.
+ *
+ * @return The cursor image.
+ */
+ Dali::Image GetCursorImage() const;
+
+ /**
+ * @brief Sets the color for a cursor.
+ *
+ * @param[in] cursor Whether this color is for the primary or secondary cursor.
+ * @param[in] color The color to use.
+ */
+ void SetColor( Cursor cursor, const Dali::Vector4& color );
+
+ /**
+ * @brief Retrieves the color for a cursor.
+ *
+ * @param[in] cursor Whether this color is for the primary or secondary cursor.
+ * @return The cursor color.
+ */
+ const Dali::Vector4& GetColor( Cursor cursor ) const;
+
+ /**
+ * @brief Start blinking the cursor; see also SetCursorBlinkDuration().
+ */
+ void StartCursorBlink();
+
+ /**
+ * @brief Stop blinking the cursor.
+ */
+ void StopCursorBlink();
+
+ /**
+ * @brief Set the interval between cursor blinks.
+ *
+ * @param[in] seconds The interval in seconds.
+ */
+ void SetCursorBlinkInterval( float seconds );
+
+ /**
+ * @brief Retrieves the blink-interval for a cursor.
+ *
+ * @return The cursor blink-interval.
+ */
+ float GetCursorBlinkInterval() const;
+
+ /**
+ * @brief The cursor will stop blinking after this duration.
+ *
+ * @param[in] seconds The duration in seconds.
+ */
+ void SetCursorBlinkDuration( float seconds );
+
+ /**
+ * @brief Retrieves the blink-duration for a cursor.
+ *
+ * @return The cursor blink-duration.
+ */
+ float GetCursorBlinkDuration() const;
+
+ /**
+ * @brief Sets whether the grab handle is active.
+ *
+ * @note The grab handle follows the cursor position set with SetPosition(Cursor, ...)
+ * @param[in] active True if the grab handle should be active.
+ */
+ void SetGrabHandleActive( bool active );
+
+ /**
+ * @brief Query whether the grab handle is active.
+ *
+ * @return True if the grab handle should be active.
+ */
+ bool IsGrabHandleActive() const;
+
+ /**
+ * @brief Sets the image for the grab handle.
+ *
+ * @param[in] image The image to use.
+ */
+ void SetGrabHandleImage( Dali::Image image );
+
+ /**
+ * @brief Retrieves the image for the grab handle.
+ *
+ * @return The grab handle image.
+ */
+ Dali::Image GetGrabHandleImage() const;
+
+ /**
+ * @brief Sets whether the selection handles and highlight are active.
+ *
+ * @param[in] active True if the selection handles and highlight are active.
+ */
+ void SetSelectionActive( bool active );
+
+ /**
+ * @brief Query whether the selection handles and highlight are active.
+ *
+ * @return True if the selection handles and highlight are active.
+ */
+ bool IsSelectionActive() const;
+
+ /**
+ * @brief Sets the position of a selection handle.
+ *
+ * @param[in] handle The handle to set.
+ * @param[in] x The x position relative to the top-left of the parent control.
+ * @param[in] y The y position relative to the top-left of the parent control.
+ * @param[in] cursorHeight The logical cursor height at this position.
+ */
+ void SetPosition( SelectionHandle handle, float x, float y, float cursorHeight );
+
+ /**
+ * @brief Retrieves the position of a selection handle.
+ *
+ * @param[in] handle The handle to get.
+ * @param[out] x The x position relative to the top-left of the parent control.
+ * @param[out] y The y position relative to the top-left of the parent control.
+ * @param[out] cursorHeight The logical cursor height at this position.
+ */
+ void GetPosition( SelectionHandle handle, float& x, float& y, float& cursorHeight ) const;
+
+ /**
+ * @brief Sets the image for one of the selection handles.
+ *
+ * @param[in] handle The selection handle.
+ * @param[in] state A different image can be set for the pressed/released states.
+ * @param[in] image The image to use.
+ */
+ void SetImage( SelectionHandle handle, SelectionHandleState state, Dali::Image image );
+
+ /**
+ * @brief Retrieves the image for a selection handle.
+ *
+ * @param[in] handle The selection handle.
+ * @param[in] state A different image can be set for the pressed/released states.
+ * @return The image.
+ */
+ Dali::Image GetImage( SelectionHandle handle, SelectionHandleState state ) const;
+
+protected:
+
+ /**
+ * @brief A reference counted object may only be deleted by calling Unreference().
+ */
+ virtual ~Decorator();
+
+private:
+
+ /**
+ * @brief Private constructor.
+ * @param[in] parent Decorations will be added to this parent control.
+ * @param[in] observer A class which receives input events from Decorator components.
+ */
+ Decorator(Dali::Toolkit::Internal::Control& parent, Observer& observer );
+
+ // Undefined
+ Decorator( const Decorator& handle );
+
+ // Undefined
+ Decorator& operator=( const Decorator& handle );
+
+private:
+
+ struct Impl;
+ Impl* mImpl;
+};
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_DECORATOR_H__
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_FONT_RUN_H__
+#define __DALI_TOOLKIT_TEXT_FONT_RUN_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/character-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Run of characters with the same font.
+ */
+struct FontRun
+{
+ CharacterRun characterRun; ///< The initial character index and the number of characters of the run.
+ FontId fontId; ///< Font id of the run.
+ bool isDefault; ///< Whether the font is a default font not defined by the user.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_FONT_RUN_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/layouts/layout-engine.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/text-abstraction/font-client.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/logical-model.h>
+#include <dali-toolkit/public-api/text/visual-model.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct LayoutEngine::Impl
+{
+ Impl()
+ : mLayout( LayoutEngine::SINGLE_LINE_BOX )
+ {
+ mFontClient = TextAbstraction::FontClient::Get();
+ }
+
+ void UpdateVisualModel( const Vector2& boundingBox,
+ const Vector<GlyphInfo>& glyphs,
+ const Vector<CharacterIndex>& characterIndices,
+ const Vector<Length>& charactersPerGlyph,
+ VisualModel& visualModel )
+ {
+ // TODO Switch between different layouts
+
+ visualModel.SetGlyphs( &glyphs[0],
+ &characterIndices[0],
+ &charactersPerGlyph[0],
+ glyphs.Count() );
+
+ UpdateGlyphPositions( boundingBox, visualModel );
+ }
+
+ void UpdateGlyphPositions( const Vector2& boundingBox, VisualModel& visualModel )
+ {
+ if( LayoutEngine::SINGLE_LINE_BOX == mLayout )
+ {
+ SingleLineLayout( boundingBox, visualModel );
+ }
+ else
+ {
+ MultiLineLayout( boundingBox, visualModel );
+ }
+ }
+
+ // TODO - Rewrite this to handle bidi
+ void SingleLineLayout( const Vector2& boundingBox, VisualModel& visualModel )
+ {
+ Length glyphCount = visualModel.GetNumberOfGlyphs();
+
+ std::vector<Vector2> glyphPositions;
+ glyphPositions.reserve( glyphCount );
+
+ if( glyphCount > 0 )
+ {
+ // FIXME Single font assumption
+ Text::FontMetrics fontMetrics;
+ GlyphInfo firstGlyph;
+ visualModel.GetGlyphs( &firstGlyph, 0, 1 );
+ mFontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics );
+
+ float penX( 0 );
+ float penY( fontMetrics.ascender ); // Move to baseline
+
+ for( unsigned int i=0; i<glyphCount; ++i )
+ {
+ GlyphInfo glyph;
+ visualModel.GetGlyphs( &glyph, i, 1 );
+
+ glyphPositions.push_back( Vector2( penX + glyph.xBearing,
+ penY - glyph.yBearing ) );
+
+ penX += glyph.advance;
+ }
+
+ visualModel.SetGlyphPositions( &glyphPositions[0], glyphCount );
+
+ visualModel.SetActualSize( Vector2(penX, fontMetrics.height) );
+ }
+ }
+
+ // TODO - Rewrite this to handle bidi
+ void MultiLineLayout( const Vector2& boundingBox, VisualModel& visualModel )
+ {
+ Length glyphCount = visualModel.GetNumberOfGlyphs();
+
+ std::vector<Vector2> glyphPositions;
+ glyphPositions.reserve( glyphCount );
+
+ if( glyphCount > 0 )
+ {
+ Size actualSize;
+
+ // FIXME Single font assumption
+ Text::FontMetrics fontMetrics;
+ GlyphInfo firstGlyph;
+ visualModel.GetGlyphs( &firstGlyph, 0, 1 );
+ mFontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics );
+
+ float penX( 0 );
+ float penY( fontMetrics.ascender ); // Move to baseline
+
+ unsigned int i=0;
+ while( i < glyphCount )
+ {
+ // Skip initial whitespace
+ for( ; i<glyphCount; ++i )
+ {
+ GlyphInfo glyph;
+ visualModel.GetGlyphs( &glyph, i, 1 );
+
+ if( glyph.width > 0 &&
+ glyph.height > 0 )
+ {
+ break;
+ }
+ else
+ {
+ glyphPositions.push_back( Vector2( penX + glyph.xBearing,
+ penY - glyph.yBearing ) );
+ }
+ }
+
+ // Find last glyph for the next line
+ unsigned int endIndex = i;
+ float endPenX = penX;
+ unsigned int j=i;
+ for( ; j<glyphCount; ++j )
+ {
+ GlyphInfo glyph;
+ visualModel.GetGlyphs( &glyph, j, 1 );
+
+ endPenX += glyph.advance;
+
+ if( glyph.width <= 0 ||
+ glyph.height <= 0 )
+ {
+ // Potential line end found
+ endIndex = j;
+ }
+ else if( endPenX > boundingBox.width )
+ {
+ break;
+ }
+ }
+
+ actualSize.width = ( actualSize.width < endPenX ) ? endPenX : actualSize.width;
+
+ // If end of text or no whitespace found
+ if( glyphCount == j ||
+ endIndex == i )
+ {
+ endIndex = j;
+ }
+
+ for( ; i<endIndex; ++i )
+ {
+ GlyphInfo glyph;
+ visualModel.GetGlyphs( &glyph, i, 1 );
+
+ glyphPositions.push_back( Vector2( penX + glyph.xBearing,
+ penY - glyph.yBearing ) );
+
+ penX += glyph.advance;
+ }
+
+ // Go to next line
+ penX = 0;
+ penY += fontMetrics.height;
+
+ actualSize.height += fontMetrics.height;
+ }
+
+ visualModel.SetGlyphPositions( &glyphPositions[0], glyphCount );
+
+ visualModel.SetActualSize( actualSize );
+ }
+ }
+
+ unsigned int mLayout;
+
+ TextAbstraction::FontClient mFontClient;
+};
+
+LayoutEngine::LayoutEngine()
+: mImpl( NULL )
+{
+ mImpl = new LayoutEngine::Impl();
+}
+
+LayoutEngine::~LayoutEngine()
+{
+ delete mImpl;
+}
+
+void LayoutEngine::SetLayout( Layout layout )
+{
+ mImpl->mLayout = layout;
+}
+
+unsigned int LayoutEngine::GetLayout() const
+{
+ return mImpl->mLayout;
+}
+
+void LayoutEngine::UpdateVisualModel( const Vector2& boundingBox,
+ const Vector<GlyphInfo>& glyphs,
+ const Vector<CharacterIndex>& characterIndices,
+ const Vector<Length>& charactersPerGlyph,
+ VisualModel& visualModel )
+{
+ mImpl->UpdateVisualModel( boundingBox,
+ glyphs,
+ characterIndices,
+ charactersPerGlyph,
+ visualModel );
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_LAYOUT_ENGINE_H__
+#define __DALI_TOOLKIT_TEXT_LAYOUT_ENGINE_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDE
+#include <dali-toolkit/public-api/text/text-definitions.h>
+
+// EXTERNAL INCLUDE
+#include <dali/public-api/common/dali-vector.h>
+
+namespace Dali
+{
+
+struct Vector2;
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+class VisualModel;
+
+/**
+ * @brief LayoutEngine is responsible for calculating the visual position of glyphs in layout.
+ */
+class LayoutEngine
+{
+public:
+
+ enum Layout
+ {
+ SINGLE_LINE_BOX,
+ MULTI_LINE_BOX
+ };
+
+ /**
+ * @brief Create a new instance of a LayoutEngine.
+ */
+ LayoutEngine();
+
+ /**
+ * @brief Virtual destructor.
+ */
+ ~LayoutEngine();
+
+ /**
+ * @brief Choose the required layout.
+ *
+ * @param[in] layout The required layout.
+ */
+ void SetLayout( Layout layout );
+
+ /**
+ * @brief Query the required layout.
+ *
+ * @return The required layout.
+ */
+ unsigned int GetLayout() const;
+
+ /**
+ * @brief Store the visual position of glyphs in the VisualModel.
+ *
+ * @param[in] boundingBox The size of the box containing the text.
+ * @param[in] glyphs A vector with glyphs.
+ * @param[in] characterIndices Vector with indices pointing the first character of each glyph.
+ * @param[in] charactersPerGlyph Vector with the number of characters that forms each glyph.
+ * @param[in] visualModel The visual model to update.
+ */
+ void UpdateVisualModel( const Vector2& boundingBox,
+ const Vector<GlyphInfo>& glyphs,
+ const Vector<CharacterIndex>& characterIndices,
+ const Vector<Length>& charactersPerGlyph,
+ VisualModel& visualModel );
+
+private:
+
+ // Undefined
+ LayoutEngine( const LayoutEngine& handle );
+
+ // Undefined
+ LayoutEngine& operator=( const LayoutEngine& handle );
+
+private:
+
+ struct Impl;
+ Impl* mImpl;
+};
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_LAYOUT_ENGINE_H__
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_LINE_RUN_H__
+#define __DALI_TOOLKIT_TEXT_LINE_RUN_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief LineRun
+ */
+struct LineRun
+{
+ GlyphIndex glyphIndex; ///< The initial glyph index.
+ Length numberOfGlyphs; ///< The number of characters of the run.
+ // VCC More info to be added. i.e the size, ...
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_LINE_RUN_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/logical-model.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/bidirectional-line-info-run.h>
+#include <dali-toolkit/public-api/text/bidirectional-paragraph-info-run.h>
+#include <dali-toolkit/public-api/text/font-run.h>
+#include <dali-toolkit/public-api/text/script-run.h>
+
+// EXTERNAL INCLUDES
+#include <memory.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct LogicalModel::Impl
+{
+ Vector<Character> mText;
+ Vector<ScriptRun> mScriptRuns;
+ Vector<FontRun> mFontRuns;
+ Vector<LineBreakInfo> mLineBreakInfo;
+ Vector<WordBreakInfo> mWordBreakInfo;
+};
+
+LogicalModelPtr LogicalModel::New()
+{
+ return LogicalModelPtr( new LogicalModel() );
+}
+
+void LogicalModel::SetText( const Character* const text,
+ Length numberOfCharacters )
+{
+ Vector<Character>& modelText = mImpl->mText;
+ modelText.Resize( numberOfCharacters );
+ memcpy( modelText.Begin(), text, numberOfCharacters * sizeof( Character ) );
+}
+
+Length LogicalModel::GetNumberOfCharacters() const
+{
+ return mImpl->mText.Count();
+}
+
+void LogicalModel::GetText( CharacterIndex characterIndex,
+ Character* text,
+ Length numberOfCharacters ) const
+{
+ Vector<Character>& modelText = mImpl->mText;
+ memcpy( text, modelText.Begin() + characterIndex, numberOfCharacters * sizeof( Character ) );
+}
+
+Character LogicalModel::GetCharacter( CharacterIndex characterIndex ) const
+{
+ return mImpl->mText[characterIndex];
+}
+
+void LogicalModel::SetScripts( const ScriptRun* const scripts,
+ Length numberOfRuns )
+{
+ Vector<ScriptRun>& scriptRuns = mImpl->mScriptRuns;
+ scriptRuns.Resize( numberOfRuns );
+ memcpy( scriptRuns.Begin(), scripts, numberOfRuns * sizeof( ScriptRun ) );
+}
+
+Length LogicalModel::GetNumberOfScriptRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ if( ( 0u == characterIndex ) && ( mImpl->mText.Count() == numberOfCharacters ) )
+ {
+ return mImpl->mScriptRuns.Count();
+ }
+
+ const CharacterIndex charcterEndIndex = characterIndex + numberOfCharacters;
+ Length numberOfScriptRuns = 0u;
+ bool firstIndexFound = false;
+
+ for( Length index = 0u, length = mImpl->mScriptRuns.Count(); index < length; ++index )
+ {
+ const ScriptRun* const scriptRun = mImpl->mScriptRuns.Begin() + index;
+
+ if( !firstIndexFound &&
+ ( characterIndex < scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters ) )
+ {
+ // The character index is within this script run.
+ // Starts the counter of script runs.
+ firstIndexFound = true;
+ }
+
+ if( firstIndexFound )
+ {
+ ++numberOfScriptRuns;
+ if( scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters > charcterEndIndex )
+ {
+ // This script run exceeds the given range. The number of scripts can be returned.
+ return numberOfScriptRuns;
+ }
+ }
+ }
+
+ return numberOfScriptRuns;
+}
+
+void LogicalModel::GetScriptRuns( ScriptRun* scriptRuns,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ // A better implementation can cache the first script run and the number of then when the GetNumberOfScriptRuns() is called.
+
+ Length numberOfScriptRuns = GetNumberOfScriptRuns( characterIndex,
+ numberOfCharacters );
+
+ for( Length index = 0u, length = mImpl->mScriptRuns.Count(); index < length; ++index )
+ {
+ const ScriptRun* const scriptRun = mImpl->mScriptRuns.Begin() + index;
+
+ if( characterIndex < scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters )
+ {
+ memcpy( scriptRuns, scriptRun, sizeof( ScriptRun ) * numberOfScriptRuns );
+ return;
+ }
+ }
+}
+
+Script LogicalModel::GetScript( CharacterIndex characterIndex ) const
+{
+ // If this operation is too slow, consider a binary search.
+
+ for( Length index = 0u, length = mImpl->mScriptRuns.Count(); index < length; ++index )
+ {
+ const ScriptRun* const scriptRun = mImpl->mScriptRuns.Begin() + index;
+
+ if( ( scriptRun->characterRun.characterIndex <= characterIndex ) &&
+ ( characterIndex < scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters ) )
+ {
+ return scriptRun->script;
+ }
+ }
+
+ return TextAbstraction::UNKNOWN;
+}
+
+void LogicalModel::SetFonts( const FontRun* const fonts,
+ Length numberOfRuns )
+{
+ Vector<FontRun>& fontRuns = mImpl->mFontRuns;
+ fontRuns.Resize( numberOfRuns );
+ memcpy( fontRuns.Begin(), fonts, numberOfRuns * sizeof( FontRun ) );
+}
+
+Length LogicalModel::GetNumberOfFontRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ if( ( 0u == characterIndex ) && ( mImpl->mText.Count() == numberOfCharacters ) )
+ {
+ return mImpl->mFontRuns.Count();
+ }
+
+ const CharacterIndex charcterEndIndex = characterIndex + numberOfCharacters;
+ Length numberOfFontRuns = 0u;
+ bool firstIndexFound = false;
+
+ for( Length index = 0u, length = mImpl->mFontRuns.Count(); index < length; ++index )
+ {
+ const FontRun* const fontRun = mImpl->mFontRuns.Begin() + index;
+
+ if( !firstIndexFound &&
+ ( characterIndex < fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters ) )
+ {
+ // The character index is within this font run.
+ // Starts the counter of font runs.
+ firstIndexFound = true;
+ }
+
+ if( firstIndexFound )
+ {
+ ++numberOfFontRuns;
+ if( fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters > charcterEndIndex )
+ {
+ // This font run exceeds the given range. The number of fonts can be returned.
+ return numberOfFontRuns;
+ }
+ }
+ }
+
+ return numberOfFontRuns;
+}
+
+void LogicalModel::GetFontRuns( FontRun* fontRuns,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ // A better implementation can cache the first font run and the number of then when the GetNumberOfFontRuns() is called.
+
+ Length numberOfFontRuns = GetNumberOfFontRuns( characterIndex,
+ numberOfCharacters );
+
+ for( Length index = 0u, length = mImpl->mFontRuns.Count(); index < length; ++index )
+ {
+ const FontRun* const fontRun = mImpl->mFontRuns.Begin() + index;
+
+ if( characterIndex < fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters )
+ {
+ memcpy( fontRuns, fontRun, sizeof( FontRun ) * numberOfFontRuns );
+ return;
+ }
+ }
+}
+
+FontId LogicalModel::GetFont( CharacterIndex characterIndex ) const
+{
+ for( Length index = 0u, length = mImpl->mFontRuns.Count(); index < length; ++index )
+ {
+ const FontRun* const fontRun = mImpl->mFontRuns.Begin() + index;
+
+ if( ( fontRun->characterRun.characterIndex <= characterIndex ) &&
+ ( characterIndex < fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters ) )
+ {
+ return fontRun->fontId;
+ }
+ }
+
+ return 0u;
+}
+
+void LogicalModel::SetLineBreakInfo( const LineBreakInfo* const lineBreakInfo,
+ Length length )
+{
+ Vector<LineBreakInfo>& modelLineBreakInfo = mImpl->mLineBreakInfo;
+ modelLineBreakInfo.Resize( length );
+ memcpy( modelLineBreakInfo.Begin(), lineBreakInfo, length * sizeof( LineBreakInfo ) );
+}
+
+void LogicalModel::GetLineBreakInfo( LineBreakInfo* lineBreakInfo,
+ CharacterIndex characterIndex,
+ Length numberOfItems ) const
+{
+ memcpy( lineBreakInfo, mImpl->mLineBreakInfo.Begin() + characterIndex, numberOfItems * sizeof( LineBreakInfo ) );
+}
+
+LineBreakInfo LogicalModel::GetLineBreakInfo( CharacterIndex characterIndex ) const
+{
+ return *( mImpl->mLineBreakInfo.Begin() + characterIndex );
+}
+
+void LogicalModel::SetWordBreakInfo( const WordBreakInfo* const wordBreakInfo,
+ Length length )
+{
+ Vector<WordBreakInfo>& modelWordBreakInfo = mImpl->mWordBreakInfo;
+ modelWordBreakInfo.Resize( length );
+ memcpy( modelWordBreakInfo.Begin(), wordBreakInfo, length * sizeof( WordBreakInfo ) );
+}
+
+void LogicalModel::GetWordBreakInfo( WordBreakInfo* wordBreakInfo,
+ CharacterIndex characterIndex,
+ Length numberOfItems ) const
+{
+ memcpy( wordBreakInfo, mImpl->mWordBreakInfo.Begin() + characterIndex, numberOfItems * sizeof( WordBreakInfo ) );
+}
+
+WordBreakInfo LogicalModel::GetWordBreakInfo( CharacterIndex characterIndex ) const
+{
+ return *( mImpl->mWordBreakInfo.Begin() + characterIndex );
+}
+
+void LogicalModel::SetBidirectionalInfo( const BidirectionalParagraphInfoRun* const bidirectionalInfo,
+ Length numberOfRuns )
+{
+}
+
+Length LogicalModel::GetNumberOfBidirectionalInfoRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ return 0u;
+}
+
+void LogicalModel::GetCharacterDirections( CharacterDirection* directions,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+}
+
+CharacterDirection LogicalModel::GetCharacterDirection( CharacterIndex characterIndex ) const
+{
+ return false;
+}
+
+void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const bidirectionalInfo,
+ Length numberOfRuns )
+{
+}
+
+CharacterIndex LogicalModel::GetVisualCharacterIndex( CharacterIndex logicalCharacterIndex ) const
+{
+ return 0u;
+}
+
+CharacterIndex LogicalModel::GetLogicalCharacterIndex( CharacterIndex visualCharacterIndex ) const
+{
+ return 0u;
+}
+
+void LogicalModel::GetLogicalToVisualMap( CharacterIndex* logicalToVisualMap,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+}
+
+void LogicalModel::GetVisualToLogicalMap( CharacterIndex* visualToLogicalMap,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+}
+
+LogicalModel::~LogicalModel()
+{
+ delete mImpl;
+}
+
+LogicalModel::LogicalModel()
+: mImpl( NULL )
+{
+ mImpl = new LogicalModel::Impl();
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_LOGICAL_MODEL_H__
+#define __DALI_TOOLKIT_TEXT_LOGICAL_MODEL_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/ref-object.h>
+#include <dali-toolkit/public-api/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct BidirectionalLineInfoRun;
+struct BidirectionalParagraphInfoRun;
+struct FontRun;
+class LogicalModel;
+typedef IntrusivePtr<LogicalModel> LogicalModelPtr;
+struct ScriptRun;
+
+/**
+ * @brief A logical text model contains layout independent information.
+ *
+ * This includes:
+ * - A series of UTF-32 characters in logical order
+ */
+class LogicalModel : public RefObject
+{
+public:
+
+ /**
+ * @brief Create a new instance of a LogicalModel.
+ *
+ * @return A pointer to a new LogicalModel.
+ */
+ static LogicalModelPtr New();
+
+ // Text interface.
+
+ /**
+ * @brief Replaces any text previously set.
+ *
+ * @param[in] text An array of UTF-32 characters.
+ * @param[in] numberOfCharacters The length of the array.
+ */
+ void SetText( const Character* const text,
+ Length numberOfCharacters );
+
+ /**
+ * @brief Retrieves the number of characters of the text.
+ *
+ * @return The number of characters.
+ */
+ Length GetNumberOfCharacters() const;
+
+ /**
+ * @brief Retrieves characters from the text in the given buffer.
+ *
+ * @pre The size of the @p text buffer needs to be big enough to copy the @p numberOfCharacters.
+ * @param[in] characterIndex The index to the first character to copy.
+ * @param[out] text Pointer to a buffer where the text is copied.
+ * @param[in] numberOfCharacters The number of characters to be copied.
+ */
+ void GetText( CharacterIndex characterIndex,
+ Character* text,
+ Length numberOfCharacters ) const;
+
+ /**
+ * Retrieves a character.
+ *
+ * @param[in] characterIndex Index to a character.
+ *
+ * @return A character.
+ */
+ Character GetCharacter( CharacterIndex characterIndex ) const;
+
+ // Language support interface.
+
+ /**
+ * Sets the script runs.
+ *
+ * Replaces any scripts previously set.
+ *
+ * A run is a group of consecutive characters. A script run contains the script for a run.
+ *
+ * @param[in] scripts Pointer to a buffer with all the script runs.
+ * @param[in] numberOfRuns The number of script runs.
+ */
+ void SetScripts( const ScriptRun* const scripts,
+ Length numberOfRuns );
+
+ /**
+ * Retrieves the number of script runs for the given range of characters.
+ *
+ * A run is a group of consecutive characters. A script run contains the script for a run.
+ *
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ *
+ * @return The number of script runs.
+ */
+ Length GetNumberOfScriptRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ /**
+ * Retrieves the script runs for the given range of characters.
+ *
+ * The @p scriptRuns buffer needs to be big enough to copy the number of script runs.
+ * Call GetNumberOfScriptRuns() to retrieve the number of script runs.
+ *
+ * @param[out] scriptRuns Pointer to a buffer where the script runs are copied.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void GetScriptRuns( ScriptRun* scriptRuns,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ /**
+ * Retrieves the script for the given character index.
+ *
+ * @param[in] characterIndex Index to the character.
+ *
+ * @return The character's script.
+ */
+ Script GetScript( CharacterIndex characterIndex ) const;
+
+ /**
+ * Sets the font runs.
+ *
+ * Replaces any fonts previously set.
+ *
+ * A run is a group of consecutive characters. A font run contains the font id for a run.
+ *
+ * @param[in] fonts Pointer to a buffer with all the font runs.
+ * @param[in] numberOfRuns The number of font runs.
+ */
+ void SetFonts( const FontRun* const fonts,
+ Length numberOfRuns );
+
+ /**
+ * Retrieves the number of font runs for the given range of characters.
+ *
+ * A run is a group of consecutive characters. A font run contains the font id for a run.
+ *
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ *
+ * @return The number of font runs.
+ */
+ Length GetNumberOfFontRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ /**
+ * Retrieves the font runs for the given range of characters.
+ *
+ * The @p fontRuns buffer needs to be big enough to copy the number of font runs.
+ * Call GetNumberOfFontRuns() to retrieve the number of font runs.
+ *
+ * @param[out] fontRuns Pointer to a buffer where the font runs are copied.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void GetFontRuns( FontRun* fontRuns,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ /**
+ * Retrieves the font id for the given character index.
+ *
+ * @param[in] characterIndex Index to the first character.
+ *
+ * @return The font id.
+ */
+ FontId GetFont( CharacterIndex characterIndex ) const;
+
+ // Break info interface.
+
+ /**
+ * Sets the line break info.
+ *
+ * See GetLineBreakInfo() to get how the line break info is encoded.
+ *
+ * Replaces any line break info previously set.
+ *
+ * @param[in] lineBreakInfo Pointer to a buffer with the line break info.
+ * @param[in] length The size of the buffer.
+ */
+ void SetLineBreakInfo( const LineBreakInfo* const lineBreakInfo,
+ Length length );
+
+ /**
+ * Retrieves the line break info in the given buffer.
+ *
+ * The size of the @p lineBreakInfo buffer needs to be big enough to copy the @p numberOfItems.
+ *
+ * Possible values for LineBreakInfo are:
+ *
+ * - 0 is a LINE_MUST_BREAK. Text must be broken into a new line.
+ * - 1 is a LINE_ALLOW_BREAK. Is possible to break the text into a new line.
+ * - 2 is a LINE_NO_BREAK. Text can't be broken into a new line.
+ *
+ @verbatim
+ i.e. Hello big\nworld produces:
+ 2222212220 22220
+ @endverbatim
+ *
+ * @param[out] lineBreakInfo Pointer to a buffer where the line break info is copied.
+ * @param[in] characterIndex Index to the first line break info item.
+ * @param[in] numberOfItems The number of items to be copied.
+ */
+ void GetLineBreakInfo( LineBreakInfo* lineBreakInfo,
+ CharacterIndex characterIndex,
+ Length numberOfItems ) const;
+
+ /**
+ * Retrieves the line break info for the given item index.
+ *
+ * @param[in] characterIndex Index to the line break info item.
+ */
+ LineBreakInfo GetLineBreakInfo( CharacterIndex characterIndex ) const;
+
+ /**
+ * Sets the word break info.
+ *
+ * See GetWordBreakInfo() to get how the word break info is encoded.
+ *
+ * Replaces any word break info previously set.
+ *
+ * @param[in] wordBreakInfo Pointer to a buffer with the word break info.
+ * @param[in] length The size of the buffer.
+ */
+ void SetWordBreakInfo( const WordBreakInfo* const wordBreakInfo,
+ Length length );
+
+ /**
+ * Retrieves the word break info in the given buffer.
+ *
+ * The size of the @p wordBreakInfo buffer needs to be big enough to copy the @p numberOfItems.
+ *
+ * The size of the buffer has to be big enough to store the whole word break info per character.
+ * Call GetNumberOfCharacters() to get the number of characters.
+ *
+ * Possible values for WordBreakInfo are:
+ *
+ * - 0 is a WORD_BREAK. Text can be broken into a new word.
+ * - 1 is a WORD_NO_BREAK. Text can't be broken into a new word.
+ *
+ @verbatim
+ i.e. Hello big\nworld produces:
+ 1111001100 11110
+ @endverbatim
+ *
+ * @param[out] wordBreakInfo Pointer to a buffer where the word break info is copied.
+ * @param[in] characterIndex Index to the first word break info item.
+ * @param[in] numberOfItems The number of items to be copied.
+ */
+ void GetWordBreakInfo( WordBreakInfo* wordBreakInfo,
+ CharacterIndex characterIndex,
+ Length numberOfItems ) const;
+
+ /**
+ * Retrieves the word break info for the given item index.
+ *
+ * @param[in] characterIndex Index to the word break info item.
+ */
+ WordBreakInfo GetWordBreakInfo( CharacterIndex characterIndex ) const;
+
+ // Bidirectional support interface.
+
+ /**
+ * Sets the bidirectional info runs.
+ *
+ * Replaces any bidirectional info previously set.
+ *
+ * Each bidirectional info run stores bidirectional info for a whole 'paragraph' of text which contains right to left scripts.
+
+ * In terms of the bidirectional algorithm, a 'paragraph' is understood as a run of characters between Paragraph Separators or appropriate Newline Functions.
+ * A 'paragraph' may also be determined by higher-level protocols like a mark-up tag.
+ *
+ * @param[in] bidirectionalInfo Pointer to a buffer with all the bidirectional info runs.
+ * @param[in] numberOfRuns The number of bidirectional info runs.
+ */
+ void SetBidirectionalInfo( const BidirectionalParagraphInfoRun* const bidirectionalInfo,
+ Length numberOfRuns );
+
+ /**
+ * Retrieves the number of bidirectional info runs for the given range of characters.
+ *
+ * It may be zero if there is no right to left scripts.
+ *
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ *
+ * @return The number of bidirectional info runs.
+ */
+ Length GetNumberOfBidirectionalInfoRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ /**
+ * Retrieves the direction of the characters.
+ *
+ * It sets @c true for right to left characters and @c false for left to right.
+ * For neutral characters it check's the next and previous character's directions:
+ * - If they are equals set that direction. If they are not, sets the paragraph's direction.
+ * - If there is no next, sets the paragraph's direction.
+ *
+ * See SetBidirectionalInfo() to get an explanation of the 'paragraph' meaning in the bidirectional algorithm.
+ *
+ * @param[out] directions Whether the characters are right to left or left to right.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void GetCharacterDirections( CharacterDirection* directions,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ /**
+ * Retrieves the direction of a characters.
+ *
+ * See GetCharacterDirections().
+ *
+ * @param[in] characterIndex Index to a character.
+ *
+ * @return The character's direction.
+ */
+ CharacterDirection GetCharacterDirection( CharacterIndex characterIndex ) const;
+
+ // Visual <--> Logical conversion tables.
+
+ /**
+ * Sets the visual to logical and the logical to visual map tables.
+ *
+ * Replaces any map tables previously set.
+ *
+ * @param[in] bidirectionalInfo Pointer to a buffer with all the bidirectional info runs.
+ * @param[in] numberOfRuns The number of bidirectional info runs.
+ */
+ void SetVisualToLogicalMap( const BidirectionalLineInfoRun* const bidirectionalInfo,
+ Length numberOfRuns );
+
+ /**
+ * Retrieves the visual character index for the given logical character index.
+ *
+ * @param[in] logicalCharacterIndex The logical character index.
+ *
+ * @return The visual character index.
+ */
+ CharacterIndex GetVisualCharacterIndex( CharacterIndex logicalCharacterIndex ) const;
+
+ /**
+ * Retrieves the logical character index for the given visual character index.
+ *
+ * @param[in] visualCharacterIndex The visual character index.
+ *
+ * @return The logical character index.
+ */
+ CharacterIndex GetLogicalCharacterIndex( CharacterIndex visualCharacterIndex ) const;
+
+ /**
+ * Retrieves the whole or part of the logical to visual conversion map.
+ *
+ * The size of the buffer needs to be big enough to copy the @p numberOfCharacters.
+ *
+ * @param[out] logicalToVisualMap Pointer to a buffer where the conversion map is copied.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void GetLogicalToVisualMap( CharacterIndex* logicalToVisualMap,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ /**
+ * Retrieves the whole or part of the visual to logical conversion map.
+ *
+ * The size of the buffer needs to be big enough to copy the @p numberOfCharacters.
+ *
+ * @param[out] visualToLogicalMap Pointer to a buffer where the conversion map is copied.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void GetVisualToLogicalMap( CharacterIndex* visualToLogicalMap,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+protected:
+
+ /**
+ * @brief A reference counted object may only be deleted by calling Unreference().
+ */
+ virtual ~LogicalModel();
+
+private:
+
+ /**
+ * @brief Private constructor.
+ */
+ LogicalModel();
+
+ // Undefined
+ LogicalModel( const LogicalModel& handle );
+
+ // Undefined
+ LogicalModel& operator=( const LogicalModel& handle );
+
+private:
+
+ struct Impl;
+ Impl* mImpl;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_LOGICAL_MODEL_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/public-api/text/multi-language-support.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/multi-language-support-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+MultilanguageSupport::MultilanguageSupport()
+{
+}
+
+MultilanguageSupport::~MultilanguageSupport()
+{
+}
+
+MultilanguageSupport::MultilanguageSupport( Internal::MultilanguageSupport* implementation )
+: BaseHandle( implementation )
+{
+}
+
+MultilanguageSupport MultilanguageSupport::Get()
+{
+ return Internal::MultilanguageSupport::Get();
+}
+
+void MultilanguageSupport::SetScripts( const Vector<Character>& text,
+ const Vector<LineBreakInfo>& lineBreakInfo,
+ Vector<ScriptRun>& scripts )
+{
+ GetImplementation( *this ).SetScripts( text,
+ lineBreakInfo,
+ scripts );
+}
+
+void MultilanguageSupport::ReplaceScripts( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert )
+{
+ GetImplementation( *this ).ReplaceScripts( model,
+ characterIndex,
+ numberOfCharactersToRemove,
+ numberOfCharactersToInsert );
+}
+
+void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
+ const Vector<ScriptRun>& scripts,
+ Vector<FontRun>& fonts )
+{
+ GetImplementation( *this ).ValidateFonts( text,
+ scripts,
+ fonts );
+}
+
+void MultilanguageSupport::ValidateFonts( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert )
+{
+ GetImplementation( *this ).ValidateFonts( model,
+ characterIndex,
+ numberOfCharactersToRemove,
+ numberOfCharactersToInsert );
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_MULTI_LANGUAGE_SUPPORT_H__
+#define __DALI_TOOLKIT_TEXT_MULTI_LANGUAGE_SUPPORT_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/object/base-handle.h>
+#include <dali-toolkit/public-api/text/font-run.h>
+#include <dali-toolkit/public-api/text/script-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace Internal DALI_INTERNAL
+{
+
+class MultilanguageSupport;
+
+} // Internal
+
+class LogicalModel;
+
+/**
+ * @brief Sets the character's scripts to the model and validates the fonts set by the user or assigns default ones.
+ */
+class MultilanguageSupport : public BaseHandle
+{
+public:
+
+ /**
+ * @brief Create an uninitialized MultilanguageSupport handle.
+ */
+ MultilanguageSupport();
+
+ /**
+ * @brief Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~MultilanguageSupport();
+
+ /**
+ * @brief This constructor is used by MultilanguageSupport::Get().
+ *
+ * @param[in] implementation A pointer to the internal multi-language support object.
+ */
+ explicit DALI_INTERNAL MultilanguageSupport( Internal::MultilanguageSupport* implementation );
+
+ /**
+ * @brief Retrieve a handle to the MultilanguageSupport instance.
+ *
+ * @return A handle to the MultilanguageSupport.
+ */
+ static MultilanguageSupport Get();
+
+ /**
+ * @brief Sets the scripts of the whole text.
+ *
+ * Scripts are used to validate and set default fonts and to shape the text in further steps.
+ *
+ * Some characters (like white spaces) are valid for many scripts. The rules to set a script
+ * for them are:
+ * - If they are at the begining of a paragraph they get the script of the first character with
+ * a defined script. If they are at the end, they get the script of the last one.
+ * - If they are between two scripts with the same direction, they get the script of the previous
+ * character with a defined script. If the two scripts have different directions, they get the
+ * script of the first character of the paragraph with a defined script.
+ *
+ * @param[in] text Vector of UTF-32 characters.
+ * @param[in] lineBreakInfo Vector with the line break info.
+ * @param[out] scripts Vector containing the script runs for the whole text.
+ */
+ void SetScripts( const Vector<Character>& text,
+ const Vector<LineBreakInfo>& lineBreakInfo,
+ Vector<ScriptRun>& scripts );
+
+ /**
+ * Replaces the scrips of the given range of characters.
+ *
+ * @pre The @p model needs to have a text set.
+ *
+ * If the @p numberOfCharactersToRemove is zero, this operation is like an insert.
+ * If the @p numberOfCharactersToInsert is zero, this operation is like a remove.
+ *
+ * @param[in,out] model The text's logical model.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharactersToRemove The number of characters removed from the text.
+ * @param[in] numberOfCharactersToInsert The number of characters inserted in the text.
+ */
+ void ReplaceScripts( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert );
+
+ /**
+ * @brief Validates the character's font of the whole text.
+ *
+ * It may update fonts set by application developers.
+ *
+ * This method ensures all characters are going to be rendered using an appropriate font. Provided a valid font
+ * exists in the platform.
+ *
+ * For those characters with no font set, it sets a default one.
+ *
+ * If a font has been set by the application developer, this method checks if the font supports the character.
+ * If it doesn't, this method replaces it by a default one.
+ *
+ * @param[in] text Vector of UTF-32 characters.
+ * @param[in] scripts Vector containing the script runs for the whole text.
+ * @param[in,out] fonts Initially contains the fonts set by the application developers. Returns the validated fonts.
+ */
+ void ValidateFonts( const Vector<Character>& text,
+ const Vector<ScriptRun>& scripts,
+ Vector<FontRun>& fonts );
+
+ /**
+ * Validates the character's font of the given range of characters.
+ *
+ * It may update fonts set by the mark-up processor.
+ * It sets default fonts based on the script to those characters without a font set.
+ *
+ * @pre The @p model needs to have a text set.
+ * @pre The @p model needs to have the scripts set.
+ *
+ * If the @p numberOfCharactersToRemove is zero, this operation is like an insert.
+ * If the @p numberOfCharactersToInsert is zero, this operation is like a remove.
+ *
+ * @param[in,out] model The text's logical model.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharactersToRemove The number of characters removed from the text.
+ * @param[in] numberOfCharactersToInsert The number of characters inserted in the text.
+ */
+ void ValidateFonts( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert );
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_MULTI_LANGUAGE_SUPPORT_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/rendering/basic/text-basic-renderer.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/text-abstraction/font-client.h>
+#include <dali/public-api/actors/mesh-actor.h>
+#include <dali/public-api/images/atlas.h>
+#include <dali/public-api/geometry/mesh.h>
+#include <dali-toolkit/public-api/text/rendering/shaders/text-basic-shader.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+using namespace Dali::Toolkit::Text;
+
+namespace
+{
+
+const std::size_t PADDING = 2; //< To avoid GL filtering artefacts
+
+struct TextureCoordinates
+{
+ TextureCoordinates()
+ : topLeft( 0.0f, 0.0f ),
+ topRight( 1.0f, 0.0f ),
+ bottomLeft( 0.0f, 1.0f ),
+ bottomRight( 1.0f, 1.0f )
+ {
+ }
+
+ Vector2 topLeft;
+ Vector2 topRight;
+ Vector2 bottomLeft;
+ Vector2 bottomRight;
+};
+
+struct AtlasHelperGlyph
+{
+ AtlasHelperGlyph()
+ : fontId( 0 ),
+ index( 0 ),
+ xOffset( 0 ),
+ width( 0 ),
+ height( 0 )
+ {
+ }
+
+ AtlasHelperGlyph( FontId id,
+ GlyphIndex glyphIndex,
+ std::size_t offset,
+ std::size_t widthPixels,
+ std::size_t heightPixels )
+ : fontId( id ),
+ index( glyphIndex ),
+ xOffset( offset ),
+ width( widthPixels ),
+ height( heightPixels )
+ {
+ }
+
+ FontId fontId;
+ GlyphIndex index;
+ std::size_t xOffset;
+ std::size_t width;
+ std::size_t height;
+ TextureCoordinates coords;
+};
+
+struct AtlasHelper
+{
+ AtlasHelper()
+ : mWidth( 0.0f ),
+ mHeight( 0.0f )
+ {
+ mFontClient = TextAbstraction::FontClient::Get();
+ }
+
+ void Reset()
+ {
+ mWidth = 0.0f;
+ mHeight = 0.0f;
+ mGlyphs.clear();
+ }
+
+ void Reserve( std::size_t size )
+ {
+ mGlyphs.reserve( size );
+ }
+
+ bool GlyphFound( FontId fontId, GlyphIndex index ) const
+ {
+ for( unsigned int i=0; i<mGlyphs.size(); ++i )
+ {
+ const AtlasHelperGlyph& glyph = mGlyphs[i];
+
+ if( fontId == glyph.fontId &&
+ index == glyph.index )
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ void AddGlyph( const GlyphInfo& glyphInfo )
+ {
+ mGlyphs.push_back( AtlasHelperGlyph( glyphInfo.fontId, glyphInfo.index, mWidth, glyphInfo.width, glyphInfo.height ) );
+
+ mWidth += glyphInfo.width + PADDING;
+ if( mHeight < glyphInfo.height + PADDING )
+ {
+ mHeight = glyphInfo.height + PADDING;
+ }
+ }
+
+ Atlas CreateAtlas()
+ {
+ Atlas atlas = Atlas::New( mWidth, mHeight, Pixel::L8 );
+
+ for( unsigned int i=0; i<mGlyphs.size(); ++i )
+ {
+ AtlasHelperGlyph& glyph = mGlyphs[i];
+ BufferImage bitmap = mFontClient.CreateBitmap( glyph.fontId, glyph.index );
+ atlas.Upload( bitmap, glyph.xOffset, 0 );
+
+ TextureCoordinates& coords = glyph.coords;
+ coords.topLeft.x = static_cast<float>(glyph.xOffset) / static_cast<float>(mWidth);
+ coords.topLeft.y = 0.0f;
+ coords.topRight.x = static_cast<float>(glyph.xOffset + glyph.width) / static_cast<float>(mWidth);
+ coords.topRight.y = 0.0f;
+ coords.bottomLeft.x = static_cast<float>(glyph.xOffset) / static_cast<float>(mWidth);
+ coords.bottomLeft.y = static_cast<float>(glyph.height) / static_cast<float>(mHeight);
+ coords.bottomRight.x = static_cast<float>(glyph.xOffset + glyph.width) / static_cast<float>(mWidth);
+ coords.bottomRight.y = static_cast<float>(glyph.height) / static_cast<float>(mHeight);
+ }
+
+ return atlas;
+ }
+
+ void GetTextureCoordinates( FontId fontId, GlyphIndex index, TextureCoordinates& coords )
+ {
+ for( unsigned int i=0; i<mGlyphs.size(); ++i )
+ {
+ const AtlasHelperGlyph& glyph = mGlyphs[i];
+
+ if( fontId == glyph.fontId &&
+ index == glyph.index )
+ {
+ coords = glyph.coords;
+ return;
+ }
+ }
+ }
+
+private: // Data
+
+ std::size_t mWidth;
+ std::size_t mHeight;
+
+ std::vector<AtlasHelperGlyph> mGlyphs;
+
+ TextAbstraction::FontClient mFontClient;
+};
+
+} // unnamed namespace
+
+struct BasicRenderer::Impl
+{
+ /**
+ * @brief Ccreate an Atlas, uploading the necessary glyph bitmaps
+ *
+ * @param[in] glyphs The glyphs to upload.
+ */
+ Atlas CreateAtlas( const Vector<GlyphInfo>& glyphs )
+ {
+ AtlasHelper& helper = mAtlasHelper;
+
+ // Clear previous atlas
+ helper.Reset();
+ helper.Reserve( glyphs.Count() );
+
+ for( unsigned int i=0; i<glyphs.Count(); ++i )
+ {
+ float width = glyphs[i].width;
+ float height = glyphs[i].height;
+
+ if( width > 0 &&
+ height > 0 ) // skip whitespace
+ {
+ if( !helper.GlyphFound( glyphs[i].fontId, glyphs[i].index ) )
+ {
+ helper.AddGlyph( glyphs[i] );
+ }
+ }
+ }
+
+ // Uploads the bitmaps to Dali
+ return helper.CreateAtlas();
+ }
+
+ /**
+ * @brief Helper method to create a mesh with one quad per glyph.
+ *
+ * @param[in] glyphs The glyphs to display.
+ * @param[in] positions The 2D positions of the glyphs.
+ * @param[in] image The material uses this as a diffuse texture.
+ */
+ Mesh CreateMesh( const Vector<GlyphInfo>& glyphs, const std::vector<Vector2>& positions, Image image )
+ {
+ MeshData::VertexContainer vertices( 4 * glyphs.Count() ); // 1 quad per glyph
+
+ MeshData::FaceIndices faces;
+ faces.reserve( 6 * glyphs.Count() ); // 2 triangles per quad
+
+ for( unsigned int i=0; i<glyphs.Count(); ++i )
+ {
+ float width = glyphs[i].width;
+ float height = glyphs[i].height;
+
+ if( width > 0 &&
+ height > 0 ) // skip whitespace
+ {
+ const Vector2& position = positions[i];
+
+ TextureCoordinates coords;
+ mAtlasHelper.GetTextureCoordinates( glyphs[i].fontId, glyphs[i].index, coords );
+
+ vertices[ i*4 + 0 ] = MeshData::Vertex( Vector3( position.x + 0.0f*width, position.y + 0.0f*height, 0.0f ), coords.topLeft, Vector3( 1.0f, 0.0f, 0.0f ) );
+ vertices[ i*4 + 1 ] = MeshData::Vertex( Vector3( position.x + 1.0f*width, position.y + 0.0f*height, 0.0f ), coords.topRight, Vector3( 1.0f, 1.0f, 0.0f ) );
+ vertices[ i*4 + 2 ] = MeshData::Vertex( Vector3( position.x + 0.0f*width, position.y + 1.0f*height, 0.0f ), coords.bottomLeft, Vector3( 0.0f, 1.0f, 0.0f ) );
+ vertices[ i*4 + 3 ] = MeshData::Vertex( Vector3( position.x + 1.0f*width, position.y + 1.0f*height, 0.0f ), coords.bottomRight, Vector3( 0.0f, 0.0f, 1.0f ) );
+
+ faces.push_back( i*4 + 0 ); faces.push_back( i*4 + 3 ); faces.push_back( i*4 + 1 );
+ faces.push_back( i*4 + 0 ); faces.push_back( i*4 + 2 ); faces.push_back( i*4 + 3 );
+ }
+ }
+
+ Material material = Material::New( "Material" );
+ material.SetDiffuseTexture( image );
+
+ // Create the mesh data from the vertices and faces
+ MeshData meshData;
+ meshData.SetHasColor( false );
+ meshData.SetMaterial( material );
+ meshData.SetVertices( vertices );
+ meshData.SetFaceIndices( faces );
+
+ // Create a mesh from the data
+ Dali::Mesh mesh = Mesh::New( meshData );
+ return mesh;
+ }
+
+ RenderableActor mActor; ///< The actor which renders the text
+
+ AtlasHelper mAtlasHelper; ///< A helper class for storing atlas positions etc.
+};
+
+Text::RendererPtr BasicRenderer::New()
+{
+ return Text::RendererPtr( new BasicRenderer() );
+}
+
+RenderableActor BasicRenderer::Render( Text::ViewInterface& view )
+{
+ UnparentAndReset( mImpl->mActor );
+
+ Text::Length numberOfGlyphs = view.GetNumberOfGlyphs();
+
+ if( numberOfGlyphs > 0 )
+ {
+ Vector<GlyphInfo> glyphs;
+ glyphs.Resize( numberOfGlyphs );
+
+ view.GetGlyphs( &glyphs[0], 0, numberOfGlyphs );
+
+ std::vector<Vector2> positions;
+ positions.resize( numberOfGlyphs );
+ view.GetGlyphPositions( &positions[0], 0, numberOfGlyphs );
+
+ Atlas atlas = mImpl->CreateAtlas( glyphs );
+
+ MeshActor actor = MeshActor::New( mImpl->CreateMesh( glyphs, positions, atlas ) );
+ actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+
+ ShaderEffect shader = BasicShader::New();
+ actor.SetShaderEffect( shader );
+
+ mImpl->mActor = actor;
+ }
+
+ return mImpl->mActor;
+}
+
+BasicRenderer::BasicRenderer()
+{
+ mImpl = new Impl();
+}
+
+BasicRenderer::~BasicRenderer()
+{
+ delete mImpl;
+}
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_BASIC_RENDERER_H__
+#define __DALI_TOOLKIT_TEXT_BASIC_RENDERER_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/rendering/text-renderer.h>
+#include <dali-toolkit/public-api/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief A reference implementation of Text::Renderer.
+ *
+ * This is intended for testing & performance comparisons with more complex solutions.
+ * Each basic renderer creates its own texture atlas, and uses a simple packing algorithm,
+ * in which glyphs are stored in a single row.
+ */
+class BasicRenderer : public Renderer
+{
+public:
+
+ /**
+ * @brief Create the renderer.
+ */
+ static RendererPtr New();
+
+ /**
+ * @brief Render the glyphs from a ViewInterface.
+ *
+ * @param[in] view The interface to a view.
+ * @return The Renderable actor used to position the text.
+ */
+ virtual RenderableActor Render( ViewInterface& view );
+
+protected:
+
+ /**
+ * @brief Constructor.
+ */
+ BasicRenderer();
+
+ /**
+ * @brief A reference counted object may only be deleted by calling Unreference().
+ */
+ virtual ~BasicRenderer();
+
+private:
+
+ // Undefined
+ BasicRenderer( const BasicRenderer& handle );
+
+ // Undefined
+ BasicRenderer& operator=( const BasicRenderer& handle );
+
+private:
+
+ struct Impl;
+ Impl* mImpl;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_BASIC_RENDERER_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/rendering/text-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace BasicShader
+{
+
+Dali::ShaderEffect New()
+{
+ std::string vertexShader = DALI_COMPOSE_SHADER(
+ uniform mediump vec4 uTextureRect;\n
+ void main()\n
+ {\n
+ gl_Position = uMvpMatrix * vec4( aPosition.xy, 0.0, 1.0 );\n
+ vTexCoord = aTexCoord.xy;\n
+ }\n
+ );
+
+ std::string fragmentShader = DALI_COMPOSE_SHADER(
+ void main()\n
+ {\n
+ mediump vec4 color = texture2D( sTexture, vTexCoord );
+ gl_FragColor = vec4(uColor.rgb, uColor.a*color.r);
+ }\n
+ );
+
+ Dali::ShaderEffect shaderEffect = Dali::ShaderEffect::New( vertexShader, fragmentShader,
+ Dali::GeometryType( Dali::GEOMETRY_TYPE_TEXTURED_MESH ),
+ Dali::ShaderEffect::GeometryHints( Dali::ShaderEffect::HINT_NONE ) );
+ return shaderEffect;
+}
+
+} // namespace BasicShader
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_BASIC_SHADER_H__
+#define __DALI_TOOLKIT_TEXT_BASIC_SHADER_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/shader-effects/shader-effect.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief A basic shader for rendering glyphs in Pixel::L8 format.
+ */
+namespace BasicShader
+{
+
+/**
+ * Create a basic text shader.
+ * @return A handle to a newly allocated ShaderEffect
+ */
+Dali::ShaderEffect New();
+
+} // namespace BasicShader
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_BASIC_SHADER_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/rendering/text-backend.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/rendering/text-backend-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+Backend Backend::Get()
+{
+ return Internal::Backend::Get();
+}
+
+RendererPtr Backend::NewRenderer( unsigned int renderingType )
+{
+ return GetImplementation(*this).NewRenderer( renderingType );
+}
+
+Backend::Backend()
+{
+}
+
+Backend::~Backend()
+{
+}
+
+Backend::Backend( const Backend& handle )
+: BaseHandle( handle )
+{
+}
+
+Backend& Backend::operator=( const Backend& handle )
+{
+ BaseHandle::operator=( handle );
+ return *this;
+}
+
+Backend::Backend( Internal::Backend* internal )
+: BaseHandle( internal )
+{
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_BACKEND_H__
+#define __DALI_TOOLKIT_TEXT_BACKEND_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-handle.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/rendering/text-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace Internal DALI_INTERNAL
+{
+class Backend;
+}
+
+// The type of text renderer required
+enum RenderingType
+{
+ RENDERING_BASIC, ///< A bitmap-based reference implementation
+ RENDERING_SHARED_ATLAS ///< A bitmap-based solution where renderers can share a texture atlas
+};
+
+/**
+ * @brief Provides access to different text rendering backends.
+ */
+class DALI_IMPORT_API Backend : public BaseHandle
+{
+public:
+
+ /**
+ * @brief Retrieve a handle to the Backend instance.
+ *
+ * @return A handle to the Backend
+ */
+ static Backend Get();
+
+ /**
+ * @brief Create a renderer from a particluar rendering type.
+ *
+ * @param[in] renderingType The type of rendering required.
+ * @return A handle to the newly created renderer.
+ */
+ RendererPtr NewRenderer( unsigned int renderingType );
+
+ /**
+ * @brief Create an uninitialized TextAbstraction handle.
+ */
+ Backend();
+
+ /**
+ * @brief Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~Backend();
+
+ /**
+ * @brief This copy constructor is required for (smart) pointer semantics.
+ *
+ * @param[in] handle A reference to the copied handle.
+ */
+ Backend( const Backend& handle );
+
+ /**
+ * @brief This assignment operator is required for (smart) pointer semantics.
+ *
+ * @param [in] handle A reference to the copied handle.
+ * @return A reference to this.
+ */
+ Backend& operator=( const Backend& handle );
+
+public: // Not intended for application developers
+
+ /**
+ * @brief This constructor is used by Backend::Get().
+ *
+ * @param[in] backend A pointer to the internal backend object.
+ */
+ explicit DALI_INTERNAL Backend( Internal::Backend* backend );
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_BACKEND_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/rendering/text-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+Renderer::Renderer()
+{
+}
+
+Renderer::~Renderer()
+{
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_RENDERER_H__
+#define __DALI_TOOLKIT_TEXT_RENDERER_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/actors/renderable-actor.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/ref-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/text-view-interface.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+class Renderer;
+typedef IntrusivePtr<Renderer> RendererPtr;
+
+/**
+ * @brief Abstract base class for Text renderers.
+ *
+ * This is reponsible for rendering the glyphs from a ViewInterface in the specified positions.
+ * It is implemented by returning a RenderableActor intended as the child of a UI control.
+ */
+class Renderer : public RefObject
+{
+public:
+
+ /**
+ * @brief Render the glyphs from a ViewInterface.
+ *
+ * @param[in] view The interface to a view.
+ * @return The Renderable actor used to position the text.
+ */
+ virtual RenderableActor Render( ViewInterface& view ) = 0;
+
+protected:
+
+ /**
+ * @brief Constructor.
+ */
+ Renderer();
+
+ /**
+ * @brief A reference counted object may only be deleted by calling Unreference().
+ */
+ virtual ~Renderer();
+
+private:
+
+ // Undefined
+ Renderer( const Renderer& handle );
+
+ // Undefined
+ Renderer& operator=( const Renderer& handle );
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_RENDERER_H__
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_SCRIPT_RUN_H__
+#define __DALI_TOOLKIT_TEXT_SCRIPT_RUN_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/character-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Run of characters with the same script.
+ */
+struct ScriptRun
+{
+ CharacterRun characterRun; ///< The initial character index and the number of characters of the run.
+ Script script; ///< Script of the run.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_SCRIPT_RUN_H__
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_SCRIPT_H__
+#define __DALI_TOOLKIT_TEXT_SCRIPT_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Retrieves a character's script.
+ *
+ * @param[in] character The character.
+ *
+ * @return The chraracter's script.
+ */
+Script GetCharacterScript( Character character );
+
+/**
+ * @brief Whether the character is a white space.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a white space.
+ */
+bool IsWhiteSpace( Character character );
+
+/**
+ * @brief Whether the character is a new paragraph character.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a new paragraph character.
+ */
+bool IsNewParagraph( Character character );
+
+/**
+ * @brief Whether the character is a zero width non joiner.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a zero width non joiner.
+ */
+bool IsZeroWidthNonJoiner( Character character );
+
+/**
+ * @brief Whether the character is a zero width joiner.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a zero width joiner.
+ */
+bool IsZeroWidthJoiner( Character character );
+
+/**
+ * @brief Whether the character is a zero width space.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a zero width space.
+ */
+bool IsZeroWidthSpace( Character character );
+
+/**
+ * @brief Whether the character is a left to right mark.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a left to right mark.
+ */
+bool IsLeftToRightMark( Character character );
+
+/**
+ * @brief Whether the character is a right to left mark.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a right to left mark.
+ */
+bool IsRightToLeftMark( Character character );
+
+/**
+ * @brief Whether the character is a thin space.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a thin space.
+ */
+bool IsThinSpace( Character character );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_SCRIPT_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/segmentation.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/text-abstraction/segmentation.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+void SetLineBreakInfo( const Vector<Character>& text,
+ Vector<LineBreakInfo>& lineBreakInfo )
+{
+ const Length numberOfCharacters = text.Count();
+
+ if( 0u == numberOfCharacters )
+ {
+ // Nothing to do if there are no characters.
+ return;
+ }
+
+ // Retrieve the line break info.
+ lineBreakInfo.Resize( numberOfCharacters );
+ TextAbstraction::Segmentation::Get().GetLineBreakPositions( text.Begin(),
+ numberOfCharacters,
+ lineBreakInfo.Begin() );
+}
+
+void ReplaceLineBreakInfo( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert )
+{
+}
+
+void SetWordBreakInfo( const Vector<Character>& text,
+ Vector<WordBreakInfo>& wordBreakInfo )
+{
+ const Length numberOfCharacters = text.Count();
+
+ if( 0u == numberOfCharacters )
+ {
+ // Nothing to do if there are no characters.
+ return;
+ }
+
+ // Retrieve the word break info.
+ wordBreakInfo.Resize( numberOfCharacters );
+ TextAbstraction::Segmentation::Get().GetWordBreakPositions( text.Begin(),
+ numberOfCharacters,
+ wordBreakInfo.Begin() );
+}
+
+void ReplaceWordBreakInfo( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert )
+{
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_SEGMENTATION_H__
+#define __DALI_TOOLKIT_TEXT_SEGMENTATION_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <dali-toolkit/public-api/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+class LogicalModel;
+
+/**
+ * Sets line break info.
+ *
+ * Possible values for LineBreakInfo are:
+ *
+ * - 0 is a LINE_MUST_BREAK. Text must be broken into a new line.
+ * - 1 is a LINE_ALLOW_BREAK. Is possible to break the text into a new line.
+ * - 2 is a LINE_NO_BREAK. Text can't be broken into a new line.
+ *
+ * @param[in] text Vector of UTF-32 characters.
+ * @param[out] lineBreakInfo The line break info
+ */
+void SetLineBreakInfo( const Vector<Character>& text,
+ Vector<LineBreakInfo>& lineBreakInfo );
+
+/**
+ * Replaces line break info.
+ *
+ * @pre The @p model needs to have a text set.
+ *
+ * If the @p numberOfCharactersToRemove is zero, this operation is like an insert.
+ * If the @p numberOfCharactersToInsert is zero, this operation is like a remove.
+ *
+ * @param[in,out] model The text's logical model.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharactersToRemove The number of characters removed from the text.
+ * @param[in] numberOfCharactersToInsert The number of characters inserted in the text.
+ */
+void ReplaceLineBreakInfo( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert );
+
+/**
+ * Sets word break info.
+ *
+ * - 0 is a WORD_BREAK. Text can be broken into a new word.
+ * - 1 is a WORD_NO_BREAK. Text can't be broken into a new word.
+ *
+ * @param[in] text Vector of UTF-32 characters.
+ * @param[out] wordBreakInfo The word break info.
+ */
+void SetWordBreakInfo( const Vector<Character>& text,
+ Vector<WordBreakInfo>& wordBreakInfo );
+
+/**
+ * Replaces word break info.
+ *
+ * @pre The @p model needs to have a text set.
+ *
+ * If the @p numberOfCharactersToRemove is zero, this operation is like an insert.
+ * If the @p numberOfCharactersToInsert is zero, this operation is like a remove.
+ *
+ * @param[in,out] model The text's logical model.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharactersToRemove The number of characters removed from the text.
+ * @param[in] numberOfCharactersToInsert The number of characters inserted in the text.
+ */
+void ReplaceWordBreakInfo( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_SEGMENTATION_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/shaper.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/text-abstraction/shaping.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/font-run.h>
+#include <dali-toolkit/public-api/text/logical-model.h>
+#include <dali-toolkit/public-api/text/script.h>
+#include <dali-toolkit/public-api/text/script-run.h>
+#include <dali-toolkit/public-api/text/visual-model.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+CharacterIndex min( CharacterIndex index0,
+ CharacterIndex index1 )
+{
+ return ( index0 < index1 ) ? index0 : index1;
+}
+
+void ShapeText( const Vector<Character>& text,
+ const Vector<LineBreakInfo>& lineBreakInfo,
+ const Vector<ScriptRun>& scripts,
+ const Vector<FontRun>& fonts,
+ Vector<GlyphInfo>& glyphs,
+ Vector<CharacterIndex>& characterIndices,
+ Vector<Length>& charactersPerGlyph )
+{
+ const Length numberOfCharacters = text.Count();
+
+ if( 0u == numberOfCharacters )
+ {
+ // Nothing to do if there are no characters.
+ return;
+ }
+
+#ifdef DEBUG_ENABLED
+ const Length numberOfFontRuns = fonts.Count();
+ const Length numberOfScriptRuns = scripts.Count();
+#endif
+
+ DALI_ASSERT_DEBUG( ( 0u != numberOfFontRuns ) &&
+ ( numberOfCharacters == fonts[numberOfFontRuns - 1u].characterRun.characterIndex + fonts[numberOfFontRuns - 1u].characterRun.numberOfCharacters ) &&
+ "Toolkit::Text::ShapeText. All characters must have a font set." );
+
+ DALI_ASSERT_DEBUG( ( 0u != numberOfScriptRuns ) &&
+ ( numberOfCharacters == scripts[numberOfScriptRuns - 1u].characterRun.characterIndex + scripts[numberOfScriptRuns - 1u].characterRun.numberOfCharacters ) &&
+ "Toolkit::Text::ShapeText. All characters must have a script set." );
+
+ // The text needs to be split in chunks of consecutive characters.
+ // Each chunk must contain characters with the same font id and script set.
+ // A chunk of consecutive characters must not contain a LINE_MUST_BREAK, if there is one a new chunk have to be created.
+
+ TextAbstraction::Shaping shaping = TextAbstraction::Shaping::Get();
+
+ // To shape the text a font and an script is needed.
+ Vector<FontRun>::ConstIterator fontRunIt = fonts.Begin();
+ Vector<ScriptRun>::ConstIterator scriptRunIt = scripts.Begin();
+
+ // Index to the the next one to be shaped. Is pointing the character after the last one it was shaped.
+ CharacterIndex previousIndex = 0u;
+
+ // The current font id and script used to shape the text.
+ FontId currentFontId = 0u;
+ Script currentScript = TextAbstraction::UNKNOWN;
+
+ // Reserve some space to allocate the glyphs and the glyph to character map.
+ // There is no way to know the number of glyphs before shaping the text.
+ // To avoid reallocations it's reserved space for a slightly biger number of glyphs than the number of characters.
+
+ Length numberOfGlyphsReserved = static_cast<Length>( numberOfCharacters * 1.3f );
+ glyphs.Resize( numberOfGlyphsReserved );
+ charactersPerGlyph.Resize( numberOfGlyphsReserved );
+
+ // The actual number of glyphs.
+ Length totalNumberOfGlyphs = 0u;
+
+ const Character* textBuffer = text.Begin();
+ const LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
+ GlyphInfo* glyphsBuffer = glyphs.Begin();
+ Length* charactersPerGlyphBuffer = charactersPerGlyph.Begin();
+
+ // Traverse the characters and shape the text.
+ for( previousIndex = 0; previousIndex < numberOfCharacters; )
+ {
+ // Get the font id and the script.
+ const FontRun& fontRun = *fontRunIt;
+ const ScriptRun& scriptRun = *scriptRunIt;
+
+ currentFontId = fontRun.fontId;
+ currentScript = scriptRun.script;
+
+ // Get the min index to the last character of both runs.
+ CharacterIndex currentIndex = min( fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters,
+ scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters );
+
+ // Check if there is a line must break.
+ bool mustBreak = false;
+ for( CharacterIndex index = previousIndex; index < currentIndex; ++index )
+ {
+ mustBreak = TextAbstraction::LINE_MUST_BREAK == *( lineBreakInfoBuffer + index );
+ if( mustBreak )
+ {
+ currentIndex = index;
+ break;
+ }
+ }
+
+ // Check if the current index is a white space. Do not want to shape a \n.
+ // The last character is always a must-break even if it's not a \n.
+ Length numberOfCharactersToShape = currentIndex - previousIndex;
+ if( mustBreak && !IsWhiteSpace( *( textBuffer + currentIndex ) ) )
+ {
+ ++numberOfCharactersToShape;
+ }
+
+ // Shape the text for the current chunk.
+ const Length numberOfGlyphs = shaping.Shape( textBuffer + previousIndex,
+ numberOfCharactersToShape,
+ currentFontId,
+ currentScript );
+
+ const Length glyphIndex = totalNumberOfGlyphs;
+ totalNumberOfGlyphs += numberOfGlyphs;
+
+ if( totalNumberOfGlyphs > numberOfGlyphsReserved )
+ {
+ // Resize the vectors to get enough space.
+ numberOfGlyphsReserved = static_cast<Length>( totalNumberOfGlyphs * 1.3f );
+ glyphs.Resize( numberOfGlyphsReserved );
+ charactersPerGlyph.Resize( numberOfGlyphsReserved );
+
+ // Iterators are not valid anymore, set them again.
+ glyphsBuffer = glyphs.Begin();
+ charactersPerGlyphBuffer = charactersPerGlyph.Begin();
+ }
+
+ // Retrieve the glyphs and the glyph to character conversion map.
+ shaping.GetGlyphs( glyphsBuffer + glyphIndex,
+ charactersPerGlyphBuffer + glyphIndex );
+
+ // Update the iterators to get the next font or script run.
+ if( currentIndex == fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters )
+ {
+ ++fontRunIt;
+ }
+ if( currentIndex == scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters )
+ {
+ ++scriptRunIt;
+ }
+
+ // Update the previous index. Jumps the \n if needed.
+ previousIndex = mustBreak ? currentIndex + 1u : currentIndex;
+ }
+
+ characterIndices.Reserve( totalNumberOfGlyphs );
+ CharacterIndex characterIndex = 0u;
+ characterIndices.PushBack( characterIndex );
+ for( Length index = 0u, length = totalNumberOfGlyphs - 1u; index < length; ++index )
+ {
+ characterIndex += *( charactersPerGlyphBuffer + index );
+ characterIndices.PushBack( characterIndex );
+ }
+
+ // Resize the vectors to set the right number of items.
+ glyphs.Resize( totalNumberOfGlyphs );
+ // characterIndices.Resize( totalNumberOfGlyphs );
+ charactersPerGlyph.Resize( totalNumberOfGlyphs );
+}
+
+void ShapeText( const LogicalModel& logicalModel,
+ VisualModel& visualModel,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert )
+{
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_SHAPER_H__
+#define __DALI_TOOLKIT_TEXT_SHAPER_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <dali-toolkit/public-api/text/font-run.h>
+#include <dali-toolkit/public-api/text/script-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+class LogicalModel;
+class VisualModel;
+
+/**
+ * Shapes the whole text.
+ *
+ * @param[in] text Vector of UTF-32 characters.
+ * @param[in] lineBreakInfo The line break info.
+ * @param[in] scripts Vector containing the script runs for the whole text.
+ * @param[in] fonts Vector with validated fonts.
+ * @param[out] glyphs Vector of glyphs in the visual order.
+ * @param[out] characterIndices Vector containing the first character in the logical model that each glyph relates to.
+ * @param[out] charactersPerGlyph Vector containing the number of characters per glyph.
+ */
+void ShapeText( const Vector<Character>& text,
+ const Vector<LineBreakInfo>& lineBreakInfo,
+ const Vector<ScriptRun>& scripts,
+ const Vector<FontRun>& fonts,
+ Vector<GlyphInfo>& glyphs,
+ Vector<CharacterIndex>& characterIndices,
+ Vector<Length>& charactersPerGlyph );
+
+/**
+ * Replaces the shape info of the given range of characters.
+ *
+ * @pre The @p model needs to have a text set.
+ * @pre The @p model needs to have the scripts set.
+ * @pre The @p model needs to have the fonts set.
+ * @pre The @p model needs to have the bidirectional info set.
+ *
+ * If the @p numberOfCharactersToRemove is zero, this operation is like an insert.
+ * If the @p numberOfCharactersToInsert is zero, this operation is like a remove.
+ *
+ * @param[in] logicalModel The text's logical model.
+ * @param[in,out] visualModel The text's logical model.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharactersToRemove The number of characters removed from the text.
+ * @param[in] numberOfCharactersToInsert The number of characters inserted in the text.
+ */
+void ShapeText( const LogicalModel& logicalModel,
+ VisualModel& visualModel,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_SHAPER_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/text-control-interface.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+ControlInterface::ControlInterface()
+{
+}
+
+ControlInterface::~ControlInterface()
+{
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H__
+#define __DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief An interface that the Text::Controller uses to request a text relayout.
+ */
+class ControlInterface
+{
+public:
+
+ /**
+ * @brief Constructor.
+ */
+ ControlInterface();
+
+ /**
+ * @brief Virtual destructor.
+ */
+ virtual ~ControlInterface();
+
+ /**
+ * @brief Called to request a text relayout.
+ */
+ virtual void RequestTextRelayout() = 0;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/text-controller.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/character-set-conversion.h>
+#include <dali-toolkit/public-api/text/layouts/layout-engine.h>
+#include <dali-toolkit/public-api/text/logical-model.h>
+#include <dali-toolkit/public-api/text/multi-language-support.h>
+#include <dali-toolkit/public-api/text/script-run.h>
+#include <dali-toolkit/public-api/text/segmentation.h>
+#include <dali-toolkit/public-api/text/shaper.h>
+#include <dali-toolkit/public-api/text/text-view.h>
+#include <dali-toolkit/public-api/text/visual-model.h>
+
+// EXTERNAL INCLUDES
+#include <limits>
+#include <vector>
+#include <dali/public-api/text-abstraction/font-client.h>
+
+using std::vector;
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct Controller::TextInput
+{
+ // Used to queue input events until DoRelayout()
+ enum EventType
+ {
+ KEYBOARD_FOCUS_GAIN_EVENT,
+ KEYBOARD_FOCUS_LOST_EVENT,
+ TAP_EVENT,
+ GRAB_HANDLE_EVENT
+ };
+
+ union Param
+ {
+ int mInt;
+ unsigned int mUint;
+ float mFloat;
+ };
+
+ struct Event
+ {
+ Event( EventType eventType )
+ : type( eventType )
+ {
+ p1.mInt = 0;
+ p2.mInt = 0;
+ }
+
+ EventType type;
+ Param p1;
+ Param p2;
+ Param p3;
+ };
+
+ enum State
+ {
+ INACTIVE,
+ SELECTING,
+ EDITING
+ };
+
+ TextInput( LogicalModelPtr logicalModel,
+ VisualModelPtr visualModel,
+ DecoratorPtr decorator )
+ : mLogicalModel( logicalModel ),
+ mVisualModel( visualModel ),
+ mDecorator( decorator ),
+ mState( INACTIVE )
+ {
+ }
+
+ /**
+ * @brief Helper to move the cursor, grab handle etc.
+ */
+ bool ProcessTouchEvents()
+ {
+ mDecoratorUpdated = false;
+
+ if( mDecorator )
+ {
+ for( vector<TextInput::Event>::iterator iter = mEventQueue.begin(); iter != mEventQueue.end(); ++iter )
+ {
+ switch( iter->type )
+ {
+ case KEYBOARD_FOCUS_GAIN_EVENT:
+ {
+ OnKeyboardFocus( true );
+ break;
+ }
+ case KEYBOARD_FOCUS_LOST_EVENT:
+ {
+ OnKeyboardFocus( false );
+ break;
+ }
+ case TAP_EVENT:
+ {
+ OnTapEvent( *iter );
+ break;
+ }
+ case GRAB_HANDLE_EVENT:
+ {
+ OnGrabHandleEvent( *iter );
+ break;
+ }
+ }
+ }
+ }
+
+ mEventQueue.clear();
+
+ return mDecoratorUpdated;
+ }
+
+ void OnKeyboardFocus( bool hasFocus )
+ {
+ // TODO
+ }
+
+ void OnTapEvent( const Event& event )
+ {
+ if( 1u == event.p1.mUint )
+ {
+ mState = TextInput::EDITING;
+ mDecorator->SetActiveCursor( ACTIVE_CURSOR_PRIMARY );
+ mDecorator->StartCursorBlink();
+ mDecorator->SetGrabHandleActive( true );
+
+ float xPosition = event.p2.mFloat;
+ float yPosition = event.p3.mFloat;
+ float height(0.0f);
+ GetClosestCursorPosition( xPosition, yPosition, height );
+ mDecorator->SetPosition( PRIMARY_CURSOR, xPosition, yPosition, height );
+
+ mDecoratorUpdated = true;
+ }
+ else if( 2u == event.p1.mUint )
+ {
+ mState = TextInput::SELECTING;
+ mDecorator->SetGrabHandleActive( false );
+ mDecorator->SetSelectionActive( true );
+ mDecoratorUpdated = true;
+ }
+ }
+
+ void OnGrabHandleEvent( const Event& event )
+ {
+ unsigned int state = event.p1.mUint;
+
+ if( GRAB_HANDLE_PRESSED == state )
+ {
+ float xPosition = event.p2.mFloat;
+ float yPosition = event.p3.mFloat;
+ float height(0.0f);
+
+ GetClosestCursorPosition( xPosition, yPosition, height );
+
+ mDecorator->SetPosition( PRIMARY_CURSOR, xPosition, yPosition, height );
+ mDecoratorUpdated = true;
+ }
+ }
+
+ void GetClosestCursorPosition( float& x, float& y, float& height )
+ {
+ // TODO - Look at LineRuns first
+
+ Text::Length numberOfGlyphs = mVisualModel->GetNumberOfGlyphs();
+ if( 0 == numberOfGlyphs )
+ {
+ return;
+ }
+
+ Vector<GlyphInfo> glyphs;
+ glyphs.Resize( numberOfGlyphs );
+ mVisualModel->GetGlyphs( &glyphs[0], 0, numberOfGlyphs );
+
+ std::vector<Vector2> positions;
+ positions.resize( numberOfGlyphs );
+ mVisualModel->GetGlyphPositions( &positions[0], 0, numberOfGlyphs );
+
+ unsigned int closestGlyph = 0;
+ float closestDistance = std::numeric_limits<float>::max();
+
+ for( unsigned int i=0; i<glyphs.Count(); ++i )
+ {
+ float glyphX = positions[i].x + glyphs[i].width*0.5f;
+ float glyphY = positions[i].y + glyphs[i].height*0.5f;
+
+ float distanceToGlyph = fabsf( glyphX - x ) + fabsf( glyphY - y );
+
+ if( distanceToGlyph < closestDistance )
+ {
+ closestDistance = distanceToGlyph;
+ closestGlyph = i;
+ }
+ }
+
+ // TODO - Consider RTL languages
+ x = positions[closestGlyph].x + glyphs[closestGlyph].width;
+ y = 0.0f;
+
+ FontMetrics metrics;
+ TextAbstraction::FontClient::Get().GetFontMetrics( glyphs[closestGlyph].fontId, metrics );
+ height = metrics.height; // TODO - Fix for multi-line
+ }
+
+ LogicalModelPtr mLogicalModel;
+ VisualModelPtr mVisualModel;
+ DecoratorPtr mDecorator;
+
+ State mState;
+
+ /**
+ * This is used to delay handling events until after the model has been updated.
+ * The number of updates to the model is minimized to improve performance.
+ */
+ vector<Event> mEventQueue; ///< The queue of touch events etc.
+
+ bool mDecoratorUpdated;
+};
+
+struct Controller::Impl
+{
+ Impl( ControlInterface& controlInterface )
+ : mControlInterface( controlInterface ),
+ mNewText(),
+ mOperations( NO_OPERATION ),
+ mControlSize(),
+ mTextInput( NULL )
+ {
+ mLogicalModel = LogicalModel::New();
+ mVisualModel = VisualModel::New();
+
+ mView.SetVisualModel( mVisualModel );
+
+ mFontClient = TextAbstraction::FontClient::Get();
+ }
+
+ ~Impl()
+ {
+ delete mTextInput;
+ }
+
+ ControlInterface& mControlInterface;
+
+ std::string mNewText;
+
+ LogicalModelPtr mLogicalModel;
+ VisualModelPtr mVisualModel;
+
+ View mView;
+
+ LayoutEngine mLayoutEngine;
+
+ TextAbstraction::FontClient mFontClient;
+
+ OperationsMask mOperations;
+
+ Size mControlSize;
+
+ // Avoid allocating everything for text input until EnableTextInput()
+ Controller::TextInput* mTextInput;
+};
+
+ControllerPtr Controller::New( ControlInterface& controlInterface )
+{
+ return ControllerPtr( new Controller( controlInterface ) );
+}
+
+void Controller::SetText( const std::string& text )
+{
+ // Keep until size negotiation
+ mImpl->mNewText = text;
+ mImpl->mOperations = ALL_OPERATIONS;
+
+ if( mImpl->mTextInput )
+ {
+ // Cancel previously queued events
+ mImpl->mTextInput->mEventQueue.clear();
+
+ // TODO - Hide selection decorations
+ }
+}
+
+void Controller::EnableTextInput( DecoratorPtr decorator )
+{
+ if( !mImpl->mTextInput )
+ {
+ mImpl->mTextInput = new TextInput( mImpl->mLogicalModel, mImpl->mVisualModel, decorator );
+ }
+}
+
+bool Controller::Relayout( const Vector2& size )
+{
+ if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
+ {
+ // Not worth to relayout if width or height is equal to zero.
+ return false;
+ }
+
+ bool updated = false;
+
+ if( size != mImpl->mControlSize )
+ {
+ updated = DoRelayout( size, mImpl->mOperations );
+
+ // Do not re-do any operation until something changes.
+ mImpl->mOperations = NO_OPERATION;
+
+ mImpl->mControlSize = size;
+ }
+
+ if( mImpl->mTextInput )
+ {
+ // Move the cursor, grab handle etc.
+ updated = mImpl->mTextInput->ProcessTouchEvents() || updated;
+ }
+
+ return updated;
+}
+
+bool Controller::DoRelayout( const Vector2& size, OperationsMask operations )
+{
+ bool viewUpdated( false );
+
+ Vector<Character> utf32Characters;
+ Length characterCount = 0u;
+ if( CONVERT_TO_UTF32 & operations )
+ {
+ std::string& text = mImpl->mNewText;
+
+ // Convert text into UTF-32
+ utf32Characters.Resize( text.size() );
+
+ // This is a bit horrible but std::string returns a (signed) char*
+ const uint8_t* utf8 = reinterpret_cast<const uint8_t*>( text.c_str() );
+
+ // Transform a text array encoded in utf8 into an array encoded in utf32.
+ // It returns the actual number of characters.
+ characterCount = Utf8ToUtf32( utf8, text.size(), utf32Characters.Begin() );
+ utf32Characters.Resize( characterCount );
+
+ // Sets the text into the model.
+ mImpl->mLogicalModel->SetText( utf32Characters.Begin(), characterCount );
+
+ // Discard temporary text
+ text.clear();
+ }
+
+ Vector<LineBreakInfo> lineBreakInfo;
+ if( GET_LINE_BREAKS & operations )
+ {
+ // Retrieves the line break info. The line break info is used to split the text in 'paragraphs' to
+ // calculate the bidirectional info for each 'paragraph'.
+ // It's also used to layout the text (where it should be a new line) or to shape the text (text in different lines
+ // is not shaped together).
+ lineBreakInfo.Resize( characterCount, TextAbstraction::LINE_NO_BREAK );
+
+ SetLineBreakInfo( utf32Characters,
+ lineBreakInfo );
+
+ mImpl->mLogicalModel->SetLineBreakInfo( lineBreakInfo.Begin(), characterCount );
+ }
+
+ const bool getScripts = GET_SCRIPTS & operations;
+ const bool validateFonts = VALIDATE_FONTS & operations;
+
+ Vector<ScriptRun> scripts;
+ Vector<FontRun> fonts;
+ if( getScripts || validateFonts )
+ {
+ // Validates the fonts assigned by the application or assigns default ones.
+ // It makes sure all the characters are going to be rendered by the correct font.
+ MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
+
+ if( getScripts )
+ {
+ // Retrieves the scripts used in the text.
+ multilanguageSupport.SetScripts( utf32Characters,
+ lineBreakInfo,
+ scripts );
+
+ // Sets the scripts into the model.
+ mImpl->mLogicalModel->SetScripts( scripts.Begin(), scripts.Count() );
+ }
+
+ if( validateFonts )
+ {
+ // Validates the fonts. If there is a character with no assigned font it sets a default one.
+ // After this call, fonts are validated.
+ multilanguageSupport.ValidateFonts( utf32Characters,
+ scripts,
+ fonts );
+
+ // Sets the fonts into the model.
+ mImpl->mLogicalModel->SetFonts( fonts.Begin(), fonts.Count() );
+ }
+ }
+
+ Vector<GlyphInfo> glyphs;
+ Vector<CharacterIndex> characterIndices;
+ Vector<Length> charactersPerGlyph;
+ if( SHAPE_TEXT & operations )
+ {
+ // Shapes the text.
+ ShapeText( utf32Characters,
+ lineBreakInfo,
+ scripts,
+ fonts,
+ glyphs,
+ characterIndices,
+ charactersPerGlyph );
+ }
+
+ if( GET_GLYPH_METRICS & operations )
+ {
+ mImpl->mFontClient.GetGlyphMetrics( glyphs.Begin(), glyphs.Count() );
+ }
+
+ if( LAYOUT & operations )
+ {
+ if( 0u == glyphs.Count() )
+ {
+ const Length numberOfGlyphs = mImpl->mVisualModel->GetNumberOfGlyphs();
+
+ glyphs.Resize( numberOfGlyphs );
+ characterIndices.Resize( numberOfGlyphs );
+ charactersPerGlyph.Resize( numberOfGlyphs );
+
+ mImpl->mVisualModel->GetGlyphs( glyphs.Begin(),
+ 0u,
+ numberOfGlyphs );
+
+ mImpl->mVisualModel->GetGlyphToCharacterMap( characterIndices.Begin(),
+ 0u,
+ numberOfGlyphs );
+
+ mImpl->mVisualModel->GetCharactersPerGlyphMap( charactersPerGlyph.Begin(),
+ 0u,
+ numberOfGlyphs );
+ }
+
+ // Update the visual model
+ mImpl->mLayoutEngine.UpdateVisualModel( size,
+ glyphs,
+ characterIndices,
+ charactersPerGlyph,
+ *mImpl->mVisualModel );
+
+ viewUpdated = true;
+ }
+
+ return viewUpdated;
+}
+
+Vector3 Controller::GetNaturalSize()
+{
+ // Operations that can be done only once until the text changes.
+ const OperationsMask onlyOnceOperations = static_cast<OperationsMask>( CONVERT_TO_UTF32 |
+ GET_SCRIPTS |
+ VALIDATE_FONTS |
+ GET_LINE_BREAKS |
+ GET_WORD_BREAKS |
+ SHAPE_TEXT |
+ GET_GLYPH_METRICS );
+
+ // Operations that need to be done if the size or the text changes.
+ const OperationsMask sizeOperations = static_cast<OperationsMask>( LAYOUT |
+ REORDER );
+
+ const float maxFloat = std::numeric_limits<float>::max();
+ DoRelayout( Vector2( maxFloat, maxFloat ),
+ static_cast<OperationsMask>( onlyOnceOperations |
+ sizeOperations ) );
+
+ // Do not do again the only once operations.
+ mImpl->mOperations = static_cast<OperationsMask>( mImpl->mOperations & ~onlyOnceOperations );
+
+ // Do the size related operations again.
+ mImpl->mOperations = static_cast<OperationsMask>( mImpl->mOperations | sizeOperations );
+
+ return Vector3( mImpl->mVisualModel->GetNaturalSize() );
+}
+
+float Controller::GetHeightForWidth( float width )
+{
+ // Operations that can be done only once until the text changes.
+ const OperationsMask onlyOnceOperations = static_cast<OperationsMask>( CONVERT_TO_UTF32 |
+ GET_SCRIPTS |
+ VALIDATE_FONTS |
+ GET_LINE_BREAKS |
+ GET_WORD_BREAKS |
+ SHAPE_TEXT |
+ GET_GLYPH_METRICS );
+
+ // Operations that need to be done if the size or the text changes.
+ const OperationsMask sizeOperations = static_cast<OperationsMask>( LAYOUT |
+ REORDER );
+
+ DoRelayout( Size( width, 0.f ),
+ static_cast<OperationsMask>( onlyOnceOperations |
+ sizeOperations ) );
+
+ // Do not do again the only once operations.
+ mImpl->mOperations = static_cast<OperationsMask>( mImpl->mOperations & ~onlyOnceOperations );
+
+ // Do the size related operations again.
+ mImpl->mOperations = static_cast<OperationsMask>( mImpl->mOperations | sizeOperations );
+
+ return mImpl->mVisualModel->GetActualSize().height;
+}
+
+View& Controller::GetView()
+{
+ return mImpl->mView;
+}
+
+LayoutEngine& Controller::GetLayoutEngine()
+{
+ return mImpl->mLayoutEngine;
+}
+
+void Controller::RequestRelayout()
+{
+ mImpl->mControlInterface.RequestTextRelayout();
+}
+
+void Controller::KeyboardFocusGainEvent()
+{
+ DALI_ASSERT_DEBUG( mImpl->mTextInput && "Unexpected KeyboardFocusGainEvent" );
+
+ if( mImpl->mTextInput )
+ {
+ TextInput::Event event( TextInput::KEYBOARD_FOCUS_GAIN_EVENT );
+ mImpl->mTextInput->mEventQueue.push_back( event );
+
+ RequestRelayout();
+ }
+}
+
+void Controller::KeyboardFocusLostEvent()
+{
+ DALI_ASSERT_DEBUG( mImpl->mTextInput && "Unexpected KeyboardFocusLostEvent" );
+
+ if( mImpl->mTextInput )
+ {
+ TextInput::Event event( TextInput::KEYBOARD_FOCUS_LOST_EVENT );
+ mImpl->mTextInput->mEventQueue.push_back( event );
+
+ RequestRelayout();
+ }
+}
+
+void Controller::TapEvent( unsigned int tapCount, float x, float y )
+{
+ DALI_ASSERT_DEBUG( mImpl->mTextInput && "Unexpected TapEvent" );
+
+ if( mImpl->mTextInput )
+ {
+ TextInput::Event event( TextInput::TAP_EVENT );
+ event.p1.mUint = tapCount;
+ event.p2.mFloat = x;
+ event.p3.mFloat = y;
+ mImpl->mTextInput->mEventQueue.push_back( event );
+
+ RequestRelayout();
+ }
+}
+
+void Controller::GrabHandleEvent( GrabHandleState state, float x, float y )
+{
+ DALI_ASSERT_DEBUG( mImpl->mTextInput && "Unexpected GrabHandleEvent" );
+
+ if( mImpl->mTextInput )
+ {
+ TextInput::Event event( TextInput::GRAB_HANDLE_EVENT );
+ event.p1.mUint = state;
+ event.p2.mFloat = x;
+ event.p3.mFloat = y;
+ mImpl->mTextInput->mEventQueue.push_back( event );
+
+ RequestRelayout();
+ }
+}
+
+Controller::~Controller()
+{
+ delete mImpl;
+}
+
+Controller::Controller( ControlInterface& controlInterface )
+: mImpl( NULL )
+{
+ mImpl = new Controller::Impl( controlInterface );
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_CONTROLLER_H__
+#define __DALI_TOOLKIT_TEXT_CONTROLLER_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/decorator/text-decorator.h>
+#include <dali-toolkit/public-api/text/text-control-interface.h>
+#include <dali-toolkit/public-api/text/text-view.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/math/vector3.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/object/ref-object.h>
+#include <string>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+class Controller;
+class LayoutEngine;
+
+typedef IntrusivePtr<Controller> ControllerPtr;
+typedef Dali::Toolkit::Text::ControlInterface ControlInterface;
+
+/**
+ * @brief A Text Controller is used by UI Controls which display text.
+ *
+ * It manipulates the Logical & Visual text models on behalf of the UI Controls.
+ * It provides a view of the text that can be used by rendering back-ends.
+ *
+ * For selectable/editable UI controls, the controller handles input events from the UI control
+ * and decorations (grab handles etc) via an observer interface.
+ */
+class Controller : public RefObject, public Decorator::Observer
+{
+private:
+
+ /**
+ * @brief Text related operations to be done in the relayout process.
+ */
+ enum OperationsMask
+ {
+ NO_OPERATION = 0x0,
+ CONVERT_TO_UTF32 = 0x1,
+ GET_SCRIPTS = 0x2,
+ VALIDATE_FONTS = 0x4,
+ GET_LINE_BREAKS = 0x8,
+ GET_WORD_BREAKS = 0x10,
+ SHAPE_TEXT = 0x20,
+ GET_GLYPH_METRICS = 0x40,
+ LAYOUT = 0x80,
+ REORDER = 0x100,
+ ALIGNMENT = 0x200,
+ RENDER = 0x400,
+ ALL_OPERATIONS = 0xFFF
+ };
+
+public:
+
+ /**
+ * @brief Create a new instance of a Controller.
+ *
+ * @param[in] controlInterface An interface used to request a text relayout.
+ * @return A pointer to a new Controller.
+ */
+ static ControllerPtr New( ControlInterface& controlInterface );
+
+ /**
+ * @brief Replaces any text previously set.
+ *
+ * @note This will be converted into UTF-32 when stored in the text model.
+ * @param[in] text A string of UTF-8 characters.
+ */
+ void SetText( const std::string& text );
+
+ /**
+ * @brief Called to enable text input.
+ *
+ * @note Only selectable or editable controls should calls this.
+ * @param[in] decorator Used to create cursor, selection handle decorations etc.
+ */
+ void EnableTextInput( DecoratorPtr decorator );
+
+ /**
+ * @brief Triggers a relayout which updates View (if necessary).
+ *
+ * @note UI Controls are expected to minimize calls to this method e.g. call once after size negotiation.
+ * @param[in] size A the size of a bounding box to layout text within.
+ * @return True if the text model or decorations were updated.
+ */
+ bool Relayout( const Vector2& size );
+
+ /**
+ *
+ */
+ bool DoRelayout( const Vector2& size, OperationsMask operations );
+
+ /**
+ * @copydoc Control::GetNaturalSize()
+ */
+ Vector3 GetNaturalSize();
+
+ /**
+ * @copydoc Control::GetHeightForWidth()
+ */
+ float GetHeightForWidth( float width );
+
+ /**
+ * @brief Return the layout engine.
+ *
+ * @return A reference to the layout engine.
+ */
+ LayoutEngine& GetLayoutEngine();
+
+ /**
+ * @brief Return a view of the text.
+ *
+ * @return A reference to the view.
+ */
+ View& GetView();
+
+ /**
+ * @brief Caller by editable UI controls when keyboard focus is gained.
+ */
+ void KeyboardFocusGainEvent();
+
+ /**
+ * @brief Caller by editable UI controls when focus is lost.
+ */
+ void KeyboardFocusLostEvent();
+
+ /**
+ * @brief Caller by editable UI controls when a tap gesture occurs.
+ * @param[in] tapCount The number of taps.
+ * @param[in] x The x position relative to the top-left of the parent control.
+ * @param[in] y The y position relative to the top-left of the parent control.
+ */
+ void TapEvent( unsigned int tapCount, float x, float y );
+
+ /**
+ * @copydoc Dali::Toolkit::Text::Decorator::Observer::GrabHandleEvent()
+ */
+ virtual void GrabHandleEvent( GrabHandleState state, float x, float y );
+
+protected:
+
+ /**
+ * @brief A reference counted object may only be deleted by calling Unreference().
+ */
+ virtual ~Controller();
+
+private:
+
+ /**
+ * @brief Request a relayout using the ControlInterface.
+ */
+ void RequestRelayout();
+
+ /**
+ * @brief Private constructor.
+ */
+ Controller( ControlInterface& controlInterface );
+
+ // Undefined
+ Controller( const Controller& handle );
+
+ // Undefined
+ Controller& operator=( const Controller& handle );
+
+private:
+
+ struct Impl;
+ Impl* mImpl;
+
+ // Avoid allocating this for non-editable controls
+ struct TextInput;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_CONTROLLER_H__
--- /dev/null
+#ifndef __DALI_TEXT_ABSTRACTION_TEXT_TYPE_DEFINITIONS_H__
+#define __DALI_TEXT_ABSTRACTION_TEXT_TYPE_DEFINITIONS_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/text-abstraction/text-abstraction-definitions.h>
+#include <dali/public-api/text-abstraction/font-metrics.h>
+#include <dali/public-api/text-abstraction/glyph-info.h>
+#include <dali/public-api/text-abstraction/script.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+typedef TextAbstraction::FontId FontId; ///< The unique identifier for a font face (generated by FontClient).
+typedef TextAbstraction::FontMetrics FontMetrics; ///< The metrics for a Font expressed in 26.6 fractional pixel format.
+typedef TextAbstraction::PointSize26Dot6 PointSize26Dot6; ///< The point size in 26.6 fractional points.
+typedef TextAbstraction::FaceIndex FaceIndex; ///< Used with fonts which allow several font faces.
+typedef TextAbstraction::GlyphIndex GlyphIndex; ///< Uniquely identifies a glyph within a particular font.
+typedef TextAbstraction::Character Character; ///< A UTF-32 representation of a character.
+typedef TextAbstraction::GlyphInfo GlyphInfo; ///< The information describing a glyph (font ID, index, metrics).
+typedef TextAbstraction::CharacterIndex CharacterIndex; ///< An index into an array of characters.
+typedef TextAbstraction::Length Length; ///< The length of an array.
+typedef TextAbstraction::BidiInfoIndex BidiInfoIndex; ///< Index to the bidirectional info for a paragraph.
+typedef TextAbstraction::Script Script; ///< The character's script.
+typedef TextAbstraction::LineBreakInfo LineBreakInfo; ///< Line break info (must break, allow break, no break). Possible values are: @e LINE_MUST_BREAK, @e LINE_ALLOW_BREAK and @e LINE_NO_BREAK (in the TextAbstraction namespace).
+typedef TextAbstraction::WordBreakInfo WordBreakInfo; ///< Word break info (break, no break). Possible values are: @e WORD_BREAK and @e WORD_NO_BREAK (in the TextAbstraction namespace).
+
+typedef uint32_t GlyphIndex; ///< An index into an array of glyphs.
+typedef bool CharacterDirection; ///< The character's direction: @e false is left to right, @e true is right to left.
+typedef uint32_t LineIndex; ///< An index into an array of lines.
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TEXT_ABSTRACTION_TEXT_TYPE_DEFINITIONS_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/public-api/text/script.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace
+{
+const unsigned int WHITE_SPACE_THRESHOLD = 0x21; ///< All characters below 0x21 are considered white spaces.
+const unsigned int CHAR_FL = 0x000A; ///< NL Line feed, new line.
+const unsigned int CHAR_VT = 0x000B; ///< Vertical tab.
+const unsigned int CHAR_FF = 0x000C; ///< NP Form feed, new page.
+const unsigned int CHAR_NEL = 0x0085; ///< Next line.
+const unsigned int CHAR_LS = 0x2028; ///< Line separator.
+const unsigned int CHAR_PS = 0x2029; ///< Paragraph separator
+
+const unsigned int CHAR_ZWS = 0x200B; ///< Zero width space.
+const unsigned int CHAR_ZWNJ = 0x200C; ///< Zero width non joiner.
+const unsigned int CHAR_ZWJ = 0x200D; ///< Zero width joiner.
+const unsigned int CHAR_LTRM = 0x200E; ///< Left to Right Mark.
+const unsigned int CHAR_RTLM = 0x200F; ///< Right to Left Mark.
+const unsigned int CHAR_TS = 0x2009; ///< Thin Space.
+} // namespace
+
+Script GetCharacterScript( Character character )
+{
+ // Latin script:
+ // 0x0000 - 0x007f C0 Controls and Basic Latin
+ // 0x0080 - 0x00ff C1 Controls and Latin-1 Supplement
+ // 0x0100 - 0x017f Latin Extended-A
+ // 0x0180 - 0x024f Latin Extended-B
+ // 0x0250 - 0x02af IPA Extensions
+ // 0x02b0 - 0x02ff Spacing Modifier Letters
+ // 0x1d00 - 0x1d7f Phonetic Extensions
+ // 0x1d80 - 0x1dbf Phonetic Extensions Supplement
+ // 0x1e00 - 0x1eff Latin Extended Additional
+ // 0x2070 - 0x209f Superscripts and Subscripts
+ // 0x2100 - 0x214f Letterlike symbols
+ // 0x2150 - 0x218f Number Forms
+ // 0x2c60 - 0x2c7f Latin Extended-C
+ // 0xa720 - 0xa7ff Latin Extended-D
+ // 0xab30 - 0xab6f Latin Extended-E
+ // 0xfb00 - 0xfb4f Alphabetic Presentation Forms
+ // 0xff00 - 0xffef Halfwidth and Fullwidth Forms
+
+ // Brahmic scripts:
+ // 0x0900 - 0x097f Devanagari
+ // 0x0980 - 0x09ff Bengali
+ // 0x0a00 - 0x0a7f Gurmukhi
+ // 0x0a80 - 0x0aff Gujarati
+ // 0x0b00 - 0x0b7f Oriya
+ // 0x0b80 - 0x0bff Tamil
+ // 0x0c00 - 0x0c7f Telugu
+ // 0x0c80 - 0x0cff Kannada
+ // 0x0d00 - 0x0d7f Malayalam
+
+ // Sinhala script.
+ // 0x0d80 - 0x0dff Sinhala
+
+ // Arabic script.
+ // 0x0600 - 0x06ff Arabic
+ // 0x0750 - 0x077f Arabic Supplement
+ // 0x08A0 - 0x08ff Arabic Extended-A
+ // 0xfb50 - 0xfdff Arabic Presentation Forms-A
+ // 0xfe70 - 0xfeff Arabic Presentation Forms-B
+ // 0x1ee00 - 0x1eeff Arabic Mathematical Alphabetic Symbols
+
+ // CJK and Vietnamese script.
+ // 0x2E80 - 0x2eff CJK Radicals Supplement
+ // 0x3000 - 0x303f CJK Symbols and Punctuation
+ // 0x3200 - 0x32ff Enclosed CJK Letters and Months
+ // 0x3400 - 0x4dbf CJK Unified Ideographs Extension A
+ // 0x4e00 - 0x62ff CJK Unified Ideographs
+ // 0x6300 - 0x77ff CJK Unified Ideographs
+ // 0x7800 - 0x8cff CJK Unified Ideographs
+ // 0x8d00 - 0x9fff CJK Unified Ideographs
+ // 0x20000 - 0x215ff CJK Unified Ideographs Extension B
+ // 0x21600 - 0x230ff CJK Unified Ideographs Extension B
+ // 0x23100 - 0x245ff CJK Unified Ideographs Extension B
+ // 0x24600 - 0x260ff CJK Unified Ideographs Extension B
+ // 0x26100 - 0x275ff CJK Unified Ideographs Extension B
+ // 0x27600 - 0x290ff CJK Unified Ideographs Extension B
+ // 0x29100 - 0x2a6df CJK Unified Ideographs Extension B
+ // 2a700-2b73f. CJK Unified Ideographs Extension C
+ // 2b740-2b81f. CJK Unified Ideographs Extension D
+
+ // Hangul script
+ // 0x1100 - 0x11ff Hangul jamo
+ // 0x3130 - 0x318f Hangul Compatibility Jamo
+ // 0xa960 - 0xa97f Hangul Jamo Extended-A
+ // 0xac00 - 0xd7af Hangul Syllables
+ // 0xd7b0 - 0xd7ff Hangul Jamo Extended-B
+
+ // Khmer script
+ // 0x1780 - 0x17ff Khmer
+ // 0x19e0 - 0x19ff Khmer Symbols
+
+ // Lao script
+ // 0x0e80 - 0x0eff Lao
+
+ // Thai script
+ // 0x0e00 - 0x0e7f Thai
+
+ // Burmese script
+ // 0x1000 - 0x109f Myanmar
+
+ if( character <= 0x0cff )
+ {
+ if( character <= 0x09ff )
+ {
+ if( character <= 0x077f )
+ {
+ if( character <= 0x02ff )
+ {
+ return TextAbstraction::LATIN;
+ }
+ if( ( 0x0600 <= character ) && ( character <= 0x06ff ) )
+ {
+ return TextAbstraction::ARABIC;
+ }
+ if( ( 0x0750 <= character ) && ( character <= 0x077f ) )
+ {
+ return TextAbstraction::ARABIC;
+ }
+ }
+ else // > 0x077f
+ {
+ if( ( 0x08A0 <= character ) && ( character <= 0x08ff ) )
+ {
+ return TextAbstraction::ARABIC;
+ }
+ if( ( 0x0900 <= character ) && ( character <= 0x097f ) )
+ {
+ return TextAbstraction::DEVANAGARI;
+ }
+ if( ( 0x0980 <= character ) && ( character <= 0x09ff ) )
+ {
+ return TextAbstraction::BENGALI;
+ }
+ }
+ }
+ else // > 0x09ff
+ {
+ if( character <= 0x0b7f )
+ {
+ if( ( 0x0a00 <= character ) && ( character <= 0x0a7f ) )
+ {
+ return TextAbstraction::GURMUKHI;
+ }
+ if( ( 0x0a80 <= character ) && ( character <= 0x0aff ) )
+ {
+ return TextAbstraction::GUJARATI;
+ }
+ if( ( 0x0b00 <= character ) && ( character <= 0x0b7f ) )
+ {
+ return TextAbstraction::ORIYA;
+ }
+ }
+ else // > 0x0b7f
+ {
+ if( ( 0x0b80 <= character ) && ( character <= 0x0bff ) )
+ {
+ return TextAbstraction::TAMIL;
+ }
+ if( ( 0x0c00 <= character ) && ( character <= 0x0c7f ) )
+ {
+ return TextAbstraction::TELUGU;
+ }
+ if( ( 0x0c80 <= character ) && ( character <= 0x0cff ) )
+ {
+ return TextAbstraction::KANNADA;
+ }
+ }
+ }
+ }
+ else // > 0x0cff
+ {
+ if( character <= 0x2c7f )
+ {
+ if( character <= 0x1eff )
+ {
+ if( ( 0x0d00 <= character ) && ( character <= 0x0d7f ) )
+ {
+ return TextAbstraction::MALAYALAM;
+ }
+ if( ( 0x0d80 <= character ) && ( character <= 0x0dff ) )
+ {
+ return TextAbstraction::SINHALA;
+ }
+ if( ( 0x0e00 <= character ) && ( character <= 0x0e7f ) )
+ {
+ return TextAbstraction::THAI;
+ }
+ if( ( 0x0e80 <= character ) && ( character <= 0x0eff ) )
+ {
+ return TextAbstraction::LAO;
+ }
+ if( ( 0x1000 <= character ) && ( character <= 0x109f ) )
+ {
+ return TextAbstraction::BURMESE;
+ }
+ if( ( 0x1100 <= character ) && ( character <= 0x11ff ) )
+ {
+ return TextAbstraction::HANGUL;
+ }
+ if( ( 0x1780 <= character ) && ( character <= 0x17ff ) )
+ {
+ return TextAbstraction::KHMER;
+ }
+ if( ( 0x19e0 <= character ) && ( character <= 0x19ff ) )
+ {
+ return TextAbstraction::KHMER;
+ }
+ if( ( 0x1d00 <= character ) && ( character <= 0x1eff ) )
+ {
+ return TextAbstraction::LATIN;
+ }
+ }
+ else // > 0x1eff
+ {
+ if( ( 0x2070 <= character ) && ( character <= 0x209f ) )
+ {
+ return TextAbstraction::LATIN;
+ }
+ if( ( 0x2100 <= character ) && ( character <= 0x218f ) )
+ {
+ return TextAbstraction::LATIN;
+ }
+ if( ( 0x2c60 <= character ) && ( character <= 0x2c7f ) )
+ {
+ return TextAbstraction::LATIN;
+ }
+ }
+ }
+ else // > 0x2c7f
+ {
+ if( character <= 0xfdff )
+ {
+ if( ( 0x2e80 <= character ) && ( character <= 0x2eff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x3000 <= character ) && ( character <= 0x303f ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x3130 <= character ) && ( character <= 0x318f ) )
+ {
+ return TextAbstraction::HANGUL;
+ }
+ if( ( 0x3200 <= character ) && ( character <= 0x32ff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x3400 <= character ) && ( character <= 0x4dbf ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x4e00 <= character ) && ( character <= 0x62ff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x6300 <= character ) && ( character <= 0x77ff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x7800 <= character ) && ( character <= 0x8cff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x8d00 <= character ) && ( character <= 0x9fff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0xa720 <= character ) && ( character <= 0xa7ff ) )
+ {
+ return TextAbstraction::LATIN;
+ }
+ if( ( 0xa960 <= character ) && ( character <= 0xa97f ) )
+ {
+ return TextAbstraction::HANGUL;
+ }
+ if( ( 0xab30 <= character ) && ( character <= 0xab6f ) )
+ {
+ return TextAbstraction::LATIN;
+ }
+ if( ( 0xac00 <= character ) && ( character <= 0xd7af ) )
+ {
+ return TextAbstraction::HANGUL;
+ }
+ if( ( 0xd7b0 <= character ) && ( character <= 0xd7ff ) )
+ {
+ return TextAbstraction::HANGUL;
+ }
+ if( ( 0xfb00 <= character ) && ( character <= 0xfb4f ) )
+ {
+ return TextAbstraction::LATIN;
+ }
+ if( ( 0xfb50 <= character ) && ( character <= 0xfdff ) )
+ {
+ return TextAbstraction::ARABIC;
+ }
+ }
+ else // > 0xfdff
+ {
+ if( ( 0xfe70 <= character ) && ( character <= 0xfeff ) )
+ {
+ return TextAbstraction::ARABIC;
+ }
+ if( ( 0xff00 <= character ) && ( character <= 0xffef ) )
+ {
+ return TextAbstraction::LATIN;
+ }
+ if( ( 0x1ee00 <= character ) && ( character <= 0x1eeff ) )
+ {
+ return TextAbstraction::ARABIC;
+ }
+ if( ( 0x20000 <= character ) && ( character <= 0x215ff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x21600 <= character ) && ( character <= 0x230ff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x23100 <= character ) && ( character <= 0x245ff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x24600 <= character ) && ( character <= 0x260ff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x26100 <= character ) && ( character <= 0x275ff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x27600 <= character ) && ( character <= 0x290ff ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x29100 <= character ) && ( character <= 0x2a6df ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x2a700 <= character ) && ( character <= 0x2b73f ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ if( ( 0x2b740 <= character ) && ( character <= 0x2b81f ) )
+ {
+ return TextAbstraction::CJK;
+ }
+ }
+ }
+ }
+
+ return TextAbstraction::UNKNOWN;
+}
+
+bool IsWhiteSpace( Character character )
+{
+ return character < WHITE_SPACE_THRESHOLD;
+}
+
+bool IsNewParagraph( Character character )
+{
+ return ( ( CHAR_FL == character ) ||
+ ( CHAR_VT == character ) ||
+ ( CHAR_FF == character ) ||
+ ( CHAR_NEL == character ) ||
+ ( CHAR_LS == character ) ||
+ ( CHAR_PS == character ) );
+}
+
+bool IsZeroWidthNonJoiner( Character character )
+{
+ return CHAR_ZWNJ == character;
+}
+
+bool IsZeroWidthJoiner( Character character )
+{
+ return CHAR_ZWJ == character;
+}
+
+bool IsZeroWidthSpace( Character character )
+{
+ return CHAR_ZWS == character;
+}
+
+bool IsLeftToRightMark( Character character )
+{
+ return CHAR_LTRM == character;
+}
+
+bool IsRightToLeftMark( Character character )
+{
+ return CHAR_RTLM == character;
+}
+
+bool IsThinSpace( Character character )
+{
+ return CHAR_TS == character;
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/text-view-interface.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+ViewInterface::ViewInterface()
+{
+}
+
+ViewInterface::~ViewInterface()
+{
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_VIEW_INTERFACE_H__
+#define __DALI_TOOLKIT_TEXT_VIEW_INTERFACE_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/text-definitions.h>
+
+namespace Dali
+{
+
+struct Vector2;
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Abstract interface to provide the information necessary displaying text.
+ *
+ * This includes:
+ * - The font & glyph IDs needed to get bitmaps etc. from TextAbstraction
+ * - The visual position of each glyph within the layout
+ * - A window into the text layout e.g. which page of a document to view
+ */
+class ViewInterface
+{
+public:
+
+ /**
+ * @brief Constructor.
+ */
+ ViewInterface();
+
+ /**
+ * @brief Virtual destructor
+ */
+ virtual ~ViewInterface();
+
+ /**
+ * Retrieves the number of glyphs.
+ *
+ * @return The number of glyphs.
+ */
+ virtual Length GetNumberOfGlyphs() const = 0;
+
+ /**
+ * @brief Retrieves glyphs in the given buffer.
+ *
+ * The size of the @p glyphs buffer needs to be big enough to copy the @p numberOfGlyphs.
+ * @param[out] glyphs Pointer to a buffer where the glyphs are copied.
+ * @param[in] glyphIndex Index to the first glyph.
+ * @param[in] numberOfGlyphs Number of glyphs to be copied.
+ */
+ virtual void GetGlyphs( GlyphInfo* glyphs,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const = 0;
+
+ /**
+ * @brief Retrieves the glyph positions.
+ *
+ * @pre The size of the @p positions buffer needs to be big enough to copy the @p numberOfGlyphs positions.
+ * @param[out] glyphPositions Pointer to a buffer where the glyph positions are copied.
+ * @param[in] glyphIndex Index to the first glyph position.
+ * @param[in] numberOfGlyphs The number of positions to be copied.
+ */
+ virtual void GetGlyphPositions( Vector2* glyphPositions,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const = 0;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_VIEW_INTERFACE_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/text-view.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/vector2.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct View::Impl
+{
+ VisualModelPtr mVisualModel;
+};
+
+View::View()
+: mImpl( NULL )
+{
+ mImpl = new View::Impl();
+}
+
+View::~View()
+{
+ delete mImpl;
+}
+
+void View::SetVisualModel( VisualModelPtr visualModel )
+{
+ mImpl->mVisualModel = visualModel;
+}
+
+Length View::GetNumberOfGlyphs() const
+{
+ if( mImpl->mVisualModel )
+ {
+ return mImpl->mVisualModel->GetNumberOfGlyphs();
+ }
+
+ return 0;
+}
+
+void View::GetGlyphs( GlyphInfo* glyphs,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+ if( mImpl->mVisualModel )
+ {
+ mImpl->mVisualModel->GetGlyphs( glyphs, glyphIndex, numberOfGlyphs );
+ }
+}
+
+void View::GetGlyphPositions( Vector2* glyphPositions,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+ if( mImpl->mVisualModel )
+ {
+ mImpl->mVisualModel->GetGlyphPositions( glyphPositions, glyphIndex, numberOfGlyphs );
+ }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_VIEW_H__
+#define __DALI_TOOLKIT_TEXT_VIEW_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/text-view-interface.h>
+#include <dali-toolkit/public-api/text/visual-model.h>
+
+namespace Dali
+{
+
+struct Vector2;
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief View provides an interface between the Text layout engine and rendering back-end.
+ */
+class View : public ViewInterface
+{
+public:
+
+ /**
+ * @brief Create a new instance of a View.
+ */
+ View();
+
+ /**
+ * @brief Virtual destructor.
+ */
+ virtual ~View();
+
+ /**
+ * @brief Set the visual model.
+ *
+ * @param[in] visualModel The visual model used by the View.
+ */
+ void SetVisualModel( VisualModelPtr visualModel );
+
+ /**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::GetNumberOfGlyphs()
+ */
+ virtual Length GetNumberOfGlyphs() const;
+
+ /**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::GetGlyphs()
+ */
+ virtual void GetGlyphs( GlyphInfo* glyphs,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+
+ /**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::GetGlyphPositions()
+ */
+ virtual void GetGlyphPositions( Vector2* glyphPositions,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+
+private:
+
+ // Undefined
+ View( const View& handle );
+
+ // Undefined
+ View& operator=( const View& handle );
+
+private:
+
+ struct Impl;
+ Impl* mImpl;
+};
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_VIEW_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/text/visual-model.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali-toolkit/public-api/text/line-run.h>
+
+// EXTERNAL INCLUDES
+#include <memory.h>
+#include <vector>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+const GlyphInfo GLYPH_INFO; // VCC to be removed.
+
+struct VisualModel::Impl
+{
+ Vector<GlyphInfo> mGlyphs;
+ Vector<CharacterIndex> mGlyphsToCharacters;
+ Vector<Length> mCharactersPerGlyph;
+ std::vector<Vector2> mGlyphPositions;
+
+ Size mNaturalSize;
+ Size mActualSize;
+};
+
+VisualModelPtr VisualModel::New()
+{
+ return VisualModelPtr( new VisualModel() );
+}
+
+void VisualModel::SetGlyphs( const GlyphInfo* glyphs,
+ const CharacterIndex* characterIndices,
+ const Length* charactersPerGlyph,
+ Length numberOfGlyphs )
+{
+ Vector<GlyphInfo>& modelGlyphs = mImpl->mGlyphs;
+ modelGlyphs.Resize( numberOfGlyphs );
+ memcpy( &modelGlyphs[0], glyphs, numberOfGlyphs*sizeof(GlyphInfo) );
+
+ Vector<CharacterIndex>& glyphsToCharacters = mImpl->mGlyphsToCharacters;
+ glyphsToCharacters.Resize( numberOfGlyphs );
+ memcpy( &glyphsToCharacters[0], characterIndices, numberOfGlyphs*sizeof(CharacterIndex) );
+
+ Vector<Length>& modelCharactersPerGlyph = mImpl->mCharactersPerGlyph;
+ modelCharactersPerGlyph.Resize( numberOfGlyphs );
+ memcpy( &modelCharactersPerGlyph[0], charactersPerGlyph, numberOfGlyphs*sizeof(Length) );
+}
+
+Length VisualModel::GetNumberOfGlyphs() const
+{
+ return mImpl->mGlyphs.Count();
+}
+
+void VisualModel::GetGlyphs( GlyphInfo* glyphs,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+ Vector<GlyphInfo>& modelGlyphs = mImpl->mGlyphs;
+ memcpy( glyphs, &modelGlyphs[glyphIndex], numberOfGlyphs*sizeof(GlyphInfo) );
+}
+
+const GlyphInfo& VisualModel::GetGlyphInfo( GlyphIndex glyphIndex ) const
+{
+ return GLYPH_INFO;
+}
+
+CharacterIndex VisualModel::GetCharacterIndex( GlyphIndex glyphIndex ) const
+{
+ return mImpl->mGlyphsToCharacters[glyphIndex];
+}
+
+Length VisualModel::GetCharactersPerGlyph( GlyphIndex glyphIndex ) const
+{
+ return mImpl->mCharactersPerGlyph[glyphIndex];
+}
+
+GlyphIndex VisualModel::GetGlyphIndex( CharacterIndex characterIndex ) const
+{
+ GlyphIndex index( 0 );
+
+ for( unsigned int i=0; i<mImpl->mGlyphsToCharacters.Count(); ++i )
+ {
+ if( mImpl->mGlyphsToCharacters[i] == characterIndex )
+ {
+ index = i;
+ break;
+ }
+ }
+
+ return index;
+}
+
+void VisualModel::GetCharacterToGlyphMap( GlyphIndex* characterToGlyphMap,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+}
+
+void VisualModel::GetCharactersPerGlyphMap( Length* charactersPerGlyph,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+}
+
+void VisualModel::GetGlyphToCharacterMap( CharacterIndex* glyphToCharacter,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+}
+
+void VisualModel::SetGlyphPositions( const Vector2* glyphPositions,
+ Length numberOfGlyphs )
+{
+ std::vector<Vector2>& modelPositions = mImpl->mGlyphPositions;
+ modelPositions.resize( numberOfGlyphs );
+ memcpy( &modelPositions[0], glyphPositions, numberOfGlyphs*sizeof(Vector2) );
+}
+
+void VisualModel::GetGlyphPositions( Vector2* glyphPositions,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+ std::vector<Vector2>& modelPositions = mImpl->mGlyphPositions;
+ memcpy( glyphPositions, &modelPositions[0], numberOfGlyphs*sizeof(Vector2) );
+}
+
+const Vector2& VisualModel::GetGlyphPosition( GlyphIndex glyphIndex ) const
+{
+ return Vector2::ZERO;
+}
+
+void VisualModel::SetLines( const LineRun* const lines,
+ Length numberOfLines )
+{
+}
+
+Length VisualModel::GetNumberOfLines() const
+{
+ return 0u;
+}
+
+void VisualModel::GetLines( LineRun* lines,
+ LineIndex lineIndex,
+ Length numberOfLines ) const
+{
+}
+
+Length VisualModel::GetNumberOfLines( GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+ return 0u;
+}
+
+void VisualModel::GetLinesOfGlyphRange( LineRun* lines,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+}
+
+void VisualModel::SetNaturalSize( const Vector2& size )
+{
+ mImpl->mNaturalSize = size;
+}
+
+const Vector2& VisualModel::GetNaturalSize() const
+{
+ return mImpl->mNaturalSize;
+}
+
+void VisualModel::SetActualSize( const Vector2& size )
+{
+ mImpl->mActualSize = size;
+}
+
+const Vector2& VisualModel::GetActualSize() const
+{
+ return mImpl->mActualSize;
+}
+
+VisualModel::~VisualModel()
+{
+ delete mImpl;
+}
+
+VisualModel::VisualModel()
+: mImpl( NULL )
+{
+ mImpl = new VisualModel::Impl();
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_VISUAL_MODEL_H__
+#define __DALI_TOOLKIT_TEXT_VISUAL_MODEL_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/ref-object.h>
+#include <dali-toolkit/public-api/text/text-definitions.h>
+
+namespace Dali
+{
+
+struct Vector2;
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct LineRun;
+class VisualModel;
+typedef IntrusivePtr<VisualModel> VisualModelPtr;
+
+/**
+ * @brief A visual text model contains layout specific information.
+ *
+ * This includes:
+ * - A series of glyphs in visual order i.e. after the bidirectional reordering.
+ * - The position of each glyph within a 2D bounding box.
+ */
+class VisualModel : public RefObject
+{
+public:
+
+ /**
+ * @brief Create a new instance of a VisualModel.
+ *
+ * @return A pointer to a new VisualModel.
+ */
+ static VisualModelPtr New();
+
+ // Glyph interface.
+
+ /**
+ * @brief Replaces any glyphs previously set.
+ *
+ * @param[in] glyphs An array of glyphs in the visual order.
+ * @param[in] characterIndices An array containing the first character in the logical model that each glyph relates to.
+ * @param[in] charactersPerGlyph An array containing the number of characters per glyph.
+ * @param[in] numberOfGlyphs The number of glyphs.
+ */
+ void SetGlyphs( const GlyphInfo* glyphs,
+ const CharacterIndex* characterIndices,
+ const Length* charactersPerGlyph,
+ Length numberOfGlyphs );
+
+ /**
+ * Retrieves the number of glyphs.
+ *
+ * @return The number of glyphs.
+ */
+ Length GetNumberOfGlyphs() const;
+
+ /**
+ * @brief Retrieves glyphs in the given buffer.
+ *
+ * The size of the @p glyphs buffer needs to be big enough to copy the @p numberOfGlyphs.
+ * @param[out] glyphs Pointer to a buffer where the glyphs are copied.
+ * @param[in] glyphIndex Index to the first glyph.
+ * @param[in] numberOfGlyphs Number of glyphs to be copied.
+ */
+ void GetGlyphs( GlyphInfo* glyphs,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+
+ /**
+ * Retrieves a glyph.
+ *
+ * @param[in] glyphIndex Index to a glyph.
+ *
+ * @return A glyph.
+ */
+ const GlyphInfo& GetGlyphInfo( GlyphIndex glyphIndex ) const;
+
+ // Character <--> Glyph conversion
+
+ /**
+ * @brief Retrieves the first character in the logical model which a glyph represents.
+ *
+ * @note After shaping several characters may be represented by the same glyph.
+ * Alternatively several glyphs may be required to display a character.
+ * @param[in] glyphIndex The glyph index.
+ * @return The character index.
+ */
+ CharacterIndex GetCharacterIndex( GlyphIndex glyphIndex ) const;
+
+ /**
+ * @brief Query the number of characters the glyph represents.
+ *
+ * @param[in] glyphIndex The glyph index.
+ * @return The number of characters represented by the glyph.
+ */
+ Length GetCharactersPerGlyph( GlyphIndex glyphIndex ) const;
+
+ /**
+ * Retrieves the first glyph in the visual model which represents a given character.
+ *
+ * @note After shaping several characters may be represented by the same glyph.
+ * Alternatively several glyphs may be required to display a character.
+ * @param[in] characterIndex The character index.
+ * @return The glyph index.
+ */
+ GlyphIndex GetGlyphIndex( CharacterIndex characterIndex ) const;
+
+ /**
+ * Retrieves the whole or part of the character to glyph conversion map.
+ *
+ * The size of the buffer needs to be big enough to copy the @p numberOfCharacters.
+ *
+ * @param[out] characterToGlyphMap Pointer to a buffer where the conversion map is copied.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void GetCharacterToGlyphMap( GlyphIndex* characterToGlyphMap,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ /**
+ * Retrieves for each glyph the number of characters the glyph represents.
+ *
+ * @param[out] charactersPerGlyph Pointer to a buffer where the number of characters for each glyph are copied.
+ * @param[in] glyphIndex Index to the first glyph.
+ * @param[in] numberOfGlyphs The number of glyphs.
+ */
+ void GetCharactersPerGlyphMap( Length* charactersPerGlyph,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+
+ /**
+ * Retrieves the whole or part of the glyph to character conversion map.
+ *
+ * The size of the buffer needs to be big enough to copy the @p numberOfGlyphs.
+ *
+ * @param[out] glyphToCharacter Pointer to a buffer where the conversion map is copied.
+ * @param[in] glyphIndex Index to the first glyph.
+ * @param[in] numberOfGlyphs The number of glyphs.
+ */
+ void GetGlyphToCharacterMap( CharacterIndex* glyphToCharacter,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+
+ // Position interface
+
+ /**
+ * @brief Replaces any glyph positions previously set.
+ *
+ * @param[in] glyphPositions An array of visual positions for each glyph.
+ * @param[in] numberOfGlyphs The number of positions.
+ */
+ void SetGlyphPositions( const Vector2* glyphPositions,
+ Length numberOfGlyphs );
+
+ /**
+ * @brief Retrieves the glyph positions.
+ *
+ * @pre The size of the @p positions buffer needs to be big enough to copy the @p numberOfGlyphs positions.
+ * @param[out] glyphPositions Pointer to a buffer where the glyph positions are copied.
+ * @param[in] glyphIndex Index to the first glyph position.
+ * @param[in] numberOfGlyphs The number of positions to be copied.
+ */
+ void GetGlyphPositions( Vector2* glyphPositions,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+
+ /**
+ * Retrieve the glyph's position of the given glyph.
+ *
+ * @param[in] glyphIndex Index to the glyph.
+ *
+ * @return The glyph's position.
+ */
+ const Vector2& GetGlyphPosition( GlyphIndex glyphIndex ) const;
+
+ // Line interface.
+
+ /**
+ * Sets the lines.
+ *
+ * Replaces any lines previously set.
+ *
+ * Every line is an item run containing the index to the first glyph of the line and the number of glyphs.
+ *
+ * @param[in] lines Pointer to a buffer containing all the line runs.
+ * @param[in] numberOfLines The number of lines in the buffer.
+ */
+ void SetLines( const LineRun* const lines,
+ Length numberOfLines );
+
+ /**
+ * Retrieves the number of lines of the whole text.
+ *
+ * @return The number of lines.
+ */
+ Length GetNumberOfLines() const;
+
+ /**
+ * Retrieves lines.
+ *
+ * The size of the @p lines buffer needs to be big enough to copy the @p numberOfLines.
+ *
+ * @param[out] lines Pointer to a buffer where the lines are copied.
+ * @param[in] lineIndex Index to the first line.
+ * @param[in] numberOfLines Number of lines to be copied.
+ */
+ void GetLines( LineRun* lines,
+ LineIndex lineIndex,
+ Length numberOfLines ) const;
+
+ /**
+ * Retrieves the number of lines where the given range of glyphs is laid out.
+ *
+ * @param[in] glyphIndex Index to the first glyph.
+ * @param[in] numberOfGlyphs The number of glyph.
+ *
+ * @return The number of lines.
+ */
+ TextAbstraction::Length GetNumberOfLines( GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+ /**
+ * Retrieves the lines where the given range of glyphs is laid out.
+ *
+ * The size of the @p lines buffer needs to be big enough to copy the @p numberOfLines.
+ *
+ * @param[out] lines Pointer to a buffer where the lines are copied.
+ * @param[in] glyphIndex Index to the first glyphs of the range.
+ * @param[in] numberOfGlyphs Number of glyphs in the range.
+ */
+ void GetLinesOfGlyphRange( LineRun* lines,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+
+ // Size interface
+
+ /**
+ * Sets the natural size.
+ *
+ * @param[in] size The text's natural size.
+ */
+ void SetNaturalSize( const Vector2& size );
+
+ /**
+ * Retrieves the natural size.
+ *
+ * @return The text's natural size.
+ */
+ const Vector2& GetNaturalSize() const;
+
+ /**
+ * Sets the text's actual size after it has been laid out.
+ *
+ * @param[in] size The text's size.
+ */
+ void SetActualSize( const Vector2& size );
+
+ /**
+ * Retrieves the text's actual size after it has been laid out.
+ *
+ * @return The text's size.
+ */
+ const Vector2& GetActualSize() const;
+
+protected:
+
+ /**
+ * @brief A reference counted object may only be deleted by calling Unreference().
+ */
+ virtual ~VisualModel();
+
+private:
+
+ /**
+ * @brief Private constructor.
+ */
+ VisualModel();
+
+ // Undefined
+ VisualModel( const VisualModel& handle );
+
+ // Undefined
+ VisualModel& operator=( const VisualModel& handle );
+
+private:
+
+ struct Impl;
+ Impl* mImpl;
+};
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_VISUAL_MODEL_H__
BuildRequires: boost-devel
BuildRequires: pkgconfig(dali)
BuildRequires: pkgconfig(dali-core)
-BuildRequires: fribidi-devel
%description
The OpenGLES Canvas Core Library Toolkit - a set of controls that provide