gbs build -A [TARGET_ARCH] --define "%enable_dali_smack_rules 1"
+1.3. MOBILE Profile
+-------------------
+ gbs build -A [TARGET_ARCH] --spec dali-toolkit-mobile.spec
2. Building for Ubuntu desktop
==============================
# 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
)
# Append list of test harness files (Won't get parsed for test cases)
// Button::PROPERTY_LABEL_ACTOR
{
button.SetLabel( "LABEL_TEXT_CUSTOM" );
- DALI_TEST_EQUALS( "TextView", button.GetProperty( Button::Property::LABEL_ACTOR ).GetValue( "type" ).Get< std::string >(), TEST_LOCATION );
+ DALI_TEST_EQUALS( "TextLabel", button.GetProperty( Button::Property::LABEL_ACTOR ).GetValue( "type" ).Get< std::string >(), TEST_LOCATION );
Property::Map map;
map[ "type" ] = "Actor";
+++ /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;
-}
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
{
}
-void ConstraintAppliedCheck::operator()( ActiveConstraint& constraint )
+void ConstraintAppliedCheck::operator()( Constraint& constraint )
{
mSignalReceived = true;
}
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
struct ConstraintAppliedCheck
{
ConstraintAppliedCheck( bool& signalReceived );
- void operator()( ActiveConstraint& constraint );
+ void operator()( Constraint& constraint );
void Reset();
void CheckSignalReceived();
void CheckSignalNotReceived();
void DummyControlImplOverride::OnInitialize() { initializeCalled = true; }
-void DummyControlImplOverride::OnThemeChange(StyleManager change) { themeChangeCalled = true;}
-void DummyControlImplOverride::OnFontChange(bool defaultFontChange, bool defaultFontSizeChange) { fontChangeCalled = true; }
+void DummyControlImplOverride::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange change ) { themeChangeCalled = change.themeChange; fontChangeCalled = change.defaultFontSizeChange; }
void DummyControlImplOverride::OnPinch(const PinchGesture& pinch) { pinchCalled = true; }
void DummyControlImplOverride::OnPan(const PanGesture& pan) { panCalled = true; }
void DummyControlImplOverride::OnTap(const TapGesture& tap) { tapCalled = true; }
private: // From Internal::Control
virtual void OnInitialize();
- virtual void OnThemeChange( StyleManager styleManager );
- virtual void OnFontChange(bool defaultFontChange, bool defaultFontSizeChange);
+ virtual void OnStyleChange( Toolkit::StyleManager styleManager, StyleChange change );
virtual void OnPinch(const PinchGesture& pinch);
virtual void OnPan(const PanGesture& pan);
virtual void OnTap(const TapGesture& tap);
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()
+ * @copydoc PlatformAbstraction::GetDefaultFontDescription()
*/
-const std::string& TestPlatformAbstraction::GetDefaultFontFamily() const
+void TestPlatformAbstraction::GetDefaultFontDescription( std::string& family, std::string& style ) const
{
- mTrace.PushCall("GetDefaultFontFamily", "");
- return mGetDefaultFontFamilyResult;
+ // TODO
}
/**
* @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
+int TestPlatformAbstraction::GetDefaultFontSize() 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
+ // TODO
+ return int();
}
/**
}
/**
- * @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()
+ * @copydoc PlatformAbstraction::GetDefaultFontDescription()
*/
- virtual const std::string& GetDefaultFontFamily() const;
+ virtual void GetDefaultFontDescription( std::string& family, std::string& style ) 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;
+ virtual int GetDefaultFontSize() 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':'orientation', \
- '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 );
+ Toolkit::NaviTitleBarStyle titleBarStyle( background, 720, 111, 68, 48, 34, 16, 11, 45, 63, 26, 14, 22 );
naviControl.CreateNavigationTitleBar( titleBarStyle, titleBarStyle );
Page naviItem = Page::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;
}
// 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");
+ popup.SetTitle("title");
- // 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);
+ DALI_TEST_CHECK( popup.GetTitle() == "title" );
- 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) );
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 );
+ TextLabel label = TextLabel::DownCast( pushButton.GetLabel() );
+ DALI_TEST_CHECK( STR == label.GetProperty<std::string>( TextLabel::Property::TEXT ) );
- textView = TextView::DownCast( pushButton.GetLabel() );
- DALI_TEST_CHECK( STR == textView.GetText() );
END_TEST;
}
{
ToolkitTestApplication application;
- TextView actor1 = TextView::New( "test actor 1" );
+ TextLabel actor1 = TextLabel::New( "test actor 1" );
RadioButton radioButton = RadioButton::New( actor1 );
DALI_TEST_CHECK( actor1 == radioButton.GetLabel() );
- TextView actor2 = TextView::New( "test actor 2" );
+ TextLabel actor2 = TextLabel::New( "test actor 2" );
radioButton.SetLabel( actor2 );
DALI_TEST_CHECK( actor2 == radioButton.GetLabel() );
/**
* @param[in] current The current base value
- * @param[in] property The property to be added to current.
+ * @param[in] inputs Contains the property to be added to current.
* @return The new current Vector.
*/
- Vector3 operator()(const Vector3& current)
+ void operator()( Vector3& current, const PropertyInputContainer& inputs )
{
- gConstraintResult = current + mOffset;
- return gConstraintResult;
- }
-
- /**
- * @param[in] current The current base value
- * @param[in] property The property to be added to current.
- * @return The new current Vector.
- */
- Vector3 operator()(const Vector3& current,
- const PropertyInput& property)
- {
- gConstraintResult = current + property.GetVector3() + mOffset;
- return gConstraintResult;
+ gConstraintResult = current + inputs[0]->GetVector3() + mOffset;
+ current = gConstraintResult;
}
Vector3 mOffset;
a.SetPosition( TEST_ACTOR_POSITION );
Wait(application);
- Constraint constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- Source(scrollView, ScrollView::Property::SCROLL_POSITION),
- TestSumConstraint( TEST_CONSTRAINT_OFFSET ) );
+ Constraint constraint = Constraint::New<Vector3>( scrollView, Actor::Property::POSITION, TestSumConstraint( TEST_CONSTRAINT_OFFSET ) );
+ constraint.AddSource( Source(scrollView, ScrollView::Property::SCROLL_POSITION) );
constraint.SetRemoveAction(Constraint::Discard);
scrollView.ApplyConstraintToChildren(constraint);
Wait(application);
Wait(application);
// apply this constraint to scrollview
- Constraint constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- Source(scrollView, ScrollView::Property::SCROLL_POSITION),
- TestSumConstraint( TEST_CONSTRAINT_OFFSET ) );
-
+ Constraint constraint = Constraint::New<Vector3>( scrollView, Actor::Property::POSITION, TestSumConstraint( TEST_CONSTRAINT_OFFSET ) );
+ constraint.AddSource( Source(scrollView, ScrollView::Property::SCROLL_POSITION) );
constraint.SetRemoveAction(Constraint::Discard);
scrollView.ApplyConstraintToChildren(constraint);
ScrollView SetupTestScrollView(int rows, int columns, Vector2 size)
{
+ Constraint constraint;
+
ScrollView scrollView = ScrollView::New();
scrollView.SetSize(size);
scrollView.SetAnchorPoint(AnchorPoint::CENTER);
scrollView.SetParentOrigin(ParentOrigin::CENTER);
- scrollView.ApplyConstraint( Constraint::New<Dali::Vector3>( Dali::Actor::Property::SIZE, Dali::ParentSource( Dali::Actor::Property::SIZE ), Dali::EqualToConstraint() ) );
+
+ constraint = Constraint::New<Dali::Vector3>( scrollView, Dali::Actor::Property::SIZE, Dali::EqualToConstraint() );
+ constraint.AddSource( Dali::ParentSource( Dali::Actor::Property::SIZE ) );
+ constraint.Apply();
+
scrollView.SetWrapMode(false);
scrollView.ScrollStartedSignal().Connect( &OnScrollStart );
scrollView.ScrollUpdatedSignal().Connect( &OnScrollUpdate );
container.SetAnchorPoint(AnchorPoint::CENTER);
container.SetSize( size );
scrollView.Add( container );
- container.ApplyConstraint( Constraint::New<Vector3>( Actor::Property::SIZE, ParentSource( Actor::Property::SIZE ), EqualToConstraint() ) );
+
+ constraint = Constraint::New<Vector3>( container, Actor::Property::SIZE, EqualToConstraint() );
+ constraint.AddSource( Dali::ParentSource( Dali::Actor::Property::SIZE ) );
+ constraint.Apply();
gPages.clear();
for(int row = 0;row<rows;row++)
for(int column = 0;column<columns;column++)
{
Actor page = Actor::New();
- page.ApplyConstraint( Constraint::New<Vector3>( Actor::Property::SIZE, ParentSource( Actor::Property::SIZE ), EqualToConstraint() ) );
+
+ constraint = Constraint::New<Vector3>( page, Actor::Property::SIZE, EqualToConstraint() );
+ constraint.AddSource( Dali::ParentSource( Dali::Actor::Property::SIZE ) );
+ constraint.Apply();
page.SetParentOrigin( ParentOrigin::CENTER );
page.SetAnchorPoint( AnchorPoint::CENTER );
page.SetPosition( column * size.x, row * size.y );
{
Actor page = *pageIter;
page.RemoveConstraints();
- page.ApplyConstraint( Constraint::New<Vector3>( Actor::Property::SIZE, ParentSource( Actor::Property::SIZE ), EqualToConstraint() ) );
+
+ Constraint constraint = Constraint::New<Vector3>( page, Actor::Property::SIZE, EqualToConstraint() );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.Apply();
effect.ApplyToPage(page, Vector2(Math::PI_2, 0.0f));
}
Wait(application);
{
Actor page = *pageIter;
page.RemoveConstraints();
- page.ApplyConstraint( Constraint::New<Vector3>( Actor::Property::SIZE, ParentSource( Actor::Property::SIZE ), EqualToConstraint() ) );
+ Constraint constraint = Constraint::New<Vector3>( page, Actor::Property::SIZE, EqualToConstraint() );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.Apply();
effect.ApplyToPage(page, Vector2(Math::PI_2, 0.0f));
}
Wait(application);
{
Actor page = *pageIter;
page.RemoveConstraints();
- page.ApplyConstraint( Constraint::New<Vector3>( Actor::Property::SIZE, ParentSource( Actor::Property::SIZE ), EqualToConstraint() ) );
+ Constraint constraint = Constraint::New<Vector3>( page, Actor::Property::SIZE, EqualToConstraint() );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.Apply();
effect.ApplyToPage(page);
}
Wait(application);
/**
* function operator to apply the parent size
*/
- Dali::Vector3 operator()(const Dali::Vector3& current)
+ void operator()( Dali::Vector3& current, const PropertyInputContainer& /* inputs */ )
{
- return Dali::Vector3( 100.0f, 100.0f, 100.0f );
+ current.x = current.y = current.z = 100.0f;
}
};
// Create a 10x10 table-view
TableView tableView = TableView::New(10,10);
- tableView.ApplyConstraint( Constraint::New<Vector3>( Actor::Property::SIZE, Constraint100() ) );
+ Constraint constraint = Constraint::New<Vector3>( tableView, Actor::Property::SIZE, Constraint100() );
+ constraint.Apply();
DALI_TEST_CHECK( tableView );
// Create a child actor with the custom properties
PKG_CHECK_MODULES(DALICORE, dali-core)
PKG_CHECK_MODULES(DALI, dali)
-PKG_CHECK_MODULES(FRIBIDI, fribidi)
DALI_TOOLKIT_CFLAGS=-DPLATFORM_TIZEN
dataReadOnlyDir=${prefix}/share/dali/
fi
+DALI_TOOLKIT_CFLAGS="$DALI_TOOLKIT_CFLAGS -DDALI_PROFILE_${enable_profile}"
+AM_CONDITIONAL([COMMON_PROFILE], [test x$enable_profile = xCOMMON])
+AM_CONDITIONAL([MOBILE_PROFILE], [test x$enable_profile = xMOBILE])
+
# v8 version 4+ requires c++11
PKG_CHECK_MODULES(V8, v8 = 3.32.7, [ pkg_check_v8=yes ], [ pkg_check_v8=no ] )
toolkit_images_dir = ../../../dali-toolkit/images
toolkit_sounds_dir = ../../../dali-toolkit/sounds
-toolkit_styles_dir = ../../../dali-toolkit/styles
toolkit_src_dir = ../../../dali-toolkit/internal
public_api_src_dir = ../../../dali-toolkit/public-api
+if MOBILE_PROFILE
+toolkit_styles_dir = ../../../dali-toolkit/styles/mobile
+else
+toolkit_styles_dir = ../../../dali-toolkit/styles
+endif
+
include ../../../dali-toolkit/images/file.list
include ../../../dali-toolkit/sounds/file.list
include ../../../dali-toolkit/styles/file.list
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
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
publicapitransitioneffectsdir = $(publicapidir)/transition-effects
publicapiscriptingdir = $(publicapidir)/scripting
+publicapirenderingbackenddir = $(publicapidir)/text
publicapi_HEADERS = $(public_api_header_files)
publicapicontrols_HEADERS = $(public_api_controls_header_files)
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)
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)
publicapitransitioneffects_HEADERS = $(public_api_transition_effects_header_files)
publicapiscripting_HEADERS = $(public_api_scripting_header_files)
+publicapirenderingbackend_HEADERS = $(public_api_rendering_backend_header_files)
$(DALI_CFLAGS) \
$(DLOG_CFLAGS) \
$(script_plugin_v8_includes) \
+ $(V8_CFLAGS) \
-Werror -Wall
libdali_script_plugin_v8_la_LIBADD = \
#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/text/rendering-backend.h>
+
#include <dali-toolkit/public-api/shader-effects/alpha-discard-effect.h>
#include <dali-toolkit/public-api/shader-effects/bendy-effect.h>
#include <dali-toolkit/public-api/shader-effects/blind-effect.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/styling/style-manager.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>
--- /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/atlas-manager/atlas-manager-impl.h>
+
+// EXTERNAL INCLUDE
+#include <iostream>
+#include <string.h>
+#include <dali/integration-api/debug.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+ const Vector2 DEFAULT_ATLAS_SIZE( 512.0f, 512.0f );
+ const Vector2 DEFAULT_BLOCK_SIZE( 32.0f, 32.0f );
+ const uint32_t SINGLE_PIXEL_PADDING( 1u );
+ const uint32_t DOUBLE_PIXEL_PADDING( SINGLE_PIXEL_PADDING << 1 );
+ const uint32_t FILLED_PIXEL( -1 );
+}
+
+AtlasManager::AtlasManager()
+: mNewAtlasSize( DEFAULT_ATLAS_SIZE ),
+ mNewBlockSize( DEFAULT_BLOCK_SIZE ),
+ mAddFailPolicy( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES ),
+ mFilledPixel( FILLED_PIXEL )
+{
+}
+
+AtlasManagerPtr AtlasManager::New()
+{
+ AtlasManagerPtr internal = new AtlasManager();
+ return internal;
+}
+
+AtlasManager::~AtlasManager()
+{
+ for ( uint32_t i = 0; i < mAtlasList.size(); ++i )
+ {
+ delete[] mAtlasList[ i ].mStripBuffer;
+ }
+}
+
+Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( SizeType width,
+ SizeType height,
+ SizeType blockWidth,
+ SizeType blockHeight,
+ Pixel::Format pixelformat )
+{
+ // Check to see if the atlas is large enough to hold a single block even ?
+ if ( blockWidth > width || blockHeight > height )
+ {
+ DALI_LOG_ERROR("Atlas %i x %i too small. Dimensions need to be at least %ix%i\n",
+ width, height, blockWidth, blockHeight );
+ return 0;
+ }
+
+ Dali::Atlas atlas = Dali::Atlas::New( width, height, pixelformat );
+ AtlasDescriptor atlasDescriptor;
+ atlasDescriptor.mAtlas = atlas;
+ atlasDescriptor.mWidth = width;
+ atlasDescriptor.mHeight = height;
+ atlasDescriptor.mBlockWidth = blockWidth;
+ atlasDescriptor.mBlockHeight = blockHeight;
+ atlasDescriptor.mPixelFormat = pixelformat;
+ std::stringstream materialLabel;
+ materialLabel << "Atlas Material - ";
+ materialLabel << mAtlasList.size();
+ atlasDescriptor.mMaterial = Material::New( materialLabel.str() );
+ atlasDescriptor.mMaterial.SetDiffuseTexture( atlas );
+ atlasDescriptor.mNextFreeBlock = 1u; // indicate next free block will be the first ( +1 )
+
+ // What size do we need for this atlas' strip buffer ( assume 32bit pixel format )?
+ uint32_t neededStripSize =( blockWidth > blockHeight - DOUBLE_PIXEL_PADDING ? blockWidth : blockHeight - DOUBLE_PIXEL_PADDING ) << 2;
+ atlasDescriptor.mStripBuffer = new PixelBuffer[ neededStripSize ];
+ memset( atlasDescriptor.mStripBuffer, 0, neededStripSize );
+
+ atlasDescriptor.mHorizontalStrip = BufferImage::New( atlasDescriptor.mStripBuffer,
+ blockWidth,
+ SINGLE_PIXEL_PADDING,
+ pixelformat );
+
+ atlasDescriptor.mVerticalStrip = BufferImage::New( atlasDescriptor.mStripBuffer,
+ SINGLE_PIXEL_PADDING,
+ blockHeight - DOUBLE_PIXEL_PADDING,
+ pixelformat );
+ atlasDescriptor.mFilledPixelImage = BufferImage::New( reinterpret_cast< PixelBuffer* >( &mFilledPixel ), 1, 1, pixelformat );
+ atlas.Upload( atlasDescriptor.mFilledPixelImage, 0, 0 );
+ mAtlasList.push_back( atlasDescriptor );
+ return mAtlasList.size();
+}
+
+void AtlasManager::SetAddPolicy( Toolkit::AtlasManager::AddFailPolicy policy )
+{
+ mAddFailPolicy = policy;
+}
+
+void AtlasManager::Add( const BufferImage& image,
+ Toolkit::AtlasManager::AtlasSlot& slot,
+ Toolkit::AtlasManager::AtlasId atlas )
+{
+ // See if there's a slot in an atlas that matches the requirements of this image
+ // A bitmap must be sliceable into a single atlas
+ Pixel::Format pixelFormat = image.GetPixelFormat();
+ SizeType width = image.GetWidth();
+ SizeType height = image.GetHeight();
+ SizeType blockArea = 0;
+ SizeType totalBlocks = 0;
+ SizeType foundAtlas = 0;
+ SizeType index = 0;
+ slot.mImageId = 0;
+
+ AtlasSlotDescriptor desc;
+
+ // If there is a preferred atlas then check for room in that first
+ if ( atlas-- )
+ {
+ foundAtlas = CheckAtlas( atlas, width, height, pixelFormat, blockArea, totalBlocks );
+ }
+
+ // Search current atlases to see if there is a good match
+
+ while( !foundAtlas && index < mAtlasList.size() )
+ {
+ foundAtlas = CheckAtlas( index, width, height, pixelFormat, blockArea, totalBlocks );
+ ++index;
+ }
+
+ // If we can't find a suitable atlas then check the policy to determine action
+ if ( !foundAtlas-- )
+ {
+ if ( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES == mAddFailPolicy )
+ {
+ SizeType newAtlas = CreateAtlas( mNewAtlasSize.x, mNewAtlasSize.y, mNewBlockSize.x, mNewBlockSize.y, pixelFormat );
+ if ( !newAtlas-- )
+ {
+ return;
+ }
+ else
+ {
+ foundAtlas = CheckAtlas( newAtlas, width, height, pixelFormat, blockArea, totalBlocks );
+ }
+ }
+
+ if ( Toolkit::AtlasManager::FAIL_ON_ADD_FAILS == mAddFailPolicy || !foundAtlas-- )
+ {
+ // Haven't found an atlas for this image!!!!!!
+ return;
+ }
+ }
+
+ // Work out where the blocks are we're going to use
+ for ( SizeType i = 0; i < blockArea; ++i )
+ {
+ // Is there currently a next free block available ?
+ if ( mAtlasList[ foundAtlas ].mNextFreeBlock )
+ {
+ // Yes, so use this for our next block
+ SizeType selectedBlock = mAtlasList[ foundAtlas ].mNextFreeBlock - 1u;
+ desc.mBlocksList.PushBack( selectedBlock );
+
+ // Any blocks going to be available after this one (adjust to store +1 )?
+ selectedBlock++;
+ selectedBlock++;
+ if ( selectedBlock > totalBlocks )
+ {
+ // No so start trying to use free blocks list
+ selectedBlock = 0;
+ }
+ mAtlasList[ foundAtlas ].mNextFreeBlock = selectedBlock;
+ }
+ else
+ {
+ // Our next block must be from the free list, fetch from the start of the list
+ desc.mBlocksList.PushBack( mAtlasList[ foundAtlas ].mFreeBlocksList[ 0 ] );
+ mAtlasList[ foundAtlas ].mFreeBlocksList.Remove( mAtlasList[ foundAtlas ].mFreeBlocksList.Begin() );
+ }
+ }
+
+ desc.mImageWidth = width;
+ desc.mImageHeight = height;
+ desc.mAtlasId = foundAtlas + 1u;
+ desc.mCount = 1u;
+
+ // See if there's a previously freed image ID that we can assign to this new image
+ uint32_t imageId = 0;
+ for ( uint32_t i = 0; i < mImageList.size(); ++i )
+ {
+ if ( !mImageList[ i ].mCount )
+ {
+ imageId = i + 1u;
+ break;
+ }
+ }
+ if ( !imageId )
+ {
+ mImageList.push_back( desc );
+ slot.mImageId = mImageList.size();
+ }
+ else
+ {
+ mImageList[ imageId - 1u ] = desc;
+ slot.mImageId = imageId;
+ }
+ slot.mAtlasId = foundAtlas + 1u;
+ UploadImage( image, desc );
+}
+
+AtlasManager::SizeType AtlasManager::CheckAtlas( SizeType atlas,
+ SizeType width,
+ SizeType height,
+ Pixel::Format pixelFormat,
+ SizeType& blockArea,
+ SizeType& totalBlocks )
+{
+ if ( pixelFormat == mAtlasList[ atlas ].mPixelFormat )
+ {
+ // Check to see if there are any unused blocks in this atlas to accomodate our image
+ SizeType blocksInX = mAtlasList[ atlas ].mWidth / mAtlasList[ atlas ].mBlockWidth;
+ SizeType blocksInY = mAtlasList[ atlas ].mHeight / mAtlasList[ atlas ].mBlockHeight;
+ totalBlocks = blocksInX * blocksInY;
+ SizeType blocksFree = mAtlasList[ atlas ].mNextFreeBlock ?
+ totalBlocks - mAtlasList[ atlas ].mNextFreeBlock + 1u :
+ mAtlasList[ atlas ].mFreeBlocksList.Size();
+
+ // Check to see if the image will fit in these blocks, if not we'll need to create a new atlas
+ if ( blocksFree
+ && width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mBlockWidth
+ && height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mBlockHeight )
+ {
+ blockArea = 1u;
+ return ( atlas + 1u );
+ }
+ }
+ return 0;
+}
+
+void AtlasManager::CreateMesh( SizeType atlas,
+ SizeType imageWidth,
+ SizeType imageHeight,
+ const Vector2& position,
+ SizeType widthInBlocks,
+ SizeType heightInBlocks,
+ Dali::MeshData& meshData,
+ AtlasSlotDescriptor& desc )
+{
+ Dali::MeshData::Vertex vertex;
+ Dali::MeshData::VertexContainer vertices;
+ Dali::MeshData::FaceIndices faces;
+ Dali::MeshData::FaceIndex faceIndex = 0;
+ meshData.SetHasNormals( false );
+ meshData.SetHasColor( true );
+ meshData.SetHasTextureCoords( true );
+
+ SizeType blockWidth = mAtlasList[ atlas ].mBlockWidth;
+ SizeType blockHeight = mAtlasList[ atlas ].mBlockHeight;
+
+ float vertexBlockWidth = static_cast< float >( blockWidth );
+ float vertexBlockHeight = static_cast< float >( blockHeight );
+
+ SizeType width = mAtlasList[ atlas ].mWidth;
+ SizeType height = mAtlasList[ atlas ].mHeight;
+
+ SizeType atlasWidthInBlocks = width / blockWidth;
+
+ // Get the normalized size of a texel in both directions
+ // TODO when texture resizing and passing texture size via uniforms is available,
+ // we will encode pixel positions into the vertex data rather than normalized
+ // meaning that geometry needn't be changed on an atlas resize
+ float texelX = 1.0f / static_cast< float >( width );
+ float texelY = 1.0f / static_cast< float >( height );
+
+ // Get the normalized size of a block in texels
+ float texelBlockWidth = texelX * vertexBlockWidth;
+ float texelBlockHeight = texelY * vertexBlockHeight;
+
+ // Get partial block space
+ float vertexEdgeWidth = static_cast< float >( imageWidth % blockWidth );
+ float vertexEdgeHeight = static_cast< float >( imageHeight % blockHeight );
+
+ // And in texels
+ float texelEdgeWidth = vertexEdgeWidth * texelX;
+ float texelEdgeHeight = vertexEdgeHeight * texelY;
+
+ // Block by block create the two triangles for the quad
+ SizeType blockIndex = 0;
+ float ndcWidth;
+ float ndcHeight;
+ float ndcVWidth;
+ float ndcVHeight;
+
+ Vector2 topLeft = position;
+
+ for ( SizeType y = 0; y < heightInBlocks; ++y )
+ {
+
+ float currentX = position.x;
+
+ if ( ( heightInBlocks - 1u ) == y && vertexEdgeHeight > 0.0f )
+ {
+ ndcHeight = texelEdgeHeight;
+ ndcVHeight = vertexEdgeHeight;
+ }
+ else
+ {
+ ndcHeight = texelBlockHeight;
+ ndcVHeight = vertexBlockHeight;
+ }
+
+ for ( SizeType x = 0; x < widthInBlocks; ++x )
+ {
+ SizeType block = desc.mBlocksList[ blockIndex++ ];
+
+ float fBlockX = texelBlockWidth * static_cast< float >( block % atlasWidthInBlocks );
+ float fBlockY = texelBlockHeight * static_cast< float >( block / atlasWidthInBlocks );
+
+ // Add on texture filtering compensation
+ fBlockX += texelX;
+ fBlockY += texelY;
+
+ if ( ( widthInBlocks - 1u ) == x && vertexEdgeWidth > 0.0f )
+ {
+ ndcWidth = texelEdgeWidth;
+ ndcVWidth = vertexEdgeWidth;
+ }
+ else
+ {
+ ndcWidth = texelBlockWidth;
+ ndcVWidth = vertexBlockWidth;
+ }
+
+ // Top left
+ vertex.x = topLeft.x;
+ vertex.y = topLeft.y;
+ vertex.z = 0.0f;
+ vertex.u = fBlockX;
+ vertex.v = fBlockY;
+
+ vertices.push_back( vertex );
+
+ // Top Right
+ vertex.x = topLeft.x + ndcVWidth;
+ vertex.y = topLeft.y;
+ vertex.z = 0.0f;
+ vertex.u = fBlockX + ndcWidth;
+ vertex.v = fBlockY;
+
+ vertices.push_back( vertex );
+
+ // Bottom Left
+ vertex.x = topLeft.x;
+ vertex.y = topLeft.y + ndcVHeight;
+ vertex.z = 0.0f;
+ vertex.u = fBlockX;
+ vertex.v = fBlockY + ndcHeight;
+
+ vertices.push_back( vertex );
+
+ // Bottom Right
+ topLeft.x += ndcVWidth;
+ vertex.x = topLeft.x;
+ vertex.y = topLeft.y + ndcVHeight;
+ vertex.z = 0.0f;
+ vertex.u = fBlockX + ndcWidth;
+ vertex.v = fBlockY + ndcHeight;
+
+ vertices.push_back( vertex );
+
+ // Six indices in counter clockwise winding
+ faces.push_back( faceIndex + 1u );
+ faces.push_back( faceIndex );
+ faces.push_back( faceIndex + 2u );
+ faces.push_back( faceIndex + 2u );
+ faces.push_back( faceIndex + 3u );
+ faces.push_back( faceIndex + 1u );
+ faceIndex += 4;
+ }
+
+ // Move down a row
+ topLeft.x = currentX;
+ topLeft.y += vertexBlockHeight;
+ }
+
+ // If there's only one block then skip this next vertex optimisation
+ if ( widthInBlocks * heightInBlocks > 1 )
+ {
+ Dali::MeshData::VertexContainer optimizedVertices;
+ OptimizeVertices( vertices, faces, optimizedVertices );
+ meshData.SetVertices( optimizedVertices );
+ }
+ else
+ {
+ meshData.SetVertices( vertices );
+ }
+
+ meshData.SetFaceIndices( faces );
+ meshData.SetMaterial( mAtlasList[ atlas ].mMaterial );
+}
+
+void AtlasManager::PrintMeshData( const MeshData& meshData )
+{
+ std::cout << "\nMesh Data for Image: VertexCount = " << meshData.GetVertexCount();
+ std::cout << ", Triangles = " << meshData.GetFaceCount() << std::endl;
+
+ Dali::MeshData::VertexContainer vertices = meshData.GetVertices();
+ Dali::MeshData::FaceIndices faces = meshData.GetFaces();
+
+ for ( SizeType v = 0; v < vertices.size(); ++v )
+ {
+ std::cout << " Vertex(" << v << ") x = " << vertices[v].x << ", ";
+ std::cout << "y = " << vertices[v].y << ", " << "z = " << vertices[v].z << ", ";
+ std::cout << "u = " << vertices[v].u << ", " << "v = " << vertices[v].v << std::endl;
+ }
+
+ std::cout << "\n Indices: ";
+ for ( SizeType i = 0; i < faces.size(); ++i )
+ {
+ std::cout << " " << faces[ i ];
+ }
+ std::cout << std::endl;
+}
+
+void AtlasManager::OptimizeVertices( const MeshData::VertexContainer& in,
+ MeshData::FaceIndices& faces,
+ MeshData::VertexContainer& out )
+{
+ unsigned short vertexIndex = 0;
+
+ // We could check to see if blocks are next to each other, but it's probably just as quick to compare verts
+ for ( SizeType i = 0; i < faces.size(); ++i )
+ {
+ // Fetch a vertex, has it already been assigned?
+ bool foundVertex = false;
+ Dali::MeshData::Vertex v = in[ faces [ i ] ];
+ for ( SizeType j = 0; j < vertexIndex; ++j )
+ {
+ if ( v.x == out[ j ].x && v.y == out[ j ].y && v.z == out[ j ].z &&
+ v.u == out[ j ].u && v.v == out[ j ].v && v.nX == out[ j ].nX &&
+ v.nY == out[ j ].nY && v.nZ == out[ j ].nZ )
+ {
+ // Yes, so store this down as the vertex to use
+ faces[ i ] = j;
+ foundVertex = true;
+ break;
+ }
+ }
+
+ // Did we find a vertex ?
+ if ( !foundVertex )
+ {
+ // Add a new vertex
+ faces[ i ] = vertexIndex++;
+ out.push_back( v );
+ }
+ }
+}
+
+void AtlasManager::StitchMesh( MeshData& first,
+ const MeshData& second,
+ bool optimize )
+{
+
+ // Would be much quicker to be able to get a non-const reference to these containers and update in situ
+ MeshData::VertexContainer v1 = first.GetVertices();
+ MeshData::VertexContainer v2 = second.GetVertices();
+ MeshData::FaceIndices f1 = first.GetFaces();
+ MeshData::FaceIndices f2 = second.GetFaces();
+
+ uint32_t vc1 = first.GetVertexCount();
+ uint32_t vc2 = second.GetVertexCount();
+
+ for ( uint32_t v = 0; v < vc2; ++v )
+ {
+ v1.push_back( v2[ v ] );
+ }
+
+ for ( uint32_t f = 0; f < f2.size(); ++f )
+ {
+ f1.push_back( f2[ f ] + vc1 );
+ }
+
+ if ( optimize )
+ {
+ MeshData::VertexContainer optimizedVertices;
+ OptimizeVertices( v1, f1, optimizedVertices );
+ first.SetVertices( optimizedVertices );
+ }
+ else
+ {
+ first.SetVertices( v1 );
+ }
+
+ first.SetFaceIndices( f1 );
+}
+
+void AtlasManager::StitchMesh( const MeshData& first,
+ const MeshData& second,
+ MeshData& out,
+ bool optimize )
+{
+ MeshData::VertexContainer v1 = first.GetVertices();
+ MeshData::VertexContainer v2 = second.GetVertices();
+ MeshData::FaceIndices f1 = first.GetFaces();
+ MeshData::FaceIndices f2 = second.GetFaces();
+
+ uint32_t vc1 = first.GetVertexCount();
+ uint32_t vc2 = second.GetVertexCount();
+
+ MeshData::VertexContainer vertices;
+
+ MeshData::FaceIndices faces;
+
+ MeshData::Vertex vertex;
+
+ for ( uint32_t v = 0; v < vc1; ++v )
+ {
+ vertices.push_back( v1[ v ] );
+ }
+
+ for ( uint32_t v = 0; v < vc2; ++v )
+ {
+ vertices.push_back( v2[ v ] );
+ }
+
+ for ( uint32_t f = 0; f < f1.size(); ++f )
+ {
+ faces.push_back( f1[ f ] );
+ }
+
+ for ( uint32_t f = 0; f < f2.size(); ++f )
+ {
+ faces.push_back( f2[ f ] + vc1 );
+ }
+
+ if ( optimize )
+ {
+ MeshData::VertexContainer optimizedVertices;
+ OptimizeVertices( vertices, faces, optimizedVertices );
+ out.SetVertices( optimizedVertices );
+ }
+ else
+ {
+ out.SetVertices( vertices );
+ }
+
+ out.SetMaterial( first.GetMaterial() );
+ out.SetFaceIndices( faces );
+}
+
+void AtlasManager::UploadImage( const BufferImage& image,
+ const AtlasSlotDescriptor& desc )
+{
+ // Get the atlas to upload the image to
+ SizeType atlas = desc.mAtlasId - 1u;
+
+ // Check to see that the pixel formats are compatible
+ if ( image.GetPixelFormat() != mAtlasList[ atlas ].mPixelFormat )
+ {
+ DALI_LOG_ERROR("Cannot upload an image with a different PixelFormat to the Atlas.\n");
+ return;
+ }
+
+ SizeType atlasBlockWidth = mAtlasList[ atlas ].mBlockWidth;
+ SizeType atlasBlockHeight = mAtlasList[ atlas ].mBlockHeight;
+ SizeType atlasWidthInBlocks = mAtlasList[ atlas ].mWidth / mAtlasList[ atlas ].mBlockWidth;
+
+ SizeType block = desc.mBlocksList[ 0 ];
+ SizeType blockX = block % atlasWidthInBlocks;
+ SizeType blockY = block / atlasWidthInBlocks;
+ SizeType blockOffsetX = blockX * atlasBlockWidth;
+ SizeType blockOffsetY = blockY * atlasBlockHeight;
+
+ SizeType width = image.GetWidth();
+ SizeType height = image.GetHeight();
+
+ // Blit image 1 pixel to the right and down into the block to compensate for texture filtering
+ if ( !mAtlasList[ atlas ].mAtlas.Upload( image,
+ blockOffsetX + SINGLE_PIXEL_PADDING,
+ blockOffsetY + SINGLE_PIXEL_PADDING ) )
+ {
+ DALI_LOG_ERROR("Uploading image to Atlas Failed!.\n");
+ }
+
+ // If this is the first block then we need to keep the first pixel free for underline texture
+ if ( block )
+ {
+
+ // Blit top strip
+ if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mHorizontalStrip,
+ blockOffsetX,
+ blockOffsetY ) )
+ {
+ DALI_LOG_ERROR("Uploading top strip to Atlas Failed!\n");
+ }
+
+ // Blit left strip
+ if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mVerticalStrip,
+ blockOffsetX,
+ blockOffsetY + SINGLE_PIXEL_PADDING ) )
+ {
+ DALI_LOG_ERROR("Uploading left strip to Atlas Failed!\n");
+ }
+ }
+
+ // Blit bottom strip
+ if ( blockOffsetY + height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mHeight )
+ {
+ if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mHorizontalStrip,
+ blockOffsetX,
+ blockOffsetY + height + SINGLE_PIXEL_PADDING ) )
+ {
+ DALI_LOG_ERROR("Uploading bottom strip to Atlas Failed!.\n");
+ }
+ }
+
+ // Blit right strip
+ if ( blockOffsetX + width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mWidth )
+ {
+ if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mVerticalStrip,
+ blockOffsetX + width + SINGLE_PIXEL_PADDING,
+ blockOffsetY + SINGLE_PIXEL_PADDING ) )
+ {
+ DALI_LOG_ERROR("Uploading right strip to Atlas Failed!.\n");
+ }
+ }
+}
+
+void AtlasManager::GenerateMeshData( ImageId id,
+ const Vector2& position,
+ MeshData& meshData )
+{
+ // Read the atlas Id to use for this image
+ SizeType imageId = id - 1u;
+ SizeType atlas = mImageList[ imageId ].mAtlasId - 1u;
+ SizeType width = mImageList[ imageId ].mImageWidth;
+ SizeType height = mImageList[ imageId ].mImageHeight;
+
+ SizeType widthInBlocks = width / mAtlasList[ atlas ].mBlockWidth;
+ if ( width % mAtlasList[ atlas ].mBlockWidth )
+ {
+ widthInBlocks++;
+ }
+ SizeType heightInBlocks = height / mAtlasList[ atlas ].mBlockHeight;
+ if ( height % mAtlasList[ atlas ].mBlockHeight )
+ {
+ heightInBlocks++;
+ }
+
+ CreateMesh( atlas, width, height, position, widthInBlocks, heightInBlocks, meshData, mImageList[ imageId ] );
+
+ // Mesh created so increase the reference count
+ mImageList[ imageId ].mCount++;
+}
+
+Dali::Atlas AtlasManager::GetAtlasContainer( AtlasId atlas ) const
+{
+ Dali::Atlas null;
+ if ( !atlas || atlas > mAtlasList.size( ) )
+ {
+
+ DALI_LOG_ERROR("Cannot get Atlas from AtlasID ( doesn't exist ).\n");
+ return null;
+ }
+ return mAtlasList[ atlas -1u ].mAtlas;
+}
+
+bool AtlasManager::Remove( ImageId id )
+{
+ // Decrements the reference count of this image, and removes the blocks if zero.
+ SizeType imageId = id - 1u;
+ bool removed = false;
+
+ if ( id > mImageList.size() )
+ {
+ DALI_LOG_ERROR("Atlas was asked to free an invalid imageID: %i\n", id );
+ return false;
+ }
+
+ // If we attempt to free an image that is already freed then do nothing, other than log
+ if ( !mImageList[ imageId ].mCount )
+ {
+ DALI_LOG_ERROR("Atlas was asked to free an imageID: %i, that has already been freed!\n", id );
+ return false;
+ }
+
+ if ( 1u == --mImageList[ imageId ].mCount )
+ {
+ // 'Remove the blocks' from this image and add to the atlas' freelist
+ removed = true;
+ mImageList[ imageId ].mCount = 0;
+ SizeType atlas = mImageList[ imageId ].mAtlasId - 1u;
+ for ( uint32_t i = 0; i < mImageList[ imageId ].mBlocksList.Size(); ++i )
+ {
+ mAtlasList[ atlas ].mFreeBlocksList.PushBack( mImageList[ imageId ].mBlocksList[ i ] );
+ }
+ }
+ return removed;
+}
+
+AtlasManager::AtlasId AtlasManager::GetAtlas( ImageId id ) const
+{
+ if ( id && id <= mImageList.size() )
+ {
+ return mImageList[ id - 1u ].mAtlasId;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void AtlasManager::SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize )
+{
+ mNewAtlasSize = size;
+ mNewBlockSize = blockSize;
+}
+
+Vector2 AtlasManager::GetBlockSize( AtlasId atlas )
+{
+ if ( atlas && atlas <= mAtlasList.size() )
+ {
+ return Vector2( static_cast< float >( mAtlasList[ atlas - 1u ].mBlockWidth ),
+ static_cast< float >( mAtlasList[ atlas - 1u ].mBlockHeight) );
+ }
+ else
+ {
+ return Vector2::ZERO;
+ }
+}
+
+Vector2 AtlasManager::GetAtlasSize( AtlasId atlas )
+{
+ if ( atlas && atlas <= mAtlasList.size() )
+ {
+ return Vector2( static_cast< float >( mAtlasList[ atlas - 1u ].mWidth ),
+ static_cast< float >( mAtlasList[ atlas - 1u ].mHeight ) );
+ }
+ else
+ {
+ return Vector2::ZERO;
+ }
+}
+
+AtlasManager::SizeType AtlasManager::GetFreeBlocks( AtlasId atlas ) const
+{
+ if ( atlas && atlas <= mAtlasList.size() )
+ {
+ uint32_t index = atlas - 1u;
+ uint32_t width = mAtlasList[ index ].mWidth;
+ uint32_t height = mAtlasList[ index ].mHeight;
+ uint32_t blockWidth = mAtlasList[ index ].mBlockWidth;
+ uint32_t blockHeight = mAtlasList[ index ].mBlockHeight;
+
+ SizeType widthInBlocks = width / blockWidth;
+ SizeType heightInBlocks = height / blockHeight;
+ uint32_t blockCount = widthInBlocks * heightInBlocks;
+
+ // Check free previously unallocated blocks and any free blocks
+ blockCount -= mAtlasList[ index ].mNextFreeBlock - mAtlasList[ index ].mFreeBlocksList.Size();
+ return blockCount;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+AtlasManager::SizeType AtlasManager::GetAtlasCount() const
+{
+ return mAtlasList.size();
+}
+
+Pixel::Format AtlasManager::GetPixelFormat( AtlasId atlas )
+{
+ if ( !atlas || atlas > mAtlasList.size( ) )
+ {
+
+ DALI_LOG_ERROR("Cannot get Atlas from AtlasID ( doesn't exist ).\n");
+ return Pixel::L8;
+ }
+ return mAtlasList[ atlas -1u ].mPixelFormat;
+}
+
+void AtlasManager::GetMetrics( Toolkit::AtlasManager::Metrics& metrics )
+{
+ Toolkit::AtlasManager::AtlasMetricsEntry entry;
+ uint32_t textureMemoryUsed = 0;
+ uint32_t atlasCount = mAtlasList.size();
+ metrics.mAtlasCount = atlasCount;
+ metrics.mAtlasMetrics.Resize(0);
+
+ for ( uint32_t i = 0; i < atlasCount; ++i )
+ {
+ SizeType width = mAtlasList[ i ].mWidth;
+ SizeType height = mAtlasList[ i ].mHeight;
+ SizeType blockWidth = mAtlasList[ i ].mBlockWidth;
+ SizeType blockHeight = mAtlasList[ i ].mBlockHeight;
+
+ entry.mWidth = width;
+ entry.mHeight = height;
+ entry.mBlockWidth = blockWidth;
+ entry.mBlockHeight = blockHeight;
+ entry.mTotalBlocks = ( width / blockWidth ) * ( height / blockHeight );
+ uint32_t reuseBlocks = mAtlasList[ i ].mFreeBlocksList.Size();
+ entry.mBlocksUsed = mAtlasList[ i ].mNextFreeBlock ? mAtlasList[ i ].mNextFreeBlock - reuseBlocks - 1u: entry.mTotalBlocks - reuseBlocks;
+ entry.mPixelFormat = GetPixelFormat( i + 1 );
+
+ metrics.mAtlasMetrics.PushBack( entry );
+
+ uint32_t size = width * height;
+ if ( entry.mPixelFormat == Pixel::BGRA8888 )
+ {
+ size <<= 2;
+ }
+
+ textureMemoryUsed += size;
+
+ }
+ metrics.mTextureMemoryUsed = textureMemoryUsed;
+}
+
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+
--- /dev/null
+#ifndef __DALI_TOOLKIT_ATLAS_MANAGER_IMPL_H__
+#define __DALI_TOOLKIT_ATLAS_MANAGER_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.
+ */
+
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/atlas-manager/atlas-manager.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+class AtlasManager;
+
+} // namespace Toolkit
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+typedef Dali::Vector< Toolkit::AtlasManager::AtlasSlot > slotContainer;
+
+class AtlasManager;
+typedef IntrusivePtr<AtlasManager> AtlasManagerPtr;
+
+class AtlasManager : public Dali::BaseObject
+{
+public:
+
+ typedef uint32_t SizeType;
+ typedef SizeType AtlasId;
+ typedef SizeType ImageId;
+
+ /**
+ * @brief Internal storage of atlas attributes and image upload results
+ */
+ struct AtlasDescriptor
+ {
+ Dali::Atlas mAtlas; // atlas image
+ SizeType mWidth; // width of atlas
+ SizeType mHeight; // height of atlas
+ SizeType mBlockWidth; // width of a block in atlas
+ SizeType mBlockHeight; // height of a block in atlas
+ Pixel::Format mPixelFormat; // pixel format used by atlas
+ BufferImage mHorizontalStrip; // Image used to pad upload
+ BufferImage mVerticalStrip; // Image used to pad upload
+ BufferImage mFilledPixelImage; // Image used by atlas for operations such as underline
+ PixelBuffer* mStripBuffer; // Blank image buffer used to pad upload
+ Material mMaterial; // material used for atlas texture
+ SizeType mNextFreeBlock; // next free block will be placed here ( actually +1 )
+ Dali::Vector< SizeType > mFreeBlocksList; // unless there are any previously freed blocks
+ };
+
+ struct AtlasSlotDescriptor
+ {
+ SizeType mCount; // Reference count for this slot
+ SizeType mImageWidth; // Width of image stored
+ SizeType mImageHeight; // Height of image stored
+ AtlasId mAtlasId; // Image is stored in this Atlas
+ Dali::Vector< SizeType > mBlocksList; // List of blocks within atlas used for image
+ };
+
+ AtlasManager();
+
+ /**
+ * Create a new AtlasManager
+ */
+ static AtlasManagerPtr New();
+
+ virtual ~AtlasManager();
+
+ /**
+ * @copydoc: Toolkit::AtlasManager::CreateAtlas
+ */
+ AtlasId CreateAtlas( SizeType width,
+ SizeType height,
+ SizeType blockWidth,
+ SizeType blockHeight,
+ Pixel::Format pixelformat );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::SetAddPolicy
+ */
+ void SetAddPolicy( Toolkit::AtlasManager::AddFailPolicy policy );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::Add
+ */
+ void Add( const BufferImage& image,
+ Toolkit::AtlasManager::AtlasSlot& slot,
+ Toolkit::AtlasManager::AtlasId atlas );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::GenerateMeshData
+ */
+ void GenerateMeshData( ImageId id,
+ const Vector2& position,
+ MeshData& mesh );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::StitchMesh
+ */
+ void StitchMesh( MeshData& first,
+ const MeshData& second,
+ bool optimize );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::StitchMesh
+ */
+ void StitchMesh( const MeshData& first,
+ const MeshData& second,
+ MeshData& out, bool optimize );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::Remove
+ */
+ bool Remove( ImageId id );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::GetAtlasContainer
+ */
+ Dali::Atlas GetAtlasContainer( AtlasId atlas ) const;
+
+ /**
+ * @copydoc Toolkit::AtlasManager::GetAtlas
+ */
+ AtlasId GetAtlas( ImageId id ) const;
+
+ /**
+ * @copydoc Toolkit::AtlasManager::SetNewAtlasSize
+ */
+ void SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::GetAtlasSize
+ */
+ Vector2 GetAtlasSize( AtlasId atlas );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::GetBlockSize
+ */
+ Vector2 GetBlockSize( AtlasId atlas );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::GetFreeBlocks
+ */
+ SizeType GetFreeBlocks( AtlasId atlas ) const;
+
+ /*
+ * @copydoc Toolkit::AtlasManager::GetAtlasCount
+ */
+ SizeType GetAtlasCount() const;
+
+ /**
+ * @copydoc Toolkit::AtlasManager::GetPixelFormat
+ */
+ Pixel::Format GetPixelFormat( AtlasId atlas );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::GetMetrics
+ */
+ void GetMetrics( Toolkit::AtlasManager::Metrics& metrics );
+
+private:
+
+ std::vector< AtlasDescriptor > mAtlasList; // List of atlases created
+ std::vector< AtlasSlotDescriptor > mImageList; // List of bitmaps store in atlases
+
+ SizeType CheckAtlas( SizeType atlas,
+ SizeType width,
+ SizeType height,
+ Pixel::Format pixelFormat,
+ SizeType& blockArea,
+ SizeType& totalBlocks );
+
+ void CreateMesh( SizeType atlas,
+ SizeType imageWidth,
+ SizeType imageHeight,
+ const Vector2& position,
+ SizeType widthInBlocks,
+ SizeType heightInBlocks,
+ Dali::MeshData& meshData,
+ AtlasSlotDescriptor& desc );
+
+ void OptimizeVertices( const MeshData::VertexContainer& in,
+ MeshData::FaceIndices& faces,
+ MeshData::VertexContainer& out );
+
+ void UploadImage( const BufferImage& image,
+ const AtlasSlotDescriptor& desc );
+
+ void PrintMeshData( const MeshData& meshData );
+
+ Vector2 mNewAtlasSize;
+ Vector2 mNewBlockSize;
+ Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy;
+ uint32_t mFilledPixel;
+};
+
+} // namespace Internal
+
+inline const Internal::AtlasManager& GetImplementation(const Toolkit::AtlasManager& manager)
+{
+ DALI_ASSERT_ALWAYS( manager && "AtlasManager handle is empty" );
+
+ const BaseObject& handle = manager.GetBaseObject();
+
+ return static_cast<const Internal::AtlasManager&>(handle);
+}
+
+inline Internal::AtlasManager& GetImplementation(Toolkit::AtlasManager& manager)
+{
+ DALI_ASSERT_ALWAYS( manager && "AtlasManager handle is empty" );
+
+ BaseObject& handle = manager.GetBaseObject();
+
+ return static_cast<Internal::AtlasManager&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+
+ #endif // __DALI_TOOLKIT_ATLAS_MANAGER_IMPL_H__
\ No newline at end of file
--- /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/atlas-manager/atlas-manager.h>
+
+ // INTERNAL INCLUDES
+#include <dali-toolkit/internal/atlas-manager/atlas-manager-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+AtlasManager::AtlasManager()
+{
+}
+
+AtlasManager::~AtlasManager()
+{
+}
+
+AtlasManager AtlasManager::New()
+{
+ Internal::AtlasManagerPtr internal = Internal::AtlasManager::New();
+ return AtlasManager(internal.Get());
+}
+
+AtlasManager::AtlasManager(Internal::AtlasManager *impl)
+ : BaseHandle(impl)
+{
+}
+
+AtlasManager::AtlasId AtlasManager::CreateAtlas( SizeType width,
+ SizeType height,
+ SizeType blockWidth,
+ SizeType blockHeight,
+ Pixel::Format pixelformat )
+{
+ return GetImplementation(*this).CreateAtlas( width, height, blockWidth, blockHeight, pixelformat );
+}
+
+void AtlasManager::SetAddPolicy( AddFailPolicy policy )
+{
+ GetImplementation(*this).SetAddPolicy( policy );
+}
+
+void AtlasManager::Add( const BufferImage& image,
+ AtlasManager::AtlasSlot& slot,
+ AtlasManager::AtlasId atlas )
+{
+ GetImplementation(*this).Add( image, slot, atlas );
+}
+
+bool AtlasManager::Remove( ImageId id )
+{
+ return GetImplementation(*this).Remove( id );
+}
+
+void AtlasManager::GenerateMeshData( ImageId id,
+ const Vector2& position,
+ MeshData& meshData)
+{
+ GetImplementation(*this).GenerateMeshData( id,
+ position,
+ meshData );
+}
+
+void AtlasManager::StitchMesh( MeshData& first,
+ const MeshData& second,
+ bool optimize )
+{
+ GetImplementation(*this).StitchMesh( first, second, optimize );
+}
+
+void AtlasManager::StitchMesh( const MeshData& first,
+ const MeshData& second,
+ MeshData& out,
+ bool optimize )
+{
+ GetImplementation(*this).StitchMesh( first, second, out, optimize );
+}
+
+Dali::Atlas AtlasManager::GetAtlasContainer( AtlasId atlas ) const
+{
+ return GetImplementation(*this).GetAtlasContainer( atlas );
+}
+
+AtlasManager::AtlasId AtlasManager::GetAtlas( ImageId id )
+{
+ return GetImplementation(*this).GetAtlas( id );
+}
+
+Vector2 AtlasManager::GetBlockSize( AtlasId atlas )
+{
+ return GetImplementation(*this).GetBlockSize( atlas );
+}
+
+Vector2 AtlasManager::GetAtlasSize( AtlasId atlas )
+{
+ return GetImplementation(*this).GetAtlasSize( atlas );
+}
+
+AtlasManager::SizeType AtlasManager::GetFreeBlocks( AtlasId atlas )
+{
+ return GetImplementation(*this).GetFreeBlocks( atlas );
+}
+
+void AtlasManager::SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize )
+{
+ GetImplementation(*this).SetNewAtlasSize( size, blockSize );
+}
+
+AtlasManager::SizeType AtlasManager::GetAtlasCount() const
+{
+ return GetImplementation(*this).GetAtlasCount();
+}
+
+Pixel::Format AtlasManager::GetPixelFormat( AtlasId atlas )
+{
+ return GetImplementation(*this).GetPixelFormat( atlas );
+}
+
+void AtlasManager::GetMetrics( Metrics& metrics )
+{
+ return GetImplementation(*this).GetMetrics( metrics );
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_ATLAS_MANAGER_H__
+#define __DALI_TOOLKIT_ATLAS_MANAGER_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 <stdint.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/geometry/mesh-data.h>
+#include <dali/public-api/images/atlas.h>
+#include <dali/public-api/images/buffer-image.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+
+class AtlasManager;
+
+} // namespace Internal
+
+/**
+ * AtlasManager
+ * ------------
+ *
+ * Creates and manages additions and removals of images from Texture Atlases
+ *
+ * The AtlasManager will match pixeltype and optimal block use to determine
+ * the appropriate atlas to upload an image to.
+ *
+ * A policy can be specified to determine the action the AtlasManager will carry
+ * out, should it not be able to add an image. This can return an error, or create
+ * a new atlas of pre-determined dimensions to accomodate the new image.
+ *
+ * Images are referenced by an ImageId once they have been successfully uploaded.
+ *
+ * Once an image has been successfully uploaded, Geometry can be generated by passing
+ * the ImageId to the GenerateMeshData method and geometry can be consolidated via
+ * the StitchMesh method.
+ *
+ * Images are reference counted once mesh data has been generated. An image is removed
+ * from the Atlas via the Remove( ImageId ) method. This unreferences the image and only
+ * physically removes it from the atlas once all references have been freed.
+ *
+ * If the AddPolicy is set to generate and error if an image can't be uploaded, then it
+ * is the applications responsibility to deal with the situation. An error will be indicated
+ * with an ImageId of 0.
+ *
+ * Examples using the AtlasManager
+ *
+ * Create or obtain the AtlasManager
+ * @code
+ *
+ * AtlasManager manager = AtlasManager::Get();
+ *
+ * @endcode
+ *
+ * Set the AtlasManager AddPolicy
+ *
+ * @code
+ *
+ * // Tell the atlas manager to create a new atlas, if it needs to
+ * manager.SetAddPolicy( FAIL_ON_ADD_CREATES );
+ *
+ * // Tell the atlas manager to return an error, if it can't add an image
+ * manager.SetAddPolicy( FAIL_ON_ADD_FAILS );
+ *
+ * @endcode
+ *
+ * Simple add and removal of BufferImage to and from an atlas
+ *
+ * @code
+ *
+ * // Structure returned by AtlasManager operations
+ * AtlasSlot slot;
+ *
+ * // Add image to an atlas ( will be created if none suitable exists )
+ * manager.Add( bitmapImage, slot );
+ *
+ * // slot.mImage returns the imageId for the bitmap, slot.mAtlas indicates the atlasId
+ * // that the image was added to. The imageId is used to communicate with the AtlasManager
+ * uint32_t imageId = slot.mImage;
+ * if ( !imageId )
+ * {
+ * // Addition has failed.....
+ * }
+ * ...
+ * ...
+ * // Done with image, so remove from atlas, if not being used elsewhere
+ * manager.Remove( imageId );
+ *
+ * @endcode
+ *
+ * Create a Specific Atlas for adding BufferImages to
+ *
+ * @code
+ *
+ * // Create an RGB888 atlas of 2048x2848, with a blocksize of 128x128
+ * uint32_t atlas = manager.CreateAtlas( 2048u, 2048u, 128u, 128u, Pixel::RGB888 );
+ *
+ * // Add an image to a preferred atlas ( note not specifying atlas may still result
+ * // in the bitmap being added to the atlas above )
+ * manager.Add( bitmapImage, slot, atlas );
+ *
+ * @endcode
+ *
+ * Create Geometry for a previously added image
+ *
+ * @code
+ *
+ * // Top left corner of geometry to be generated
+ * Vector2 position( 1.0f, 1.0f );
+ *
+ * // Geometry will end up here!
+ * MeshData meshData;
+ * manager.GenerateMeshData( imageId, position, meshData );
+ *
+ * @endcode
+ *
+ * Generating Geometry from multiple images in the same atlas
+ *
+ * @code
+ *
+ * MeshData firstMesh;
+ * MeshData secondMesh;
+ * manager.GenerateMeshData( imageid_1, position_1, firstMesh );
+ * manager.GenerateMeshData( imageid_2, position_2, secondMesh );
+ *
+ * // Combine the two meshes. Passing MESH_OPTIMIZE as an optional third parameter will remove duplicate vertices
+ * manager.StitchMesh( first, second );
+ *
+ * @endcode
+ *
+ */
+
+class AtlasManager : public BaseHandle
+{
+public:
+
+ typedef uint32_t SizeType;
+ typedef SizeType AtlasId;
+ typedef SizeType ImageId;
+ static const bool MESH_OPTIMIZE = true;
+
+ /**
+ * Metrics structures to describe Atlas Manager state
+ *
+ */
+ struct AtlasMetricsEntry
+ {
+ SizeType mWidth; // width of the atlas in pixels
+ SizeType mHeight;; // height of the atlas in pixels
+ SizeType mBlockWidth; // width of a block in pixels
+ SizeType mBlockHeight; // height of a block in pixels
+ SizeType mBlocksUsed; // number of blocks used in the atlas
+ SizeType mTotalBlocks; // total blocks used by atlas
+ Pixel::Format mPixelFormat; // pixel format of the atlas
+ };
+
+ struct Metrics
+ {
+ SizeType mAtlasCount; // number of atlases
+ SizeType mTextureMemoryUsed; // texture memory used by atlases
+ Dali::Vector< AtlasMetricsEntry > mAtlasMetrics; // container of atlas information
+ };
+
+ /**
+ * Create an AtlasManager handle; this can be initialised with AtlasManager::New()
+ * Calling member functions with an uninitialised handle is not allowed.
+ */
+ AtlasManager();
+
+ /**
+ * @brief Get new instance of AtlasManager object.
+ *
+ * @return A handle to the AtlasManager control.
+ */
+ static AtlasManager New();
+
+ /**
+ * @brief Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~AtlasManager();
+
+ /**
+ * Policy on failing to add an image
+ */
+ enum AddFailPolicy
+ {
+ FAIL_ON_ADD_FAILS,
+ FAIL_ON_ADD_CREATES
+ };
+
+ /**
+ * @brief Container to hold result of placing texture into atlas
+ */
+ struct AtlasSlot
+ {
+ ImageId mImageId; // Id of stored Image
+ AtlasId mAtlasId; // Id of Atlas containing this slot
+ };
+
+ typedef Dali::Vector< AtlasManager::AtlasSlot > slotContainer;
+
+ /**
+ * @brief Create a blank atlas of specific dimensions and pixel format with a certain block size
+ *
+ * @param[in] width desired atlas width in pixels
+ * @param[in] height desired atlas height in pixels
+ * @param[in] blockWidth block width to use in atlas in pixels
+ * @param[in] blockHeight block height to use in atlas in pixels
+ * @param[in] pixelformat format of a pixel in atlas
+ *
+ * @return atlas Id
+ */
+ AtlasId CreateAtlas( SizeType width,
+ SizeType height,
+ SizeType blockWidth,
+ SizeType blockHeight,
+ Pixel::Format pixelformat = Pixel::RGBA8888 );
+
+ /**
+ * @brief Set the policy on failure to add an image to an atlas
+ *
+ * @param policy policy to carry out if add fails
+ */
+ void SetAddPolicy( AddFailPolicy policy );
+
+ /**
+ * @brief Attempts to add an image to the most suitable atlas
+ *
+ * @details Add Policy may dictate that a new atlas is created if it can't presently be placed.
+ * If an add is made before an atlas is created under this policy,
+ * then a default size atlas will be created
+ *
+ * @param[in] image reference to a bitmapimage
+ * @param[out] slot result of add operation
+ * @param[in] atlas optional preferred atlas
+ */
+ void Add( const BufferImage& image,
+ AtlasSlot& slot,
+ AtlasId atlas = 0 );
+
+ /**
+ * @brief Remove previously added bitmapimage from atlas
+ *
+ * @param[in] id ImageId returned in the AtlasSlot from the add operation
+ *
+ * @return if true then image has been removed from the atlas
+ */
+ bool Remove( ImageId id );
+
+ /**
+ * @brief Generate mesh data for a previously added image
+ *
+ * @param[in] id Image Id returned in the AtlasSlot from the add operation
+ * @param[in] position position of the resulting mesh in model space
+ * @param[out] mesh Mesh Data Object to populate with mesh data
+ */
+ void GenerateMeshData( ImageId id,
+ const Vector2& position,
+ MeshData& mesh );
+
+ /**
+ * @brief Append second mesh to the first mesh
+ *
+ * @param[in] first First mesh
+ * @param[in] second Second mesh
+ * @param[in] optimize should we optimize vertex data
+ */
+ void StitchMesh( MeshData& first,
+ const MeshData& second,
+ bool optimize = false );
+
+ /**
+ * @brief Combine two meshes, outputting the result into a new mesh
+ *
+ * @param[in] first First mesh
+ * @param[in] second Second mesh
+ * @param[in] optimize should we optimize vertex data
+ * @param[out] out resulting mesh
+ */
+ void StitchMesh( const MeshData& first,
+ const MeshData& second,
+ MeshData& out,
+ bool optimize = false );
+
+ /**
+ * @brief Get the BufferImage containing an atlas
+ *
+ * @param[in] atlas AtlasId returned when atlas was created
+ *
+ * @return Atlas Handle
+ */
+ Dali::Atlas GetAtlasContainer( AtlasId atlas ) const;
+
+ /**
+ * @brief Get the Id of the atlas containing an image
+ *
+ * @param[in] id ImageId
+ *
+ * @return Atlas Id
+ */
+ AtlasId GetAtlas( ImageId id );
+
+ /**
+ * @brief Get the size of the blocks used in an atlas
+ *
+ * @param[in] atlas AtlasId
+ *
+ * @return width and height of the blocks used
+ */
+ Vector2 GetBlockSize( AtlasId atlas );
+
+ /**
+ * @brief Get the current size of an atlas
+ *
+ * @param[in] atlas AtlasId
+ *
+ * @return width and height of the atlas
+ */
+ Vector2 GetAtlasSize( AtlasId atlas );
+
+ /**
+ * @brief Get the number of blocks available in an atlas
+ *
+ * @param[in] atlas AtlasId
+ *
+ * @return Number of blocks free in this atlas
+ */
+ SizeType GetFreeBlocks( AtlasId atlas );
+
+ /**
+ * @brief Sets the pixel area of any new atlas and also the individual block size
+ *
+ * @param[in] size pixel area of atlas
+ *
+ * @param blockSize pixel area in atlas for a block
+ */
+ void SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize );
+
+ /**
+ * @brief Get the number of atlases created
+ *
+ * @return number of atlases
+ */
+ SizeType GetAtlasCount() const;
+
+ /**
+ * @brief Get the pixel format used by an atlas
+ *
+ * @param[in] atlas AtlasId
+ *
+ * @return Pixel format used by this atlas
+ */
+ Pixel::Format GetPixelFormat( AtlasId atlas );
+
+ /**
+ * @brief Fill in a metrics structure showing current status of this Atlas Manager
+ *
+ * @param[in] metrics metrics structure to be filled
+ */
+ void GetMetrics( Metrics& metrics );
+
+private:
+
+ explicit DALI_INTERNAL AtlasManager(Internal::AtlasManager *impl);
+
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_ATLAS_MANAGER_H__
\ No newline at end of file
if( actor )
{
- // TEMP: Assume all script created actors are not using size negotiation for now
- actor.SetRelayoutEnabled( false );
-
// add children of all the styles
if( OptionalChild actors = IsChild( node, KEYNAME_ACTORS ) )
{
// EXTERNAL INCLUDES
#include <sstream>
#include <iomanip>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/common/stage.h>
}
/**
- * EqualToConstraintFloat
- *
- * f(current, property) = property
- */
-struct EqualToConstraintFloat
-{
- EqualToConstraintFloat(){}
-
- float operator()(const float current, const PropertyInput& property) {return property.GetFloat();}
-};
-
-/**
* RecipOneMinusConstraint
*
* f(current, property) = property
{
RecipOneMinusConstraint(){}
- float operator()(const float current, const PropertyInput& property)
+ void operator()( float& current, const PropertyInputContainer& inputs )
{
- return 1.0f / (1.0f - property.GetFloat());
+ current = 1.0f / ( 1.0f - inputs[0]->GetFloat() );
}
};
// Register a property that the user can control to change the bloom threshold
mBloomThresholdPropertyIndex = self.RegisterProperty(BLOOM_THRESHOLD_PROPERTY_NAME, BLOOM_THRESHOLD_DEFAULT);
Property::Index shaderBloomThresholdPropertyIndex = mBloomExtractShader.GetPropertyIndex(BLOOM_THRESHOLD_PROPERTY_NAME);
- Constraint bloomThresholdConstraint = Constraint::New<float>(shaderBloomThresholdPropertyIndex, Source(self, mBloomThresholdPropertyIndex), EqualToConstraintFloat());
- mBloomExtractShader.ApplyConstraint(bloomThresholdConstraint);
+ Constraint bloomThresholdConstraint = Constraint::New<float>( mBloomExtractShader, shaderBloomThresholdPropertyIndex, EqualToConstraint());
+ bloomThresholdConstraint.AddSource( Source(self, mBloomThresholdPropertyIndex) );
+ bloomThresholdConstraint.Apply();
// precalc 1.0 / (1.0 - threshold) on CPU to save shader insns, using constraint to tie to the normal threshold property
Property::Index shaderRecipOneMinusBloomThresholdPropertyIndex = mBloomExtractShader.GetPropertyIndex(RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME);
- Constraint thresholdConstraint = Constraint::New<float>( shaderRecipOneMinusBloomThresholdPropertyIndex, LocalSource(shaderBloomThresholdPropertyIndex), RecipOneMinusConstraint());
- mBloomExtractShader.ApplyConstraint(thresholdConstraint);
+ Constraint thresholdConstraint = Constraint::New<float>( mBloomExtractShader, shaderRecipOneMinusBloomThresholdPropertyIndex, RecipOneMinusConstraint());
+ thresholdConstraint.AddSource( LocalSource(shaderBloomThresholdPropertyIndex) );
+ thresholdConstraint.Apply();
////////////////////////////////////////////
// Register a property that the user can control to fade the blur in / out via internal GaussianBlurView object
mBlurStrengthPropertyIndex = self.RegisterProperty(BLOOM_BLUR_STRENGTH_PROPERTY_NAME, BLOOM_BLUR_STRENGTH_DEFAULT);
- Constraint blurStrengthConstraint = Constraint::New<float>( mGaussianBlurView.GetBlurStrengthPropertyIndex(), Source(self, mBlurStrengthPropertyIndex), EqualToConstraintFloat());
- mGaussianBlurView.ApplyConstraint(blurStrengthConstraint);
+ Constraint blurStrengthConstraint = Constraint::New<float>( mGaussianBlurView, mGaussianBlurView.GetBlurStrengthPropertyIndex(), EqualToConstraint());
+ blurStrengthConstraint.AddSource( Source(self, mBlurStrengthPropertyIndex) );
+ blurStrengthConstraint.Apply();
////////////////////////////////////////////
mBloomIntensityPropertyIndex = self.RegisterProperty(BLOOM_INTENSITY_PROPERTY_NAME, BLOOM_INTENSITY_DEFAULT);
mCompositeShader.SetUniform( BLOOM_INTENSITY_PROPERTY_NAME, BLOOM_INTENSITY_DEFAULT );
Property::Index shaderBloomIntensityPropertyIndex = mCompositeShader.GetPropertyIndex(BLOOM_INTENSITY_PROPERTY_NAME);
- Constraint bloomIntensityConstraint = Constraint::New<float>( shaderBloomIntensityPropertyIndex, Source(self, mBloomIntensityPropertyIndex), EqualToConstraintFloat());
- mCompositeShader.ApplyConstraint(bloomIntensityConstraint);
+ Constraint bloomIntensityConstraint = Constraint::New<float>( mCompositeShader, shaderBloomIntensityPropertyIndex, EqualToConstraint());
+ bloomIntensityConstraint.AddSource( Source(self, mBloomIntensityPropertyIndex) );
+ bloomIntensityConstraint.Apply();
////////////////////////////////////////////
mBloomSaturationPropertyIndex = self.RegisterProperty(BLOOM_SATURATION_PROPERTY_NAME, BLOOM_SATURATION_DEFAULT);
mCompositeShader.SetUniform( BLOOM_SATURATION_PROPERTY_NAME, BLOOM_SATURATION_DEFAULT );
Property::Index shaderBloomSaturationPropertyIndex = mCompositeShader.GetPropertyIndex(BLOOM_SATURATION_PROPERTY_NAME);
- Constraint bloomSaturationConstraint = Constraint::New<float>( shaderBloomSaturationPropertyIndex, Source(self, mBloomSaturationPropertyIndex), EqualToConstraintFloat());
- mCompositeShader.ApplyConstraint(bloomSaturationConstraint);
+ Constraint bloomSaturationConstraint = Constraint::New<float>( mCompositeShader, shaderBloomSaturationPropertyIndex, EqualToConstraint());
+ bloomSaturationConstraint.AddSource( Source(self, mBloomSaturationPropertyIndex) );
+ bloomSaturationConstraint.Apply();
////////////////////////////////////////////
mImageIntensityPropertyIndex = self.RegisterProperty(IMAGE_INTENSITY_PROPERTY_NAME, IMAGE_INTENSITY_DEFAULT);
mCompositeShader.SetUniform( IMAGE_INTENSITY_PROPERTY_NAME, IMAGE_INTENSITY_DEFAULT );
Property::Index shaderImageIntensityPropertyIndex = mCompositeShader.GetPropertyIndex(IMAGE_INTENSITY_PROPERTY_NAME);
- Constraint imageIntensityConstraint = Constraint::New<float>( shaderImageIntensityPropertyIndex, Source(self, mImageIntensityPropertyIndex), EqualToConstraintFloat());
- mCompositeShader.ApplyConstraint(imageIntensityConstraint);
+ Constraint imageIntensityConstraint = Constraint::New<float>( mCompositeShader, shaderImageIntensityPropertyIndex, EqualToConstraint());
+ imageIntensityConstraint.AddSource( Source(self, mImageIntensityPropertyIndex) );
+ imageIntensityConstraint.Apply();
////////////////////////////////////////////
mImageSaturationPropertyIndex = self.RegisterProperty(IMAGE_SATURATION_PROPERTY_NAME, IMAGE_SATURATION_DEFAULT);
mCompositeShader.SetUniform( IMAGE_SATURATION_PROPERTY_NAME, IMAGE_SATURATION_DEFAULT );
Property::Index shaderImageSaturationPropertyIndex = mCompositeShader.GetPropertyIndex(IMAGE_SATURATION_PROPERTY_NAME);
- Constraint imageSaturationConstraint = Constraint::New<float>( shaderImageSaturationPropertyIndex, Source(self, mImageSaturationPropertyIndex), EqualToConstraintFloat());
- mCompositeShader.ApplyConstraint(imageSaturationConstraint);
+ Constraint imageSaturationConstraint = Constraint::New<float>( mCompositeShader, shaderImageSaturationPropertyIndex, EqualToConstraint());
+ imageSaturationConstraint.AddSource( Source(self, mImageSaturationPropertyIndex) );
+ imageSaturationConstraint.Apply();
}
} // namespace Internal
#include <dali/public-api/scripting/scripting.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
/**
* Button states and contents
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 );
+ Toolkit::TextLabel textLabel = Toolkit::TextLabel::New( label );
+ SetLabel( textLabel );
}
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/public-api/controls/text-controls/text-label.h>
namespace Dali
{
{
/**
- * Find the first image actor in the actor hierarchy
+ * Get size of Actor if larger than given size
+ * @param[in] root the actor to get the size of
+ * @param[out] size the greater of the given size or the size of the Actor
*/
-ImageActor FindImageActor( Actor root )
+void SizeOfActorIfLarger( Actor root, Vector3& size )
{
- ImageActor imageActor = ImageActor::DownCast( root );
- if( !imageActor && root )
+ if ( root )
{
- for( unsigned int i = 0, numChildren = root.GetChildCount(); i < numChildren; ++i )
- {
- ImageActor childImageActor = FindImageActor( root.GetChildAt( i ) );
- if( childImageActor )
- {
- return childImageActor;
- }
- }
+ // RelayoutSize retreived for Actor to use any padding set to it.
+ size.width = std::max( root.GetRelayoutSize( WIDTH ), size.width );
+ size.height = std::max( root.GetRelayoutSize( HEIGHT ), size.height );
}
-
- return imageActor;
}
} // unnamed namespace
{
Vector3 size;
- // If background and background not scale9 try get size from that
- ImageActor imageActor = FindImageActor( GetButtonImage() );
- if( imageActor && imageActor.GetStyle() != ImageActor::STYLE_NINE_PATCH )
- {
- size.width = imageActor.GetRelayoutSize( WIDTH );
- size.height = imageActor.GetRelayoutSize( HEIGHT );
- }
-
- ImageActor backgroundImageActor = FindImageActor( GetBackgroundImage() );
- if( backgroundImageActor && backgroundImageActor.GetStyle() != ImageActor::STYLE_NINE_PATCH )
- {
- size.width = std::max( size.width, backgroundImageActor.GetRelayoutSize( WIDTH ) );
- size.height = std::max( size.height, backgroundImageActor.GetRelayoutSize( HEIGHT ) );
- }
+ // Check Image and Background image and use the largest size as the control's Natural size.
+ SizeOfActorIfLarger( GetButtonImage(), size );
+ SizeOfActorIfLarger( GetBackgroundImage(), size );
// If label, test against it's size
- Toolkit::TextView textView = Toolkit::TextView::DownCast( GetLabel() );
- if( textView )
+ Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( GetLabel() );
+ if( label )
{
- Vector3 textViewSize = textView.GetNaturalSize();
+ Vector3 labelSize = label.GetNaturalSize();
- size.width = std::max( size.width, textViewSize.width + TEXT_PADDING * 2.0f );
- size.height = std::max( size.height, textViewSize.height + TEXT_PADDING * 2.0f );
+ size.width = std::max( size.width, labelSize.width + TEXT_PADDING * 2.0f );
+ size.height = std::max( size.height, labelSize.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 <dali-toolkit/public-api/controls/table-view/table-view.h>
#include "button-impl.h"
#include "effects-view-impl.h"
// EXTERNAL INCLUDES
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/common/stage.h>
mEffectStrengthPropertyIndex = self.RegisterProperty(EFFECT_STRENGTH_PROPERTY_NAME, EFFECT_STRENGTH_DEFAULT, Property::READ_WRITE);
mEffectOffsetPropertyIndex = self.RegisterProperty(EFFECT_OFFSET_PROPERTY_NAME, EFFECT_OFFSET_DEFAULT);
mEffectColorPropertyIndex = self.RegisterProperty(EFFECT_COLOR_PROPERTY_NAME, EFFECT_COLOR_DEFAULT);
- mActorPostFilter.ApplyConstraint( Constraint::New<Vector3>( Actor::Property::POSITION, Source( self, mEffectOffsetPropertyIndex ), EqualToConstraint() ) );
- mActorPostFilter.ApplyConstraint( Constraint::New<Vector4>( Actor::Property::COLOR, Source( self, mEffectColorPropertyIndex ), EqualToConstraint() ) );
+
+ Constraint positionConstraint = Constraint::New<Vector3>( mActorPostFilter, Actor::Property::POSITION, EqualToConstraint() );
+ positionConstraint.AddSource( Source( self, mEffectOffsetPropertyIndex ) );
+ positionConstraint.Apply();
+
+ Constraint colorConstraint = Constraint::New<Vector4>( mActorPostFilter, Actor::Property::COLOR, EqualToConstraint() );
+ colorConstraint.AddSource( Source( self, mEffectColorPropertyIndex ) );
+ colorConstraint.Apply();
}
void EffectsView::SetBackgroundColor( const Vector4& color )
// EXTERNAL INCLUDES
#include <sstream>
#include <iomanip>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/common/stage.h>
GaussianBlurView::GaussianBlurView( const unsigned int numSamples, const float blurBellCurveWidth, const Pixel::Format renderTargetPixelFormat,
const float downsampleWidthScale, const float downsampleHeightScale,
bool blurUserImage)
- : Control( CONTROL_BEHAVIOUR_NONE )
+ : Control( NO_SIZE_NEGOTIATION )
, mNumSamples(numSamples)
, mBlurBellCurveWidth( 0.001f )
, mPixelFormat(renderTargetPixelFormat)
// Private methods
//
-/**
- * EqualToConstraintFloat
- *
- * f(current, property) = property
- */
-struct EqualToConstraintFloat
-{
- EqualToConstraintFloat(){}
-
- float operator()(const float current, const PropertyInput& property) {return property.GetFloat();}
-};
-
void GaussianBlurView::OnInitialize()
{
// root actor to parent all user added actors, needed to allow us to set that subtree as exclusive for our child render task
// Create an ImageActor for performing a horizontal blur on the texture
mImageActorHorizBlur = ImageActor::New();
+ mImageActorHorizBlur.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
mImageActorHorizBlur.SetParentOrigin(ParentOrigin::CENTER);
mImageActorHorizBlur.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME
mImageActorHorizBlur.SetShaderEffect( mHorizBlurShader );
// Create an ImageActor for performing a vertical blur on the texture
mImageActorVertBlur = ImageActor::New();
+ mImageActorVertBlur.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
mImageActorVertBlur.SetParentOrigin(ParentOrigin::CENTER);
mImageActorVertBlur.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME
mImageActorVertBlur.SetShaderEffect( mVertBlurShader );
if(!mBlurUserImage)
{
mImageActorComposite = ImageActor::New();
+ mImageActorComposite.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
mImageActorComposite.SetParentOrigin(ParentOrigin::CENTER);
mImageActorComposite.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME
mImageActorComposite.SetOpacity(GAUSSIAN_BLUR_VIEW_DEFAULT_BLUR_STRENGTH); // ensure alpha is enabled for this object and set default value
- Constraint blurStrengthConstraint = Constraint::New<float>( Actor::Property::COLOR_ALPHA, ParentSource(mBlurStrengthPropertyIndex), EqualToConstraintFloat());
- mImageActorComposite.ApplyConstraint(blurStrengthConstraint);
+ Constraint blurStrengthConstraint = Constraint::New<float>( mImageActorComposite, Actor::Property::COLOR_ALPHA, EqualToConstraint());
+ blurStrengthConstraint.AddSource( ParentSource(mBlurStrengthPropertyIndex) );
+ blurStrengthConstraint.Apply();
// Create an ImageActor for holding final result, i.e. the blurred image. This will get rendered to screen later, via default / user render task
mTargetActor = ImageActor::New();
+ mTargetActor.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
mTargetActor.SetParentOrigin(ParentOrigin::CENTER);
mTargetActor.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME
// EXTERNAL INCLUDES
#include <sstream>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/common/stage.h>
" gl_FragColor = texture2D(sTexture, vTexCoord) * vec4(1,1,1,mask.a); \n"
"}";
-Vector2 EqualToConstraintVector2( const Vector2& current, const PropertyInput& property )
-{
- return property.GetVector2();
-}
-
Vector2 GetSizeForAspectRatio( const Vector2& targetSize, float aspectRatio )
{
Vector2 sizeToKeepAspectRatio( targetSize );
mRenderTask.SetInputEnabled( false );
mRenderTask.SetExclusive( true );
mRenderTask.SetClearEnabled( true );
- mRenderTask.ApplyConstraint( Constraint::New<Vector4>( RenderTask::Property::CLEAR_COLOR,
- Source( self, mCustomProperties[ Dali::Toolkit::MaskedImageView::BACKGROUND_COLOR ] ),
- EqualToConstraint() ) );
+
+ Constraint clearColorConstraint = Constraint::New<Vector4>( mRenderTask, RenderTask::Property::CLEAR_COLOR, EqualToConstraint() );
+ clearColorConstraint.AddSource( Source( self, mCustomProperties[ Dali::Toolkit::MaskedImageView::BACKGROUND_COLOR ] ) );
+ clearColorConstraint.Apply();
mRenderTask.FinishedSignal().Connect( this, &MaskedImageView::OnRenderTaskFinished );
// Edit mode initialization
ShaderEffect::GeometryHints( ShaderEffect::HINT_BLENDING ) );
shader.SetUniform( "uTargetSize", mTargetSize );
+
shader.SetUniform( "uSourceSize", mTargetSize );
- shader.ApplyConstraint( Constraint::New<Vector2>( shader.GetPropertyIndex( "uSourceSize" ),
- Source( self, mCustomProperties[ Dali::Toolkit::MaskedImageView::SOURCE_SIZE ] ),
- EqualToConstraintVector2 ) );
+ Constraint sourceSizeConstraint = Constraint::New<Vector2>( shader, shader.GetPropertyIndex( "uSourceSize" ), EqualToConstraint() );
+ sourceSizeConstraint.AddSource( Source( self, mCustomProperties[ Dali::Toolkit::MaskedImageView::SOURCE_SIZE ] ) );
+ sourceSizeConstraint.Apply();
+
shader.SetUniform( "uSourceOffset", Vector2::ZERO );
- shader.ApplyConstraint( Constraint::New<Vector2>( shader.GetPropertyIndex( "uSourceOffset" ),
- Source( self, mCustomProperties[ Dali::Toolkit::MaskedImageView::SOURCE_OFFSET ] ),
- EqualToConstraintVector2 ) );
+ Constraint sourceOffsetConstraint = Constraint::New<Vector2>( shader, shader.GetPropertyIndex( "uSourceOffset" ), EqualToConstraint() );
+ sourceOffsetConstraint.AddSource( Source( self, mCustomProperties[ Dali::Toolkit::MaskedImageView::SOURCE_OFFSET ] ) );
+ sourceOffsetConstraint.Apply();
+
shader.SetUniform( "uMaskSize", mTargetSize );
- shader.ApplyConstraint( Constraint::New<Vector2>( shader.GetPropertyIndex( "uMaskSize" ),
- Source( self, mCustomProperties[ Dali::Toolkit::MaskedImageView::MASK_SIZE ] ),
- EqualToConstraintVector2 ) );
+ Constraint maskSizeConstraint = Constraint::New<Vector2>( shader, shader.GetPropertyIndex( "uMaskSize" ), EqualToConstraint() );
+ maskSizeConstraint.AddSource( Source( self, mCustomProperties[ Dali::Toolkit::MaskedImageView::MASK_SIZE ] ) );
+ maskSizeConstraint.Apply();
+
shader.SetUniform( "uMaskOffset", mTargetSize );
- shader.ApplyConstraint( Constraint::New<Vector2>( shader.GetPropertyIndex( "uMaskOffset" ),
- Source( self, mCustomProperties[ Dali::Toolkit::MaskedImageView::MASK_OFFSET ] ),
- EqualToConstraintVector2 ) );
+ Constraint maskOffsetConstraint = Constraint::New<Vector2>( shader, shader.GetPropertyIndex( "uMaskOffset" ), EqualToConstraint() );
+ maskOffsetConstraint.AddSource( Source( self, mCustomProperties[ Dali::Toolkit::MaskedImageView::MASK_OFFSET ] ) );
+ maskOffsetConstraint.Apply();
shader.SetEffectImage( mMaskImage );
mSourceImageActor.SetShaderEffect( shader );
#include <dali-toolkit/internal/controls/magnifier/magnifier-impl.h>
// EXTERNAL INCLUDES
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/common/stage.h>
const float IMAGE_BORDER_INDENT = 14.0f; ///< Indent of border in pixels.
-/**
- * ImageBorderSizeConstraint
- */
-struct ImageBorderSizeConstraint
-{
- ImageBorderSizeConstraint()
- : mSizeOffset(Vector3(IMAGE_BORDER_INDENT - 1, IMAGE_BORDER_INDENT - 1, 0.0f) * 2.0f)
- {
- }
-
- Vector3 operator()(const Vector3& current,
- const PropertyInput& referenceSizeProperty)
- {
- const Vector3& referenceSize = referenceSizeProperty.GetVector3();
-
- return referenceSize + mSizeOffset;
- }
-
- Vector3 mSizeOffset; ///< The amount to offset the size from referenceSize
-};
-
struct CameraActorPositionConstraint
{
CameraActorPositionConstraint(const Vector2& stageSize, float defaultCameraDistance = 0.0f)
{
}
- Vector3 operator()(const Vector3& current,
- const PropertyInput& sourcePositionProperty)
+ void operator()( Vector3& current, const PropertyInputContainer& inputs )
{
- const Vector3& sourcePosition = sourcePositionProperty.GetVector3();
+ const Vector3& sourcePosition = inputs[0]->GetVector3();
- return Vector3( sourcePosition.x + mStageSize.x * 0.5f,
- sourcePosition.y + mStageSize.y * 0.5f,
- sourcePosition.z + mDefaultCameraDistance);
+ current.x = sourcePosition.x + mStageSize.x * 0.5f;
+ current.y = sourcePosition.y + mStageSize.y * 0.5f;
+ current.z = sourcePosition.z + mDefaultCameraDistance;
}
Vector2 mStageSize;
{
}
- Vector2 operator()(const Vector2& current,
- const PropertyInput& positionProperty,
- const PropertyInput& magnifierSizeProperty,
- const PropertyInput& magnifierScaleProperty)
+ void operator()( Vector2& current, const PropertyInputContainer& inputs )
{
- Vector2 position(positionProperty.GetVector3()); // World position?
-
- //position -= mStageSize * 0.5f;
+ current = inputs[0]->GetVector3(); // World position?
// should be updated when:
// Magnifier's world position/size/scale/parentorigin/anchorpoint changes.
// or Magnifier camera's world position changes.
- Vector3 size = magnifierSizeProperty.GetVector3() * magnifierScaleProperty.GetVector3();
+ Vector3 size = inputs[1]->GetVector3() * inputs[2]->GetVector3(); /* magnifier-size * magnifier-scale */
// Reposition, and resize viewport to reflect the world bounds of this Magnifier actor.
- position.x += (mStageSize.width - size.width) * 0.5f;
- position.y += (mStageSize.height - size.height) * 0.5f;
-
- return position;
+ current.x += ( mStageSize.width - size.width ) * 0.5f;
+ current.y += ( mStageSize.height - size.height ) * 0.5f;
}
Vector2 mStageSize;
{
}
- Vector2 operator()(const Vector2& current,
- const PropertyInput& magnifierSizeProperty,
- const PropertyInput& magnifierScaleProperty)
+ void operator()( Vector2& current, const PropertyInputContainer& inputs )
{
- return Vector2(magnifierSizeProperty.GetVector3() * magnifierScaleProperty.GetVector3());
+ current = inputs[0]->GetVector3() * inputs[1]->GetVector3(); /* magnifier-size * magnifier-scale */
}
};
mSourceActor = Actor::New();
Stage().GetCurrent().Add(mSourceActor);
mSourceActor.SetParentOrigin(ParentOrigin::CENTER);
- Constraint constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- Source( self, mPropertySourcePosition ),
- EqualToConstraint() );
- mSourceActor.ApplyConstraint(constraint);
+ Constraint constraint = Constraint::New<Vector3>( mSourceActor, Actor::Property::POSITION, EqualToConstraint() );
+ constraint.AddSource( Source( self, mPropertySourcePosition ) );
+ constraint.Apply();
// create the render task this will render content on top of everything
// based on camera source position.
// at the end of the update cycle i.e. after constraints have been applied.)
//Property::Index propertySourcePositionDelayed = mCameraActor.RegisterProperty("delayed-source-position", Vector3::ZERO);
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- Source( mSourceActor, Actor::Property::WORLD_POSITION ),
- CameraActorPositionConstraint(stageSize, mDefaultCameraDistance) );
- mCameraActor.ApplyConstraint(constraint);
+ constraint = Constraint::New<Vector3>( mCameraActor, Actor::Property::POSITION, CameraActorPositionConstraint(stageSize, mDefaultCameraDistance) );
+ constraint.AddSource( Source( mSourceActor, Actor::Property::WORLD_POSITION ) );
+ constraint.Apply();
// Apply constraint to render-task viewport position
- constraint = Constraint::New<Vector2>( RenderTask::Property::VIEWPORT_POSITION,
- Source( self, Actor::Property::WORLD_POSITION ),//mPropertySourcePosition ),
- Source( self, Actor::Property::SIZE ),
- Source( self, Actor::Property::WORLD_SCALE ),
- RenderTaskViewportPositionConstraint(stageSize) );
- mTask.ApplyConstraint(constraint);
+ constraint = Constraint::New<Vector2>( mTask, RenderTask::Property::VIEWPORT_POSITION, RenderTaskViewportPositionConstraint(stageSize) );
+ constraint.AddSource( Source( self, Actor::Property::WORLD_POSITION ) );
+ constraint.AddSource( Source( self, Actor::Property::SIZE ) );
+ constraint.AddSource( Source( self, Actor::Property::WORLD_SCALE ) );
+ constraint.Apply();
// Apply constraint to render-task viewport position
- constraint = Constraint::New<Vector2>( RenderTask::Property::VIEWPORT_SIZE,
- Source( self, Actor::Property::SIZE ),
- Source( self, Actor::Property::WORLD_SCALE ),
- RenderTaskViewportSizeConstraint() );
- mTask.ApplyConstraint(constraint);
+ constraint = Constraint::New<Vector2>( mTask, RenderTask::Property::VIEWPORT_SIZE, RenderTaskViewportSizeConstraint() );
+ constraint.AddSource( Source( self, Actor::Property::SIZE ) );
+ constraint.AddSource( Source( self, Actor::Property::WORLD_SCALE ) );
+ constraint.Apply();
}
Magnifier::~Magnifier()
mFrame.SetPositionInheritanceMode(DONT_INHERIT_POSITION);
mFrame.SetInheritScale(true);
- Constraint constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- ParentSource( Actor::Property::WORLD_POSITION ),
- EqualToConstraint() );
- mFrame.ApplyConstraint( constraint );
+ Constraint constraint = Constraint::New<Vector3>( mFrame, Actor::Property::POSITION, EqualToConstraint() );
+ constraint.AddSource( ParentSource( Actor::Property::WORLD_POSITION ) );
+ constraint.Apply();
mFrame.SetNinePatchBorder( Vector4::ONE * IMAGE_BORDER_INDENT );
self.Add(mFrame);
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);
+ mTitle = Toolkit::TextLabel::New();
+ mSubTitle = Toolkit::TextLabel::New();
}
void NavigationTitleBar::Update( Toolkit::Page page )
}
// add title and subtitle(if exist)
- mTitle.SetText( page.GetTitle() );
- mTitle.SetStyleToCurrentText(mCurrentStyle->titleTextStyle);
+ mTitle.SetProperty( Toolkit::TextLabel::Property::TEXT, page.GetTitle() );
if( page.GetSubTitle().empty() ) //display title
{
mTitleLayout.SetFixedHeight( 1,mCurrentStyle->titleHeightWithoutSubtitle - mCurrentStyle->subtitleHeight );
{
mTitleLayout.SetFixedHeight( 1, mCurrentStyle->titleHeightWithSubtitle );
mTitleLayout.AddChild( mTitle, Toolkit::TableView::CellPosition(1,0) );
- mSubTitle.SetText( page.GetSubTitle() );
- mSubTitle.SetStyleToCurrentText(mCurrentStyle->subtitleTextStyle);
+ mSubTitle.SetProperty( Toolkit::TextLabel::Property::TEXT, page.GetSubTitle() );
mTitleLayout.AddChild( mSubTitle, Toolkit::TableView::CellPosition(2,0) );
}
// 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/public-api/controls/text-controls/text-label.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;
+ Toolkit::TextLabel mTitle;
+ Toolkit::TextLabel mSubTitle;
};
// 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>
// EXTERNAL INCLUDES
#include <dali/public-api/animation/animation.h>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/events/hit-test-algorithm.h>
#include <dali/public-api/object/type-registry.h>
mDirection = offset / mDistance;
}
- Vector2 operator()(const Vector2& current, const PropertyInput& panDisplacement)
+ void operator()( Vector2& current, const PropertyInputContainer& inputs )
{
- float displacement = panDisplacement.GetFloat();
+ float displacement = inputs[0]->GetFloat();
if( displacement < mDistance )
{
- return mOldCenter + mDirection * displacement;
+ current = mOldCenter + mDirection * displacement;
}
else
{
- return mNewCenter + Vector2(0.25f*(displacement-mDistance), 0.f);
+ current = mNewCenter + Vector2(0.25f*(displacement-mDistance), 0.f);
}
}
mRotation = isTurnBack ? Quaternion( -Math::PI, Vector3::YAXIS ) : Quaternion( 0.f, Vector3::YAXIS );
}
- Quaternion operator()( const Quaternion& current, const PropertyInput& panDisplacement )
+ void operator()( Quaternion& current, const PropertyInputContainer& inputs )
{
- float displacement = panDisplacement.GetFloat();
- float angle;
+ float displacement = inputs[0]->GetFloat();
if( displacement < mDistance)
{
- return mRotation;
+ current = mRotation;
}
else
{
float coef = std::max(-1.0f, mStep*(mDistance-displacement));
- angle = Math::PI*( mConst + mSign*coef );
- return Quaternion( angle, Vector3::YAXIS );
+ float angle = Math::PI * ( mConst + mSign * coef );
+ current = Quaternion( angle, Vector3::YAXIS );
}
}
*/
struct CurrentCenterConstraint
{
- CurrentCenterConstraint( float pageWidth)
+ CurrentCenterConstraint( float pageWidth )
: mPageWidth( pageWidth )
{
mThres = pageWidth * PAGE_TURN_OVER_THRESHOLD_RATIO * 0.5f;
}
- Vector2 operator()( const Vector2& current, const PropertyInput& center, const PropertyInput& originalCenter )
+ void operator()( Vector2& current, const PropertyInputContainer& inputs )
{
- Vector2 centerPosition = center.GetVector2();
+ const Vector2& centerPosition = inputs[0]->GetVector2();
if( centerPosition.x > 0.f )
{
- return Vector2( mThres+centerPosition.x*0.5f , centerPosition.y);
+ current.x = mThres+centerPosition.x * 0.5f;
+ current.y = centerPosition.y;
}
else
{
- Vector2 centerOrigin = originalCenter.GetVector2();
+ const Vector2& centerOrigin = inputs[1]->GetVector2();
Vector2 direction = centerOrigin - Vector2(mThres, centerPosition.y);
float coef = 1.f+(centerPosition.x*2.f / mPageWidth);
// Todo: when coef <= 0, the page is flat, slow down the last moment of the page stretch by 10 times to avoid a small bounce
{
coef = (coef+0.225f)/10.0f;
}
- return centerOrigin - direction * coef;
+ current = centerOrigin - direction * coef;
}
}
: mThres( thres )
{}
- float operator()( const float current, const PropertyInput& currentCenter, const PropertyInput& originalCenter, const PropertyInput& panDisplacement)
+ void operator()( float& blurStrength, const PropertyInputContainer& inputs )
{
- float displacement = panDisplacement.GetFloat();
- float blurStrength;
+ float displacement = inputs[2]->GetFloat();
if( EqualsZero(displacement))
{
- Vector2 cur = currentCenter.GetVector2();
- Vector2 ori = originalCenter.GetVector2();
+ const Vector2& cur = inputs[0]->GetVector2();
+ const Vector2& ori = inputs[1]->GetVector2();
blurStrength = 5.f*(ori-cur).Length() / mThres;
}
else
}
blurStrength = blurStrength > 1.f ? 1.f : ( blurStrength < 0.f ? 0.f : blurStrength );
- return blurStrength;
}
float mThres;
mShadowView.RemoveConstraints();
Actor self = Self();
self.SetProperty( mPropertyPanDisplacement[mIndex], 0.f );
- Constraint shadowBlurStrengthConstraint = Constraint::New<float>( mShadowView.GetBlurStrengthPropertyIndex(),
- Source(mTurnEffect[mIndex], mTurnEffect[mIndex].GetPropertyIndex(mTurnEffect[mIndex].PageTurnEffect::GetCurrentCenterPropertyName())),
- Source(mTurnEffect[mIndex], mTurnEffect[mIndex].GetPropertyIndex(mTurnEffect[mIndex].PageTurnEffect::GetOriginalCenterPropertyName())),
- Source( self, mPropertyPanDisplacement[mIndex] ),
- ShadowBlurStrengthConstraint( mPageSize.width*PAGE_TURN_OVER_THRESHOLD_RATIO ) );
- mShadowView.ApplyConstraint( shadowBlurStrengthConstraint );
+
+ Constraint shadowBlurStrengthConstraint = Constraint::New<float>( mShadowView, mShadowView.GetBlurStrengthPropertyIndex(), ShadowBlurStrengthConstraint( mPageSize.width*PAGE_TURN_OVER_THRESHOLD_RATIO ) );
+ shadowBlurStrengthConstraint.AddSource( Source(mTurnEffect[mIndex], mTurnEffect[mIndex].GetPropertyIndex(mTurnEffect[mIndex].PageTurnEffect::GetCurrentCenterPropertyName())) );
+ shadowBlurStrengthConstraint.AddSource( Source(mTurnEffect[mIndex], mTurnEffect[mIndex].GetPropertyIndex(mTurnEffect[mIndex].PageTurnEffect::GetOriginalCenterPropertyName())) );
+ shadowBlurStrengthConstraint.AddSource( Source( self, mPropertyPanDisplacement[mIndex] ) );
+ shadowBlurStrengthConstraint.Apply();
}
}
else
/( offset.x*offset.x + offset.y*offset.y );
offset *= k;
Actor self = Self();
- Source source(self, mPropertyPanDisplacement[mIndex]);
Property::Index shaderOriginalCenterPropertyIndex = mTurnEffect[mIndex].GetPropertyIndex(mTurnEffect[mIndex].PageTurnEffect::GetOriginalCenterPropertyName());
- Constraint originalCenterConstraint = Constraint::New<Vector2>( shaderOriginalCenterPropertyIndex ,
- source,
- OriginalCenterConstraint( mOriginalCenter, offset ));
- mTurnEffect[mIndex].ApplyConstraint( originalCenterConstraint );
+ Constraint originalCenterConstraint = Constraint::New<Vector2>( mTurnEffect[mIndex], shaderOriginalCenterPropertyIndex, OriginalCenterConstraint( mOriginalCenter, offset ));
+ originalCenterConstraint.AddSource( Source( self, mPropertyPanDisplacement[mIndex] ) );
+ originalCenterConstraint.Apply();
Property::Index shaderCurrentCenterPropertyIndex = mTurnEffect[mIndex].GetPropertyIndex(mTurnEffect[mIndex].PageTurnEffect::GetCurrentCenterPropertyName());
- Constraint currentCenterConstraint = Constraint::New<Vector2>( shaderCurrentCenterPropertyIndex,
- Source(self, mPropertyCurrentCenter[mIndex]),
- Source(mTurnEffect[mIndex], shaderOriginalCenterPropertyIndex),
- CurrentCenterConstraint(mPageSize.width));
- mTurnEffect[mIndex].ApplyConstraint( currentCenterConstraint );
+ Constraint currentCenterConstraint = Constraint::New<Vector2>( mTurnEffect[mIndex], shaderCurrentCenterPropertyIndex, CurrentCenterConstraint(mPageSize.width));
+ currentCenterConstraint.AddSource( Source(self, mPropertyCurrentCenter[mIndex]) );
+ currentCenterConstraint.AddSource( Source(mTurnEffect[mIndex], shaderOriginalCenterPropertyIndex) );
+ currentCenterConstraint.Apply();
GetImpl( mTurnEffect[mIndex] ).ApplyInternalConstraint();
float distance = offset.Length();
- Constraint rotationConstraint = Constraint::New<Quaternion>( Actor::Property::ORIENTATION,
- Source( self, mPropertyPanDisplacement[mIndex] ),
- RotationConstraint(distance, mPageSize.width, mIsTurnBack[mPanActor]));
- mPanActor.ApplyConstraint( rotationConstraint );
+ Constraint rotationConstraint = Constraint::New<Quaternion>( mPanActor, Actor::Property::ORIENTATION, RotationConstraint(distance, mPageSize.width, mIsTurnBack[mPanActor]));
+ rotationConstraint.AddSource( Source( self, mPropertyPanDisplacement[mIndex] ) );
+ rotationConstraint.Apply();
mConstraints = false;
}
void Popup::SetTitle( const std::string& text )
{
- Toolkit::TextView titleActor = Toolkit::TextView::New();
- titleActor.SetName( "POPUP_TITLE" );
- 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 )
-{
// Replaces the current title actor.
if( mPopupLayout )
{
mPopupLayout.RemoveChildAt( Toolkit::TableView::CellPosition( 0, 0 ) );
}
- mTitle = titleActor;
+ mTitle = Toolkit::TextLabel::New( text );
+ mTitle.SetName( "POPUP_TITLE" );
+ mTitle.SetProperty( Toolkit::TextLabel::Property::MULTI_LINE, true );
+ mTitle.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
if( mPopupLayout )
{
RelayoutRequest();
}
-Toolkit::TextView Popup::GetTitle() const
+std::string Popup::GetTitle() const
{
- return mTitle;
+ if( mTitle )
+ {
+ return mTitle.GetProperty<std::string>( Toolkit::TextLabel::Property::TEXT );
+ }
+
+ return std::string();
}
void Popup::CreateFooter()
const float titleBuffer = 0.5f;
titleNaturalSize.width += titleBuffer;
- // As TextView GetNaturalSize does not take wrapping into account, limit the width
+ // As TextLabel GetNaturalSize does not take wrapping into account, limit the width
// to that of the stage
if( titleNaturalSize.width >= maxWidth)
{
#include <dali-toolkit/public-api/controls/popup/popup.h>
#include <dali-toolkit/internal/controls/popup/popup-style-impl.h>
#include <dali-toolkit/public-api/controls/table-view/table-view.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
namespace Dali
{
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;
+ 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.
+ Toolkit::TextLabel 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
/**
* Constraint operator
- * @param[in] current The current indicator position
- * @param[in] indicatorSizeProperty The size of indicator.
- * @param[in] parentSizeProperty The parent size of indicator.
- * @param[in] scrollPositionProperty The scroll position of the scrollable container // (from 0.0 -> 1.0 in each axis)
+ * @param[in,out] current The current indicator position
+ * @param[in] inputs Contains the size of indicator, the size of indicator's parent, and the scroll position of the scrollable container (from 0.0 -> 1.0 in each axis)
* @return The new indicator position is returned.
*/
- Vector3 operator()(const Vector3& current,
- const PropertyInput& indicatorSizeProperty,
- const PropertyInput& parentSizeProperty,
- const PropertyInput& scrollPositionProperty)
+ void operator()( Vector3& current, const PropertyInputContainer& inputs )
{
- Vector3 indicatorSize = indicatorSizeProperty.GetVector3();
- Vector3 parentSize = parentSizeProperty.GetVector3();
- float scrollPosition = scrollPositionProperty.GetFloat();
+ const Vector3& indicatorSize = inputs[0]->GetVector3();
+ const Vector3& parentSize = inputs[1]->GetVector3();
+ float scrollPosition = inputs[2]->GetFloat();
const float domainSize = fabs(mMaxPosition - mMinPosition);
float relativePosition = (mMaxPosition - scrollPosition) / domainSize;
- return Vector3(current.x, relativePosition * (parentSize.height - indicatorSize.height), DEFAULT_SLIDER_DEPTH);
+
+ current.y = relativePosition * ( parentSize.height - indicatorSize.height );
+ current.z = DEFAULT_SLIDER_DEPTH;
}
float mMinPosition; ///< The minimum scroll position
{
if( mScrollConnector )
{
- Constraint constraint;
-
- if(mIndicatorSizeConstraint)
- {
- mIndicator.RemoveConstraint(mIndicatorSizeConstraint);
- }
-
// Set indicator height according to the indicator's height policy
if(mIndicatorHeightPolicy == Toolkit::ScrollBar::Fixed)
{
if(mIndicatorPositionConstraint)
{
- mIndicator.RemoveConstraint(mIndicatorPositionConstraint);
+ mIndicatorPositionConstraint.Remove();
}
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- LocalSource( Actor::Property::SIZE ),
- ParentSource( Actor::Property::SIZE ),
- Source( mScrollPositionObject, Toolkit::ScrollConnector::SCROLL_POSITION ),
- IndicatorPositionConstraint( mScrollConnector.GetMinLimit(), mScrollConnector.GetMaxLimit() ) );
- mIndicatorPositionConstraint = mIndicator.ApplyConstraint( constraint );
+ mIndicatorPositionConstraint = Constraint::New<Vector3>( mIndicator, Actor::Property::POSITION, IndicatorPositionConstraint( mScrollConnector.GetMinLimit(), mScrollConnector.GetMaxLimit() ) );
+ mIndicatorPositionConstraint.AddSource( LocalSource( Actor::Property::SIZE ) );
+ mIndicatorPositionConstraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ mIndicatorPositionConstraint.AddSource( Source( mScrollPositionObject, Toolkit::ScrollConnector::SCROLL_POSITION ) );
+ mIndicatorPositionConstraint.Apply();
}
}
// EXTERNAL INCLUDES
#include <dali/public-api/adaptor-framework/timer.h>
#include <dali/public-api/actors/image-actor.h>
-#include <dali/public-api/animation/active-constraint.h>
+#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/animation.h>
#include <dali/public-api/object/property-notification.h>
ScrollPositionNotifiedSignalType mScrollPositionNotifiedSignal;
- ActiveConstraint mIndicatorSizeConstraint;
- ActiveConstraint mIndicatorPositionConstraint;
+ Constraint mIndicatorPositionConstraint;
};
} // namespace Internal
#include <dali-toolkit/internal/controls/scroll-component/scroll-bar-internal-impl.h>
// EXTERNAL INCLUDES
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/property-input.h>
#include <dali/public-api/object/type-registry.h>
* ScrollBarInternal Visibility Constraint
* Returns whether scroll bar is visible
*/
-bool ScrollBarInternalVisibilityConstraint(const bool& current,
- const PropertyInput& canScrollProperty)
+void ScrollBarInternalVisibilityConstraint( bool& current, const PropertyInputContainer& inputs )
{
- bool canScroll = canScrollProperty.GetBoolean();
- return canScroll;
+ current = inputs[0]->GetBoolean();
}
/**
/**
* Constraint operator
- * @param[in] current The current ScrollBarInternal size
- * @param[in] scrollMinProperty The container's minimum position.
- * @param[in] scrollMaxProperty The container's maximum position.
- * @param[in] scrollDirectionProperty The container's scroll direction.
- * @param[in] scrollSizeProperty The container's size of viewport.
+ * @param[in,out] current The current ScrollBarInternal size
+ * @param[in] inputs Contains the container's minimum position, its maximum position, its scroll direction & its size of viewport.
* @return The new ScrollBarInternal position is returned.
*/
- Vector3 operator()(const Vector3& current,
- const PropertyInput& scrollMinProperty,
- const PropertyInput& scrollMaxProperty,
- const PropertyInput& scrollDirectionProperty,
- const PropertyInput& scrollSizeProperty)
+ void operator()( Vector3& current, const PropertyInputContainer& inputs )
{
- const Vector3& min = scrollMinProperty.GetVector3();
- const Vector3& max = scrollMaxProperty.GetVector3();
- const Vector3& scrollDirection = scrollDirectionProperty.GetVector3();
+ const Vector3& min = inputs[0]->GetVector3();
+ const Vector3& max = inputs[1]->GetVector3();
+ const Vector3& scrollDirection = inputs[2]->GetVector3();
const Toolkit::ControlOrientation::Type& orientation = static_cast<Toolkit::ControlOrientation::Type>(scrollDirection.z);
- const Vector3& size = scrollSizeProperty.GetVector3();
+ const Vector3& size = inputs[3]->GetVector3();
const Vector3 domainSize = max - min;
if (mVertical && Toolkit::IsVertical(orientation))
{
- float mod = fabsf(domainSize.height) > size.height ? size.height * ( size.height / fabsf(domainSize.height) ) : size.height * ( (size.height - fabsf(domainSize.height * 0.5f)) / size.height);
- return Vector3( current.width, mod, current.depth );
+ current.height = fabsf(domainSize.height) > size.height ? size.height * ( size.height / fabsf(domainSize.height) ) : size.height * ( (size.height - fabsf(domainSize.height * 0.5f)) / size.height);
}
else
{
- float mod = fabsf(domainSize.height) > size.width ? size.width * ( size.width / fabsf(domainSize.height) ) : size.width * ( (size.width - fabsf(domainSize.height * 0.5f)) / size.width);
- return Vector3( current.width, mod, current.depth );
+ current.height = fabsf(domainSize.height) > size.width ? size.width * ( size.width / fabsf(domainSize.height) ) : size.width * ( (size.width - fabsf(domainSize.height * 0.5f)) / size.width);
}
}
/**
* Constraint operator
- * @param[in] current The current ScrollBarInternal rotation
+ * @param[in,out] current The current ScrollBarInternal rotation
* @param[in] scrollDirectionProperty The container's scroll direction.
* @return The new ScrollBarInternal rotation is returned.
*/
- Quaternion operator()(const Quaternion& current,
- const PropertyInput& scrollDirectionProperty)
+ void operator()( Quaternion& current, const PropertyInputContainer& inputs )
{
- const Vector3& scrollDirection = scrollDirectionProperty.GetVector3();
+ const Vector3& scrollDirection = inputs[0]->GetVector3();
const Toolkit::ControlOrientation::Type& orientation = static_cast<Toolkit::ControlOrientation::Type>(scrollDirection.z);
if( (mVertical && Toolkit::IsVertical(orientation)) || (!mVertical && Toolkit::IsHorizontal(orientation)) )
{
- return Quaternion(0.0f, Vector3::ZAXIS);
+ current = Quaternion(0.0f, Vector3::ZAXIS);
}
else
{
- return Quaternion(0.5f * Math::PI, Vector3::ZAXIS);
+ current = Quaternion(0.5f * Math::PI, Vector3::ZAXIS);
}
}
/**
* Constraint operator
- * @param[in] current The current ScrollBarInternal position
- * @param[in] scrollBarSizeProperty ScrollBarInternal size
- * @param[in] scrollRelativePositionProperty The container's relative position (from 0.0 -> 1.0 in each axis)
- * @param[in] scrollMinProperty The container's minimum position.
- * @param[in] scrollMaxProperty The container's maximum position.
- * @param[in] scrollDirectionProperty The container's scroll direction.
- * @param[in] scrollSizeProperty The container's size of viewport.
+ * @param[in] finalPosition The current ScrollBarInternal position
+ * @param[in] inputs Contains:
+ * The ScrollBarInternal size,
+ * The container's relative position (from 0.0 -> 1.0 in each axis),
+ * The container's minimum position,
+ * The container's maximum position,
+ * The container's scroll direction,
+ * The container's size of viewport.
* @return The new ScrollBarInternal position is returned.
*/
- Vector3 operator()(const Vector3& current,
- const PropertyInput& scrollBarSizeProperty,
- const PropertyInput& scrollRelativePositionProperty,
- const PropertyInput& scrollMinProperty,
- const PropertyInput& scrollMaxProperty,
- const PropertyInput& scrollDirectionProperty,
- const PropertyInput& scrollSizeProperty)
+ void operator()( Vector3& finalPosition, const PropertyInputContainer& inputs )
{
- Vector3 barSize = scrollBarSizeProperty.GetVector3();
- Vector3 relativePosition = scrollRelativePositionProperty.GetVector3();
- Vector3 size = scrollSizeProperty.GetVector3();
- const Vector3& min = scrollMinProperty.GetVector3();
- const Vector3& max = scrollMaxProperty.GetVector3();
- const Vector3& scrollDirection = scrollDirectionProperty.GetVector3();
+ const Vector3& barSize = inputs[0]->GetVector3();
+ const Vector3& relativePosition = inputs[1]->GetVector3();
+ const Vector3& min = inputs[2]->GetVector3();
+ const Vector3& max = inputs[3]->GetVector3();
+ const Vector3& scrollDirection = inputs[4]->GetVector3();
+ const Vector3& size = inputs[5]->GetVector3();
const Toolkit::ControlOrientation::Type& orientation = static_cast<Toolkit::ControlOrientation::Type>(scrollDirection.z);
Vector3 domainSize = max - min;
Vector3 maskedRelativePosition = Toolkit::IsVertical(orientation) ? Vector3(relativePosition.x * (size.x-barSize.y), relativePosition.y * (size.y-barSize.y), 0.0f) * mask
: Vector3(relativePosition.y * (size.x-barSize.y), relativePosition.x * (size.y-barSize.y), 0.0f) * mask;
- Vector3 finalPosition = relativeOffset * size + absoluteOffset + maskedRelativePosition;
+ finalPosition = relativeOffset * size + absoluteOffset + maskedRelativePosition;
// If Wrapped Slider, then position 1 domain either before or after current slider.
if(mWrap)
finalPosition.y -= size.y;
}
}
-
- return finalPosition;
}
bool mVertical; ///< Whether vertical or horizontal.
/**
* Constraint operator
* @param[in] current The current HitSize
- * @param[in] scrollDirectionProperty The container's scroll direction.
- * @param[in] scrollSizeProperty The container's size of viewport.
+ * @param[in] inputs Contains the container's scroll direction and size of its viewport.
* @return The new ScrollBarInternal Hit Area size is returned.
*/
- Vector3 operator()(const Vector3& current,
- const PropertyInput& scrollDirectionProperty,
- const PropertyInput& scrollSizeProperty)
+ void operator()( Vector3& current, const PropertyInputContainer& inputs )
{
- const Vector3& scrollDirection = scrollDirectionProperty.GetVector3();
+ const Vector3& scrollDirection = inputs[0]->GetVector3();
const Toolkit::ControlOrientation::Type& orientation = static_cast<Toolkit::ControlOrientation::Type>(scrollDirection.z);
- Vector3 size = scrollSizeProperty.GetVector3();
+ const Vector3& size = inputs[1]->GetVector3();
Vector3 mask; // Mask size aspect of hit area.
Vector3 offset; // Add Offset size.
offset = Vector3::YAXIS * mThickness;
}
- return size * mask + offset;
+ current = size * mask + offset;
}
bool mVertical; ///< Whether vertical or horizontal.
// target the container to observe for scrolling
Actor target = mContainer.Self();
- Constraint constraint = Constraint::New<bool>( Actor::Property::VISIBLE,
- Source( target, vertical ? Toolkit::Scrollable::Property::CAN_SCROLL_VERTICAL : Toolkit::Scrollable::Property::CAN_SCROLL_HORIZONTAL),
- ScrollBarInternalVisibilityConstraint );
- mSlider.ApplyConstraint( constraint );
- mSliderWrap.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector3>( Actor::Property::SIZE,
- Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source( target, Toolkit::Scrollable::Property::SCROLL_DIRECTION ),
- Source( target, Actor::Property::SIZE ),
- ScrollBarInternalSizeConstraint( vertical ) );
- mSlider.ApplyConstraint( constraint );
- mSliderWrap.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Quaternion>( Actor::Property::ORIENTATION,
- Source( target, Toolkit::Scrollable::Property::SCROLL_DIRECTION ),
- ScrollBarInternalRotationConstraint( vertical ) );
- mSlider.ApplyConstraint( constraint );
- mSliderWrap.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- Source( mSlider, Actor::Property::SIZE),
- Source( target, Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION ),
- Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source( target, Toolkit::Scrollable::Property::SCROLL_DIRECTION ),
- Source( target, Actor::Property::SIZE ),
- ScrollBarInternalPositionConstraint(vertical) );
-
- mSlider.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- Source( mSlider, Actor::Property::SIZE),
- Source( target, Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION ),
- Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source( target, Toolkit::Scrollable::Property::SCROLL_DIRECTION ),
- Source( target, Actor::Property::SIZE ),
- ScrollBarInternalPositionConstraint(vertical, true) );
- mSliderWrap.ApplyConstraint( constraint );
+ Constraint constraint = Constraint::New<bool>( mSlider, Actor::Property::VISIBLE, ScrollBarInternalVisibilityConstraint );
+ constraint.AddSource( Source( target, vertical ? Toolkit::Scrollable::Property::CAN_SCROLL_VERTICAL : Toolkit::Scrollable::Property::CAN_SCROLL_HORIZONTAL ) );
+ constraint.Apply();
+
+ constraint = constraint.Clone( mSliderWrap );
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector3>( mSlider, Actor::Property::SIZE, ScrollBarInternalSizeConstraint( vertical ) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_DIRECTION ) );
+ constraint.AddSource( Source( target, Actor::Property::SIZE ) );
+ constraint.Apply();
+
+ constraint = constraint.Clone( mSliderWrap );
+ constraint.Apply();
+
+ constraint = Constraint::New<Quaternion>( mSlider, Actor::Property::ORIENTATION, ScrollBarInternalRotationConstraint( vertical ) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_DIRECTION ) );
+ constraint.Apply();
+
+ constraint = constraint.Clone( mSliderWrap );
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector3>( mSlider, Actor::Property::POSITION, ScrollBarInternalPositionConstraint(vertical) );
+ constraint.AddSource( Source( mSlider, Actor::Property::SIZE) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION ) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_DIRECTION ) );
+ constraint.AddSource( Source( target, Actor::Property::SIZE ) );
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector3>( mSliderWrap, Actor::Property::POSITION, ScrollBarInternalPositionConstraint(vertical, true) );
+ constraint.AddSource( Source( mSlider, Actor::Property::SIZE) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION ) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_DIRECTION ) );
+ constraint.AddSource( Source( target, Actor::Property::SIZE ) );
+ constraint.Apply();
// Add Sliders to internal Actor, to avoid mixing up with regular
// Actors added by user.
mHitArea.SetPosition(0.0f, 0.0f, 0.2f);
mContainer.AddOverlay( mHitArea );
- constraint = Constraint::New<Vector3>( Actor::Property::SIZE,
- Source( target, Toolkit::Scrollable::Property::SCROLL_DIRECTION ),
- Source( target, Actor::Property::SIZE ),
- ScrollBarInternalHitSizeConstraint(vertical, BAR_TAB_SIZE.width) );
- mHitArea.ApplyConstraint( constraint );
+ constraint = Constraint::New<Vector3>( mHitArea, Actor::Property::SIZE, ScrollBarInternalHitSizeConstraint(vertical, BAR_TAB_SIZE.width) );
+ constraint.AddSource( Source( target, Toolkit::Scrollable::Property::SCROLL_DIRECTION ) );
+ constraint.AddSource( Source( target, Actor::Property::SIZE ) );
+ constraint.Apply();
if(vertical)
{
// EXTERNAL INCLUDES
#include <math.h>
#include <dali/public-api/actors/mesh-actor.h>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/geometry/animatable-mesh.h>
#include <dali/public-api/shader-effects/shader-effect.h>
{
}
- Vector3 operator()( const Vector3& current, const PropertyInput& bounceCoef )
+ void operator()( Vector3& current, const PropertyInputContainer& inputs )
{
- float positionY = mInitialY + mRange * fabsf(bounceCoef.GetFloat());
- return Vector3( current.x, positionY, current.z );
+ current.y = mInitialY + mRange * fabsf( inputs[0]->GetFloat() );
}
float mInitialY;
for( size_t i=0;i<NUM_LAYERS;i++ )
{
size_t j=i*4;
- mesh.ApplyConstraint( Constraint::New<Vector3>( mesh.GetPropertyIndex(j+2, AnimatableVertex::Property::POSITION ),
- Source(meshActor, bouncePropertyIndex),
- VertexPositionConstraint(-0.5f, LAYER_HEIGHTS[i]) ) );
- mesh.ApplyConstraint( Constraint::New<Vector3>( mesh.GetPropertyIndex(j+3, AnimatableVertex::Property::POSITION),
- Source(meshActor, bouncePropertyIndex),
- VertexPositionConstraint(-0.5f, LAYER_HEIGHTS[i]) ) );
+ Constraint constraint = Constraint::New<Vector3>( mesh, mesh.GetPropertyIndex(j+2, AnimatableVertex::Property::POSITION ), VertexPositionConstraint(-0.5f, LAYER_HEIGHTS[i]) );
+ constraint.AddSource( Source(meshActor, bouncePropertyIndex) );
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector3>( mesh, mesh.GetPropertyIndex(j+3, AnimatableVertex::Property::POSITION), VertexPositionConstraint(-0.5f, LAYER_HEIGHTS[i]) );
+ constraint.AddSource( Source(meshActor, bouncePropertyIndex) );
+ constraint.Apply();
}
return meshActor;
// EXTERNAL INCLUDES
#include <algorithm>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/common/set-wrapper.h>
}
// Overshoot overlay constraints
-
-struct OvershootOverlaySizeConstraint
+void OvershootOverlaySizeConstraint( Vector3& current, const PropertyInputContainer& inputs )
{
- Vector3 operator()(const Vector3& current,
- const PropertyInput& parentScrollDirectionProperty,
- const PropertyInput& parentOvershootProperty,
- const PropertyInput& parentSizeProperty)
- {
- const Vector3 parentScrollDirection = parentScrollDirectionProperty.GetVector3();
- const Vector3 parentSize = parentSizeProperty.GetVector3();
- const Toolkit::ControlOrientation::Type& parentOrientation = static_cast<Toolkit::ControlOrientation::Type>(parentScrollDirection.z);
+ const Vector3& parentScrollDirection = inputs[0]->GetVector3();
+ const Vector3& parentSize = inputs[1]->GetVector3();
+ const Toolkit::ControlOrientation::Type& parentOrientation = static_cast<Toolkit::ControlOrientation::Type>(parentScrollDirection.z);
- float overlayWidth;
-
- if(Toolkit::IsVertical(parentOrientation))
- {
- overlayWidth = fabsf(parentScrollDirection.y) > Math::MACHINE_EPSILON_1 ? parentSize.x : parentSize.y;
- }
- else
- {
- overlayWidth = fabsf(parentScrollDirection.x) > Math::MACHINE_EPSILON_1 ? parentSize.y : parentSize.x;
- }
-
- float overlayHeight = (overlayWidth > OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD) ? OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height : OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height*0.5f;
-
- return Vector3( overlayWidth, overlayHeight, current.depth );
+ if(Toolkit::IsVertical(parentOrientation))
+ {
+ current.width = fabsf(parentScrollDirection.y) > Math::MACHINE_EPSILON_1 ? parentSize.x : parentSize.y;
+ }
+ else
+ {
+ current.width = fabsf(parentScrollDirection.x) > Math::MACHINE_EPSILON_1 ? parentSize.y : parentSize.x;
}
-};
-struct OvershootOverlayRotationConstraint
+ current.height = ( current.width > OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD ) ? OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height : OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height*0.5f;
+}
+
+void OvershootOverlayRotationConstraint( Quaternion& current, const PropertyInputContainer& inputs )
{
- Quaternion operator()(const Quaternion& current,
- const PropertyInput& parentScrollDirectionProperty,
- const PropertyInput& parentOvershootProperty)
- {
- const Vector3 parentScrollDirection = parentScrollDirectionProperty.GetVector3();
- const float parentOvershoot = parentOvershootProperty.GetFloat();
- const Toolkit::ControlOrientation::Type& parentOrientation = static_cast<Toolkit::ControlOrientation::Type>(parentScrollDirection.z);
+ const Vector3& parentScrollDirection = inputs[0]->GetVector3();
+ const float parentOvershoot = inputs[1]->GetFloat();
+ const Toolkit::ControlOrientation::Type& parentOrientation = static_cast<Toolkit::ControlOrientation::Type>(parentScrollDirection.z);
- float multiplier = 0;
- if(Toolkit::IsVertical(parentOrientation))
+ float multiplier = 0;
+ if(Toolkit::IsVertical(parentOrientation))
+ {
+ if(fabsf(parentScrollDirection.y) <= Math::MACHINE_EPSILON_1)
{
- if(fabsf(parentScrollDirection.y) <= Math::MACHINE_EPSILON_1)
+ if( (parentOrientation == Toolkit::ControlOrientation::Up && parentOvershoot < Math::MACHINE_EPSILON_0)
+ || (parentOrientation == Toolkit::ControlOrientation::Down && parentOvershoot > Math::MACHINE_EPSILON_0) )
{
- if( (parentOrientation == Toolkit::ControlOrientation::Up && parentOvershoot < Math::MACHINE_EPSILON_0)
- || (parentOrientation == Toolkit::ControlOrientation::Down && parentOvershoot > Math::MACHINE_EPSILON_0) )
- {
- multiplier = 0.5f;
- }
- else
- {
- multiplier = 1.5f;
- }
- }
- else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.y > Math::MACHINE_EPSILON_0)
- || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.y < Math::MACHINE_EPSILON_0) )
- {
- multiplier = 0.0f;
+ multiplier = 0.5f;
}
else
{
- multiplier = 1.0f;
+ multiplier = 1.5f;
}
}
+ else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.y > Math::MACHINE_EPSILON_0)
+ || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.y < Math::MACHINE_EPSILON_0) )
+ {
+ multiplier = 0.0f;
+ }
else
{
- if(fabsf(parentScrollDirection.x) <= Math::MACHINE_EPSILON_1)
- {
- if( (parentOrientation == Toolkit::ControlOrientation::Left && parentOvershoot > Math::MACHINE_EPSILON_0)
- ||(parentOrientation == Toolkit::ControlOrientation::Right && parentOvershoot < Math::MACHINE_EPSILON_0) )
- {
- multiplier = 1.0f;
- }
- else
- {
- multiplier = 0.0f;
- }
- }
- else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.x > Math::MACHINE_EPSILON_0)
- || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.x < Math::MACHINE_EPSILON_0) )
+ multiplier = 1.0f;
+ }
+ }
+ else
+ {
+ if(fabsf(parentScrollDirection.x) <= Math::MACHINE_EPSILON_1)
+ {
+ if( (parentOrientation == Toolkit::ControlOrientation::Left && parentOvershoot > Math::MACHINE_EPSILON_0)
+ ||(parentOrientation == Toolkit::ControlOrientation::Right && parentOvershoot < Math::MACHINE_EPSILON_0) )
{
- multiplier = 1.5f;
+ multiplier = 1.0f;
}
else
{
- multiplier = 0.5f;
+ multiplier = 0.0f;
}
}
-
- Quaternion rotation( Radian( multiplier * Math::PI ), Vector3::ZAXIS );
-
- return rotation;
+ else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.x > Math::MACHINE_EPSILON_0)
+ || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.x < Math::MACHINE_EPSILON_0) )
+ {
+ multiplier = 1.5f;
+ }
+ else
+ {
+ multiplier = 0.5f;
+ }
}
-};
-struct OvershootOverlayPositionConstraint
+ current = Quaternion( Radian( multiplier * Math::PI ), Vector3::ZAXIS );
+}
+
+void OvershootOverlayPositionConstraint( Vector3& current, const PropertyInputContainer& inputs )
{
- Vector3 operator()(const Vector3& current,
- const PropertyInput& parentSizeProperty,
- const PropertyInput& parentScrollDirectionProperty,
- const PropertyInput& parentOvershootProperty)
- {
- const Vector3 parentScrollDirection = parentScrollDirectionProperty.GetVector3();
- const float parentOvershoot = parentOvershootProperty.GetFloat();
- const Vector3 parentSize = parentSizeProperty.GetVector3();
- const Toolkit::ControlOrientation::Type& parentOrientation = static_cast<Toolkit::ControlOrientation::Type>(parentScrollDirection.z);
+ const Vector3& parentSize = inputs[0]->GetVector3();
+ const Vector3& parentScrollDirection = inputs[1]->GetVector3();
+ const float parentOvershoot = inputs[2]->GetFloat();
+ const Toolkit::ControlOrientation::Type& parentOrientation = static_cast<Toolkit::ControlOrientation::Type>(parentScrollDirection.z);
- Vector3 relativeOffset;
+ Vector3 relativeOffset;
- if(Toolkit::IsVertical(parentOrientation))
+ if(Toolkit::IsVertical(parentOrientation))
+ {
+ if(fabsf(parentScrollDirection.y) <= Math::MACHINE_EPSILON_1)
{
- if(fabsf(parentScrollDirection.y) <= Math::MACHINE_EPSILON_1)
+ if( (parentOrientation == Toolkit::ControlOrientation::Up && parentOvershoot < Math::MACHINE_EPSILON_0)
+ || (parentOrientation == Toolkit::ControlOrientation::Down && parentOvershoot > Math::MACHINE_EPSILON_0) )
{
- if( (parentOrientation == Toolkit::ControlOrientation::Up && parentOvershoot < Math::MACHINE_EPSILON_0)
- || (parentOrientation == Toolkit::ControlOrientation::Down && parentOvershoot > Math::MACHINE_EPSILON_0) )
- {
- relativeOffset = Vector3(1.0f, 0.0f, 0.0f);
- }
- else
- {
- relativeOffset =Vector3(0.0f, 1.0f, 0.0f);
- }
- }
- else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.y > Math::MACHINE_EPSILON_0)
- || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.y < Math::MACHINE_EPSILON_0) )
- {
- relativeOffset = Vector3(0.0f, 0.0f, 0.0f);
+ relativeOffset = Vector3(1.0f, 0.0f, 0.0f);
}
else
{
- relativeOffset = Vector3(1.0f, 1.0f, 0.0f);
+ relativeOffset =Vector3(0.0f, 1.0f, 0.0f);
}
}
+ else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.y > Math::MACHINE_EPSILON_0)
+ || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.y < Math::MACHINE_EPSILON_0) )
+ {
+ relativeOffset = Vector3(0.0f, 0.0f, 0.0f);
+ }
else
{
- if(fabsf(parentScrollDirection.x) <= Math::MACHINE_EPSILON_1)
- {
- if( (parentOrientation == Toolkit::ControlOrientation::Left && parentOvershoot < Math::MACHINE_EPSILON_0)
- || (parentOrientation == Toolkit::ControlOrientation::Right && parentOvershoot > Math::MACHINE_EPSILON_0) )
- {
- relativeOffset = Vector3(0.0f, 0.0f, 0.0f);
- }
- else
- {
- relativeOffset = Vector3(1.0f, 1.0f, 0.0f);
- }
- }
- else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.x > Math::MACHINE_EPSILON_0)
- || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.x < Math::MACHINE_EPSILON_0) )
+ relativeOffset = Vector3(1.0f, 1.0f, 0.0f);
+ }
+ }
+ else
+ {
+ if(fabsf(parentScrollDirection.x) <= Math::MACHINE_EPSILON_1)
+ {
+ if( (parentOrientation == Toolkit::ControlOrientation::Left && parentOvershoot < Math::MACHINE_EPSILON_0)
+ || (parentOrientation == Toolkit::ControlOrientation::Right && parentOvershoot > Math::MACHINE_EPSILON_0) )
{
- relativeOffset = Vector3(0.0f, 1.0f, 0.0f);
+ relativeOffset = Vector3(0.0f, 0.0f, 0.0f);
}
else
{
- relativeOffset = Vector3(1.0f, 0.0f, 0.0f);
+ relativeOffset = Vector3(1.0f, 1.0f, 0.0f);
}
}
-
- return relativeOffset * parentSize;
-
+ else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.x > Math::MACHINE_EPSILON_0)
+ || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.x < Math::MACHINE_EPSILON_0) )
+ {
+ relativeOffset = Vector3(0.0f, 1.0f, 0.0f);
+ }
+ else
+ {
+ relativeOffset = Vector3(1.0f, 0.0f, 0.0f);
+ }
}
-};
-struct OvershootOverlayVisibilityConstraint
-{
- bool operator()(const bool& current,
- const PropertyInput& parentLayoutScrollableProperty)
- {
- const bool parentLayoutScrollable = parentLayoutScrollableProperty.GetBoolean();
+ current = relativeOffset * parentSize;
+}
- return parentLayoutScrollable;
- }
-};
+void OvershootOverlayVisibilityConstraint( bool& current, const PropertyInputContainer& inputs )
+{
+ current = inputs[0]->GetBoolean();
+}
/**
* Relative position Constraint
* Generates the relative position value of the item view based on the layout position,
* and it's relation to the layout domain. This is a value from 0.0f to 1.0f in each axis.
*/
-Vector3 RelativePositionConstraint(const Vector3& current,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollMinProperty,
- const PropertyInput& scrollMaxProperty,
- const PropertyInput& layoutSizeProperty)
+void RelativePositionConstraint( Vector3& current, const PropertyInputContainer& inputs )
{
- const Vector3& position = Vector3(0.0f, scrollPositionProperty.GetFloat(), 0.0f);
- const Vector3& min = scrollMinProperty.GetVector3();
- const Vector3& max = scrollMaxProperty.GetVector3();
+ const Vector3& position = Vector3(0.0f, inputs[0]->GetFloat(), 0.0f);
+ const Vector3& min = inputs[1]->GetVector3();
+ const Vector3& max = inputs[2]->GetVector3();
- Vector3 relativePosition;
Vector3 domainSize = max - min;
- relativePosition.x = fabsf(domainSize.x) > Math::MACHINE_EPSILON_1 ? ((min.x - position.x) / fabsf(domainSize.x)) : 0.0f;
- relativePosition.y = fabsf(domainSize.y) > Math::MACHINE_EPSILON_1 ? ((min.y - position.y) / fabsf(domainSize.y)) : 0.0f;
-
- return relativePosition;
+ current.x = fabsf(domainSize.x) > Math::MACHINE_EPSILON_1 ? ((min.x - position.x) / fabsf(domainSize.x)) : 0.0f;
+ current.y = fabsf(domainSize.y) > Math::MACHINE_EPSILON_1 ? ((min.y - position.y) / fabsf(domainSize.y)) : 0.0f;
+ current.z = 0.0f;
}
} // unnamed namespace
EnableScrollComponent(Toolkit::Scrollable::OvershootIndicator);
- Constraint constraint = Constraint::New<Vector3>(Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION,
- LocalSource(mPropertyPosition),
- LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MIN),
- LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX),
- LocalSource(Actor::Property::SIZE),
- RelativePositionConstraint);
- self.ApplyConstraint(constraint);
+ Constraint constraint = Constraint::New<Vector3>( self, Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION, RelativePositionConstraint );
+ constraint.AddSource( LocalSource( mPropertyPosition ) );
+ constraint.AddSource( LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.Apply();
Vector2 stageSize = Stage::GetCurrent().GetSize();
mMouseWheelScrollDistanceStep = stageSize.y * DEFAULT_MOUSE_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION;
mOvershootOverlay.SetDrawMode(DrawMode::OVERLAY);
self.Add(mOvershootOverlay);
- Constraint constraint = Constraint::New<Vector3>( Actor::Property::SIZE,
- ParentSource( Toolkit::Scrollable::Property::SCROLL_DIRECTION ),
- Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ),
- ParentSource( Actor::Property::SIZE ),
- OvershootOverlaySizeConstraint() );
- mOvershootOverlay.ApplyConstraint(constraint);
+ Constraint constraint = Constraint::New<Vector3>( mOvershootOverlay, Actor::Property::SIZE, OvershootOverlaySizeConstraint );
+ constraint.AddSource( ParentSource( Toolkit::Scrollable::Property::SCROLL_DIRECTION ) );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.Apply();
+
mOvershootOverlay.SetSize(OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.width, OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height);
- constraint = Constraint::New<Quaternion>( Actor::Property::ORIENTATION,
- ParentSource( Toolkit::Scrollable::Property::SCROLL_DIRECTION ),
- Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ),
- OvershootOverlayRotationConstraint() );
- mOvershootOverlay.ApplyConstraint(constraint);
-
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- ParentSource( Actor::Property::SIZE ),
- ParentSource( Toolkit::Scrollable::Property::SCROLL_DIRECTION ),
- Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ),
- OvershootOverlayPositionConstraint() );
- mOvershootOverlay.ApplyConstraint(constraint);
-
- constraint = Constraint::New<bool>( Actor::Property::VISIBLE,
- ParentSource( Toolkit::Scrollable::Property::CAN_SCROLL_VERTICAL ),
- OvershootOverlayVisibilityConstraint() );
- mOvershootOverlay.ApplyConstraint(constraint);
-
- constraint = Constraint::New<float>( effectOvershootPropertyIndex,
- Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ),
- EqualToConstraint() );
- mOvershootOverlay.ApplyConstraint(constraint);
+ constraint = Constraint::New<Quaternion>( mOvershootOverlay, Actor::Property::ORIENTATION, OvershootOverlayRotationConstraint );
+ constraint.AddSource( ParentSource( Toolkit::Scrollable::Property::SCROLL_DIRECTION ) );
+ constraint.AddSource( Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ) );
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector3>( mOvershootOverlay, Actor::Property::POSITION, OvershootOverlayPositionConstraint );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.AddSource( ParentSource( Toolkit::Scrollable::Property::SCROLL_DIRECTION ) );
+ constraint.AddSource( Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ) );
+ constraint.Apply();
+
+ constraint = Constraint::New<bool>( mOvershootOverlay, Actor::Property::VISIBLE, OvershootOverlayVisibilityConstraint );
+ constraint.AddSource( ParentSource( Toolkit::Scrollable::Property::CAN_SCROLL_VERTICAL ) );
+ constraint.Apply();
+
+ constraint = Constraint::New<float>( mOvershootOverlay, effectOvershootPropertyIndex, EqualToConstraint() );
+ constraint.AddSource( Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ) );
+ constraint.Apply();
}
else
{
if(mOvershootAnimationSpeed > Math::MACHINE_EPSILON_0)
{
float currentOvershoot = mScrollPositionObject.GetProperty<float>(ScrollConnector::OVERSHOOT);
- float duration = mOvershootOverlay.GetCurrentSize().height * (animatingOn ? (1.0f - fabsf(currentOvershoot)) : fabsf(currentOvershoot)) / mOvershootAnimationSpeed;
+ float duration = 0.0f;
+
+ if (mOvershootOverlay)
+ {
+ duration = mOvershootOverlay.GetCurrentSize().height * (animatingOn ? (1.0f - fabsf(currentOvershoot)) : fabsf(currentOvershoot)) / mOvershootAnimationSpeed;
+ }
RemoveAnimation(mScrollOvershootAnimation);
mScrollOvershootAnimation = Animation::New(duration);
// EXTERNAL INCLUDES
// TODO - Replace list with dali-vector.h
#include <list>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
// INTERNAL INCLUDES
*/
void ApplyConstraint(Constraint constraint)
{
- ActiveConstraint activeConstraint = mActor.ApplyConstraint( constraint );
- mConstraints.push_back( activeConstraint );
+ Constraint clone = constraint.Clone( mActor );
+ clone.Apply();
+ mConstraints.push_back( clone );
}
/**
*/
void RemoveConstraints()
{
- std::vector<ActiveConstraint>::iterator it = mConstraints.begin();
- std::vector<ActiveConstraint>::iterator end = mConstraints.end();
+ std::vector<Constraint>::iterator it = mConstraints.begin();
+ std::vector<Constraint>::iterator end = mConstraints.end();
for(;it!=end;++it)
{
- mActor.RemoveConstraint(*it);
+ it->Remove();
}
mConstraints.clear();
}
Actor mActor; ///< The Actor that this ActorInfo represents.
- std::vector<ActiveConstraint> mConstraints; ///< A list keeping track of constraints applied to the actor via this delegate.
+ std::vector<Constraint> mConstraints; ///< A list keeping track of constraints applied to the actor via this delegate.
};
typedef IntrusivePtr<ActorInfo> ActorInfoPtr;
// CLASS HEADER
#include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.h>
-// EXTERNAL INCLUDES
-#include <boost/bind.hpp>
-
// INTERNAL INCLUDES
#include <dali-toolkit/internal/controls/scrollable/scrollable-impl.h>
#include <dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h>
*/
// EXTERNAL INCLUDES
-#include <boost/bind.hpp>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/property-input.h>
}
/**
- * @param[in] current The current visibility of this Actor
- * @param[in] positionProperty The Actor's Position.
- * @param[in] scaleProperty The Actor's Scale.
- * @param[in] sizeProperty The Actor's Size
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
+ * @param[in,out] current The current visibility of this Actor
+ * @param[in] inputs Contains:
+ * The Actor's Position
+ * The Actor's Scale
+ * The Actor's Size
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The size of the scroll-view (scrollView SIZE)
* @return The new visibility of this Actor.
*/
- bool VisibilityConstraint(const bool& current,
- const PropertyInput& positionProperty,
- const PropertyInput& scaleProperty,
- const PropertyInput& sizeProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollSizeProperty)
+ void VisibilityConstraint( bool& current, const PropertyInputContainer& inputs )
{
const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
- Vector2 position(positionProperty.GetVector3() + scrollPositionProperty.GetVector3());
- Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
+ Vector2 position( inputs[0]->GetVector3() + inputs[3]->GetVector3());
+ Vector2 scaledSize( inputs[2]->GetVector3() * inputs[1]->GetVector3());
- Vector2 domain(scrollSizeProperty.GetVector3());
+ Vector2 domain( inputs[4]->GetVector3() );
position -= (anchor - mVisibilityThreshold) * scaledSize;
domain -= (Vector2::ONE - mVisibilityThreshold * 2.0f) * scaledSize;
- return ( position.x >= 0 &&
- position.x <= domain.x &&
- position.y >= 0 &&
- position.y <= domain.y );
+ current = ( position.x >= 0 &&
+ position.x <= domain.x &&
+ position.y >= 0 &&
+ position.y <= domain.y );
}
/**
- * @param[in] current The current orientation of this Actor
- * @param[in] positionProperty The Actor's Position.
- * @param[in] scaleProperty The Actor's Scale.
- * @param[in] sizeProperty The Actor's Size
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
- * @param[in] activateProperty Activation value (0 - normal, 1.0 - full effect)
+ * @param[in,out] current The current orientation of this Actor
+ * @param[in] inputs Contains:
+ * The Actor's Position.
+ * The Actor's Scale.
+ * The Actor's Size
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The size of the scroll-view (scrollView SIZE)
+ * Activation value (0 - normal, 1.0 - full effect)
* @return The new orientation of this Actor.
*/
- Quaternion RotationConstraint(const Quaternion& current,
- const PropertyInput& positionProperty,
- const PropertyInput& scaleProperty,
- const PropertyInput& sizeProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollSizeProperty,
- const PropertyInput& activateProperty)
+ void RotationConstraint( Quaternion& current, const PropertyInputContainer& inputs )
{
- const float activate(activateProperty.GetFloat());
+ const float activate(inputs[5]->GetFloat());
if(activate <= Math::MACHINE_EPSILON_0)
{
- return current;
+ return;
}
const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
- Vector2 position(positionProperty.GetVector3() + scrollPositionProperty.GetVector3());
- Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
- Vector2 domain(scrollSizeProperty.GetVector3());
+ Vector2 position(inputs[0]->GetVector3() + inputs[3]->GetVector3());
+ Vector2 scaledSize(inputs[2]->GetVector3() * inputs[1]->GetVector3());
+ Vector2 domain(inputs[4]->GetVector3());
position -= (anchor - mCanvasMargin) * scaledSize;
domain -= (Vector2::ONE - mCanvasMargin * 2.0f) * scaledSize;
angle *= activate;
- return Quaternion(-angle.x, Vector3::YAXIS) *
- Quaternion(angle.y, Vector3::XAXIS) *
- current;
+ current = Quaternion(-angle.x, Vector3::YAXIS) *
+ Quaternion(angle.y, Vector3::XAXIS) *
+ current;
}
/**
- * @param[in] current The current position of this Actor
- * @param[in] scaleProperty The Actor's Scale.
- * @param[in] sizeProperty The Actor's Size
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollSizeProperty The size of the scroll-view (scrollView SIZE)
- * @param[in] activateProperty Activation value (0 - normal, 1.0 - full effect)
+ * @param[in,out] current The current position of this Actor
+ * @param[in] inputs Contains:
+ * The Actor's Scale.
+ * The Actor's Size
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The size of the scroll-view (scrollView SIZE)
+ * Activation value (0 - normal, 1.0 - full effect)
* @return The new position of this Actor.
*/
- Vector3 PositionConstraint(const Vector3& current,
- const PropertyInput& scaleProperty,
- const PropertyInput& sizeProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollSizeProperty,
- const PropertyInput& activateProperty)
+ void PositionConstraint( Vector3& position, const PropertyInputContainer& inputs )
{
- const float activate(activateProperty.GetFloat());
- Vector3 position(current + scrollPositionProperty.GetVector3());
+ const float activate(inputs[4]->GetFloat());
if(activate <= Math::MACHINE_EPSILON_0)
{
- return position;
+ return;
}
+ position += inputs[2]->GetVector3();
+
const Vector2& anchor(AnchorPoint::CENTER.GetVectorXY());
- Vector2 scaledSize(sizeProperty.GetVector3() * scaleProperty.GetVector3());
- Vector2 domain(scrollSizeProperty.GetVector3());
+ Vector2 scaledSize(inputs[1]->GetVector3() * inputs[0]->GetVector3());
+ Vector2 domain(inputs[3]->GetVector3());
position.GetVectorXY() -= (anchor - mCanvasMargin) * scaledSize;
domain -= (Vector2::ONE - mCanvasMargin * 2.0f) * scaledSize;
}
position.GetVectorXY() += (anchor - mCanvasMargin) * scaledSize;
-
- return position;
}
Vector2 mAngleSwing; ///< Maximum amount in X and Y axes to rotate.
// Apply constraints to this actor //
Constraint constraint;
- constraint = Constraint::New<bool>( Actor::Property::VISIBLE,
- LocalSource( Actor::Property::POSITION ),
- LocalSource( Actor::Property::SCALE ),
- LocalSource( Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_POSITION ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
- boost::bind( &ScrollCarouselEffectInfo::VisibilityConstraint, info, _1, _2, _3, _4, _5, _6) );
+ constraint = Constraint::New<bool>( child, Actor::Property::VISIBLE, info, &ScrollCarouselEffectInfo::VisibilityConstraint );
+ constraint.AddSource( LocalSource( Actor::Property::POSITION ) );
+ constraint.AddSource( LocalSource( Actor::Property::SCALE ) );
+ constraint.AddSource( LocalSource( Actor::Property::SIZE ) );
+ constraint.AddSource( Source( scrollView, Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ constraint.AddSource( Source( scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source( scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Quaternion>( Actor::Property::ORIENTATION,
- LocalSource( Actor::Property::POSITION ),
- LocalSource( Actor::Property::SCALE ),
- LocalSource( Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_POSITION ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
- boost::bind( &ScrollCarouselEffectInfo::RotationConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
+ constraint.Apply();
+
+ constraint = Constraint::New<Quaternion>( child, Actor::Property::ORIENTATION, info, &ScrollCarouselEffectInfo::RotationConstraint );
+ constraint.AddSource( LocalSource( Actor::Property::POSITION ) );
+ constraint.AddSource( LocalSource( Actor::Property::SCALE ) );
+ constraint.AddSource( LocalSource( Actor::Property::SIZE ) );
+ constraint.AddSource( Source( scrollView, Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ constraint.AddSource( Source( scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source( scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- LocalSource( Actor::Property::SCALE ),
- LocalSource( Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_POSITION ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ),
- boost::bind( &ScrollCarouselEffectInfo::PositionConstraint, info, _1, _2, _3, _4, _5, _6) );
-
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector3>( child, Actor::Property::POSITION, info, &ScrollCarouselEffectInfo::PositionConstraint );
+ constraint.AddSource( LocalSource( Actor::Property::SCALE ) );
+ constraint.AddSource( LocalSource( Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, scrollView.GetPropertyIndex( Toolkit::ScrollViewCarouselEffect::EFFECT_ACTIVATE ) ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
+ constraint.Apply();
}
} // unnamed namespace
*/
// EXTERNAL INCLUDES
-#include <boost/bind.hpp>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/property-input.h>
}
/**
- * @param[in] current The current orientation of this Actor
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollWrap Whether scroll wrap has been enabled or not (WRAP)
+ * @param[in,out] current The current orientation of this Actor
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * Whether scroll wrap has been enabled or not (SCROLL_WRAP)
* @return The new orientation of this Actor.
*/
- Quaternion RotationConstraint(const Quaternion& current,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollWrap)
+ void RotationConstraint( Quaternion& current, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: for orthognal view.
if( (fabsf(position.x) < Math::MACHINE_EPSILON_1) && (fabsf(position.y) < Math::MACHINE_EPSILON_1) )
{
- return current;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
- bool wrap = scrollWrap.GetBoolean();
+ const Vector3& pageSize = inputs[4]->GetVector3();
+ bool wrap = inputs[5]->GetBoolean();
if(wrap)
{
- const Vector3& min = scrollPositionMin.GetVector3();
- const Vector3& max = scrollPositionMax.GetVector3();
+ const Vector3& min = inputs[2]->GetVector3();
+ const Vector3& max = inputs[3]->GetVector3();
if(fabsf(min.x - max.x) > Math::MACHINE_EPSILON_1)
{
// short circuit: for pages outside of view.
if( (fabsf(position.x) >= pageSize.x) || (fabsf(position.y) >= pageSize.y) )
{
- return current;
+ return;
}
position.x /= pageSize.x;
Vector2 angle( Clamp(position.x, -1.0f,1.0f),
Clamp(position.y, -1.0f,1.0f) );
- Quaternion rotation = Quaternion(angle.x * mAngleSwing.x, Vector3::YAXIS) *
+ current = Quaternion( angle.x * mAngleSwing.x, Vector3::YAXIS) *
Quaternion(-angle.y * mAngleSwing.y, Vector3::XAXIS) *
current;
-
- return rotation;
}
/**
- * @param[in] current The current color of this Actor
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollWrap Whether scroll wrap has been enabled or not (WRAP)
+ * @param[in,out] current The current color of this Actor
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * Whether scroll wrap has been enabled or not (SCROLL_WRAP)
* @return The new color of this Actor.
*/
- Vector4 ColorConstraint(const Vector4& current,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollWrap)
+ void ColorConstraint( Vector4& current, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: for orthognal view.
if( (fabsf(position.x) < Math::MACHINE_EPSILON_1) && (fabsf(position.y) < Math::MACHINE_EPSILON_1) )
{
- return current;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
- bool wrap = scrollWrap.GetBoolean();
+ const Vector3& pageSize = inputs[4]->GetVector3();
+ bool wrap = inputs[5]->GetBoolean();
if(wrap)
{
- const Vector3& min = scrollPositionMin.GetVector3();
- const Vector3& max = scrollPositionMax.GetVector3();
+ const Vector3& min = inputs[2]->GetVector3();
+ const Vector3& max = inputs[3]->GetVector3();
if(fabsf(min.x - max.x) > Math::MACHINE_EPSILON_1)
{
{
// note preserve color channels incase there is a shader/further constraint
// that wishes to do something with that information.
- return Vector4(current.r, current.g, current.b, 0.0f);
+ current.a = 0.0f;
+ return;
}
position.x /= pageSize.x;
float f = (1.0f - fabsf(angle.x)) * (1.0f - fabsf(angle.y));
f = f*f;
- Vector4 color = current;
- color.a *= f;
-
- return color;
+ current.a *= f;
}
/**
- * @param[in] current The current position
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollWrap Whether scroll wrap has been enabled or not (WRAP)
+ * @param[in,out] current The current position
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * Whether scroll wrap has been enabled or not (SCROLL_WRAP)
* @return The new position of this Actor.
*/
- Vector3 PositionConstraint(const Vector3& current,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollWrap)
+ void PositionConstraint( Vector3& current, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
// Get position of page.
Vector3 relativePosition = pagePosition + scrollPosition;
// short circuit: for orthognal view.
if( (fabsf(relativePosition.x) < Math::MACHINE_EPSILON_1) && (fabsf(relativePosition.y) < Math::MACHINE_EPSILON_1) )
{
- return current + scrollPosition;
+ current += scrollPosition;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
- bool wrap = scrollWrap.GetBoolean();
+ const Vector3& pageSize = inputs[4]->GetVector3();
+ bool wrap = inputs[5]->GetBoolean();
if(wrap)
{
- const Vector3& min = scrollPositionMin.GetVector3();
- const Vector3& max = scrollPositionMax.GetVector3();
+ const Vector3& min = inputs[2]->GetVector3();
+ const Vector3& max = inputs[3]->GetVector3();
if(fabsf(min.x - max.x) > Math::MACHINE_EPSILON_1)
{
{
// position actors at: scrollposition (Property) + pagePosition (Parent) + current (this)
// they will be invisible so doesn't have to be precise, just away from stage.
- return current + scrollPosition;
+ current += scrollPosition;
+ return;
}
relativePosition.x /= pageSize.x;
position += mAnchor;
position += relativePosition * mPositionSwing;
- return position - pagePosition;
+ current = position - pagePosition;
}
Vector3 mAnchor; ///< Anchor point where Actor should rotate about.
{
// Apply constraints to this actor //
Constraint constraint;
- constraint = Constraint::New<Quaternion>( Actor::Property::ORIENTATION,
- Source(parentPage, Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::WRAP ),
- boost::bind( &ScrollCubeEffectInfo::RotationConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
-
+ constraint = Constraint::New<Quaternion>( child, Actor::Property::ORIENTATION, info, &ScrollCubeEffectInfo::RotationConstraint );
+ constraint.AddSource( Source(parentPage, Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::WRAP ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector4>( Actor::Property::COLOR,
- Source(parentPage, Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::WRAP ),
- boost::bind( &ScrollCubeEffectInfo::ColorConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
-
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector4>( child, Actor::Property::COLOR, info, &ScrollCubeEffectInfo::ColorConstraint );
+ constraint.AddSource( Source(parentPage, Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::WRAP ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- Source(parentPage, Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::WRAP ),
- boost::bind( &ScrollCubeEffectInfo::PositionConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
-
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector3>( child, Actor::Property::POSITION, info, &ScrollCubeEffectInfo::PositionConstraint );
+ constraint.AddSource( Source(parentPage, Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::WRAP ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
+ constraint.Apply();
}
} // unnamed namespace
*/
// EXTERNAL INCLUDES
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/property-input.h>
}
/**
- * @param[in] current The current scale
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollWrap Whether scroll wrap has been enabled or not (WRAP)
+ * @param[in,out] current The current scale
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * Whether scroll wrap has been enabled or not (SCROLL_WRAP)
* @return The new scale of this Actor.
*/
- Vector3 operator()(const Vector3& currentScale,
- const PropertyInput& currentPositionProperty,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty)
+ void operator()( Vector3& currentScale, const PropertyInputContainer& inputs )
{
- const Vector3& currentPosition = currentPositionProperty.GetVector3();
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
+ const Vector3& currentPosition = inputs[0]->GetVector3();
+ const Vector3& pagePosition = inputs[1]->GetVector3();
+ const Vector3& scrollPosition = inputs[2]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: for orthognal view.
if( (fabsf(position.x) < Math::MACHINE_EPSILON_1) && (fabsf(position.y) < Math::MACHINE_EPSILON_1) )
{
- return currentScale;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
+ const Vector3& pageSize = inputs[5]->GetVector3();
// Don't have enough parameters, to provide Wrap mode (need a way of having 'uniforms' instead of scrollWrap.GetBoolean())
- const Vector3& min = scrollPositionMin.GetVector3();
- const Vector3& max = scrollPositionMax.GetVector3();
+ const Vector3& min = inputs[3]->GetVector3();
+ const Vector3& max = inputs[4]->GetVector3();
if(fabsf(min.x - max.x) > Math::MACHINE_EPSILON_1)
{
// short circuit: for pages outside of view.
if( (fabsf(position.x) >= pageSize.x) || (fabsf(position.y) >= pageSize.y) )
{
- return currentScale;
+ return;
}
// Calculate scale ////////////////////////////////////////////////////////
float f = mScaleExtent + cos(position.x * Math::PI_2) * cos(position.y * Math::PI_2) * (1.0f - mScaleExtent);
- return currentScale * f;
+ currentScale *= f;
}
const Vector2 mPositionExtent; ///< Determines how much of the Actor's X and Y position affects exponent value.
}
/**
- * @param[in] current The current position
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollWrap Whether scroll wrap has been enabled or not (WRAP)
+ * @param[in,out] current The current position
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * Whether scroll wrap has been enabled or not (SCROLL_WRAP)
* @return The new position of this Actor.
*/
- Vector3 operator()(const Vector3& currentPosition,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollWrap)
+ void operator()( Vector3& currentPosition, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: for orthognal view.
if( (fabsf(position.x) < Math::MACHINE_EPSILON_1) && (fabsf(position.y) < Math::MACHINE_EPSILON_1) )
{
- return currentPosition + scrollPosition;
+ currentPosition += scrollPosition;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
- bool wrap = scrollWrap.GetBoolean();
+ const Vector3& pageSize = inputs[4]->GetVector3();
+ bool wrap = inputs[5]->GetBoolean();
if(wrap)
{
- const Vector3& min = scrollPositionMin.GetVector3();
- const Vector3& max = scrollPositionMax.GetVector3();
+ const Vector3& min = inputs[2]->GetVector3();
+ const Vector3& max = inputs[3]->GetVector3();
if(fabsf(min.x - max.x) > Math::MACHINE_EPSILON_1)
{
{
// position actors at: scrollposition (Property) + pagePosition (Parent) + current (this)
// they will be invisible so doesn't have to be precise, just away from stage.
- return currentPosition + scrollPosition;
+ currentPosition += scrollPosition;
+ return;
}
// Calculate position /////////////////////////////////////////////////////
position *= mPositionScale;
- Vector3 finalPosition(currentPosition - pagePosition);
-
Vector3 relCurrentPosition = currentPosition;
relCurrentPosition.x = relCurrentPosition.x / pageSize.x + 0.5f;
relCurrentPosition.y = relCurrentPosition.y / pageSize.y + 0.5f;
position.x = RampFunction(position.x, mOffsetExtent.x + extent.x);
position.y = RampFunction(position.y, mOffsetExtent.y + extent.y);
- finalPosition += pageSize * position;
-
- return finalPosition;
+ currentPosition -= pagePosition;
+ currentPosition += pageSize * position;
}
const Vector2 mPositionExtent; ///< Determines how much of the Actor's X and Y position affects exponent value.
float scaleExtent)
{
// Scale Constraint
- Constraint constraint = Constraint::New<Vector3>( Actor::Property::SCALE,
- LocalSource(Actor::Property::POSITION),
- ParentSource(Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_POSITION ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- ScrollDepthScaleConstraint( positionExtent, offsetExtent, positionScale, scaleExtent ) );
+ Constraint constraint = Constraint::New<Vector3>( child, Actor::Property::SCALE, ScrollDepthScaleConstraint( positionExtent, offsetExtent, positionScale, scaleExtent ) );
+ constraint.AddSource( LocalSource( Actor::Property::POSITION ) );
+ constraint.AddSource( ParentSource( Actor::Property::POSITION ) );
+ constraint.AddSource( Source( scrollView, Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ constraint.AddSource( Source( scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source( scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source( scrollView, Actor::Property::SIZE ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
+ constraint.Apply();
// Position Constraint (apply last as other constraints use Actor::POSITION as a function input)
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- ParentSource(Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_POSITION ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::WRAP ),
- ScrollDepthPositionConstraint( positionExtent, offsetExtent, positionScale ) );
-
+ constraint = Constraint::New<Vector3>( child, Actor::Property::POSITION, ScrollDepthPositionConstraint( positionExtent, offsetExtent, positionScale ) );
+ constraint.AddSource( ParentSource(Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::WRAP ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
+ constraint.Apply();
}
} // unnamed namespace
* scroll domain. This is a value from 0.0f to 1.0f in each
* scroll position axis.
*/
-Vector3 InternalRelativePositionConstraint(const Vector3& current,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollMinProperty,
- const PropertyInput& scrollMaxProperty,
- const PropertyInput& scrollSizeProperty)
+void InternalRelativePositionConstraint( Vector3& relativePosition, const PropertyInputContainer& inputs)
{
- Vector3 position = -scrollPositionProperty.GetVector3();
- const Vector3& min = scrollMinProperty.GetVector3();
- const Vector3& max = scrollMaxProperty.GetVector3();
- const Vector3& size = scrollSizeProperty.GetVector3();
+ Vector3 position = -inputs[0]->GetVector3();
+ const Vector3& min = inputs[1]->GetVector3();
+ const Vector3& max = inputs[2]->GetVector3();
+ const Vector3& size = inputs[3]->GetVector3();
position.x = WrapInDomain(position.x, min.x, max.x);
position.y = WrapInDomain(position.y, min.y, max.y);
- Vector3 relativePosition;
Vector3 domainSize = (max - min) - size;
relativePosition.x = domainSize.x > Math::MACHINE_EPSILON_1 ? fabsf((position.x - min.x) / domainSize.x) : 0.0f;
relativePosition.y = domainSize.y > Math::MACHINE_EPSILON_1 ? fabsf((position.y - min.y) / domainSize.y) : 0.0f;
-
- return relativePosition;
+ relativePosition.z = 0.0f;
}
} // unnamed namespace
{
}
- Vector3 operator()(const Vector3& current,
- const PropertyInput& gesturePositionProperty,
- const PropertyInput& sizeProperty)
+ void operator()( Vector3& scrollPostPosition, const PropertyInputContainer& inputs )
{
- Vector3 scrollPostPosition = current;
- Vector2 panPosition = gesturePositionProperty.GetVector2();
+ const Vector2& panPosition = inputs[0]->GetVector2();
if(!mWasPanning)
{
- mPrePosition = current;
+ mPrePosition = scrollPostPosition;
mCurrentPanMask = mInitialPanMask;
mWasPanning = true;
}
// Calculate Deltas...
- Vector2 currentPosition = gesturePositionProperty.GetVector2();
+ const Vector2& currentPosition = panPosition;
Vector2 panDelta( currentPosition - mLocalStart );
// Axis Auto Lock - locks the panning to the horizontal or vertical axis if the pan
scrollPostPosition.GetVectorXY() += panDelta;
// if no wrapping then clamp preposition to maximum overshoot amount
- const Vector3& size = sizeProperty.GetVector3();
+ const Vector3& size = inputs[1]->GetVector3();
if( mClampX )
{
float newXPosition = Clamp(scrollPostPosition.x, (mDomainMax.x + size.x) - mMaxOvershoot.x, mDomainMin.x + mMaxOvershoot.x );
}
scrollPostPosition.y = newYPosition;
}
-
- return scrollPostPosition;
}
Vector3 mPrePosition;
{
}
- Vector3 operator()(const Vector3& current,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollMinProperty,
- const PropertyInput& scrollMaxProperty,
- const PropertyInput& scrollSizeProperty)
+ void operator()( Vector3& position, const PropertyInputContainer& inputs )
{
- Vector3 position = scrollPositionProperty.GetVector3();
- const Vector2& size = scrollSizeProperty.GetVector3().GetVectorXY();
- const Vector3& min = scrollMinProperty.GetVector3();
- const Vector3& max = scrollMaxProperty.GetVector3();
+ position = inputs[0]->GetVector3();
+ const Vector2& size = inputs[3]->GetVector3().GetVectorXY();
+ const Vector3& min = inputs[1]->GetVector3();
+ const Vector3& max = inputs[2]->GetVector3();
if( mWrap )
{
position.x = mClampX ? Clamp(position.x, mDomainMax.x + size.x, mDomainMin.x ) : position.x;
position.y = mClampY ? Clamp(position.y, mDomainMax.y + size.y, mDomainMin.y ) : position.y;
}
-
- return position;
}
Vector2 mDomainMin;
{
OvershootXConstraint(float maxOvershoot) : mMaxOvershoot(maxOvershoot) {}
- float operator()(const float& current,
- const PropertyInput& scrollPrePositionProperty,
- const PropertyInput& scrollPostPositionProperty,
- const PropertyInput& canScrollProperty)
+ void operator()( float& current, const PropertyInputContainer& inputs )
{
- if( canScrollProperty.GetBoolean() )
+ if( inputs[2]->GetBoolean() )
{
- const Vector3& scrollPrePosition = scrollPrePositionProperty.GetVector3();
- const Vector3& scrollPostPosition = scrollPostPositionProperty.GetVector3();
+ const Vector3& scrollPrePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPostPosition = inputs[1]->GetVector3();
float newOvershoot = scrollPrePosition.x - scrollPostPosition.x;
- return (newOvershoot > 0.0f ? std::min(newOvershoot, mMaxOvershoot) : std::max(newOvershoot, -mMaxOvershoot)) / mMaxOvershoot;
+ current = (newOvershoot > 0.0f ? std::min(newOvershoot, mMaxOvershoot) : std::max(newOvershoot, -mMaxOvershoot)) / mMaxOvershoot;
+ }
+ else
+ {
+ current = 0.0f;
}
- return 0.0f;
}
float mMaxOvershoot;
{
OvershootYConstraint(float maxOvershoot) : mMaxOvershoot(maxOvershoot) {}
- float operator()(const float& current,
- const PropertyInput& scrollPrePositionProperty,
- const PropertyInput& scrollPostPositionProperty,
- const PropertyInput& canScrollProperty)
+ void operator()( float& current, const PropertyInputContainer& inputs )
{
- if( canScrollProperty.GetBoolean() )
+ if( inputs[2]->GetBoolean() )
{
- const Vector3& scrollPrePosition = scrollPrePositionProperty.GetVector3();
- const Vector3& scrollPostPosition = scrollPostPositionProperty.GetVector3();
+ const Vector3& scrollPrePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPostPosition = inputs[1]->GetVector3();
float newOvershoot = scrollPrePosition.y - scrollPostPosition.y;
- return (newOvershoot > 0.0f ? std::min(newOvershoot, mMaxOvershoot) : std::max(newOvershoot, -mMaxOvershoot)) / mMaxOvershoot;
+ current = (newOvershoot > 0.0f ? std::min(newOvershoot, mMaxOvershoot) : std::max(newOvershoot, -mMaxOvershoot)) / mMaxOvershoot;
+ }
+ else
+ {
+ current = 0.0f;
}
- return 0.0f;
}
float mMaxOvershoot;
*
* Generates position-delta property based on scroll-position + scroll-offset properties.
*/
-Vector3 InternalPositionDeltaConstraint(const Vector3& current,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollOffsetProperty)
+void InternalPositionDeltaConstraint( Vector3& current, const PropertyInputContainer& inputs )
{
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
- const Vector3& scrollOffset = scrollOffsetProperty.GetVector3();
+ const Vector3& scrollPosition = inputs[0]->GetVector3();
+ const Vector3& scrollOffset = inputs[1]->GetVector3();
- return scrollPosition + scrollOffset;
+ current = scrollPosition + scrollOffset;
}
/**
{
}
- Vector3 operator()(const Vector3& current,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollOvershootXProperty,
- const PropertyInput& scrollOvershootYProperty)
+ void operator()( Vector3& current, const PropertyInputContainer& inputs )
{
- const float& overshootx = scrollOvershootXProperty.GetFloat();
- const float& overshooty = scrollOvershootYProperty.GetFloat();
+ const float& overshootx = inputs[1]->GetFloat();
+ const float& overshooty = inputs[2]->GetFloat();
Vector3 offset( mFunctionX(overshootx),
mFunctionY(overshooty),
0.0f);
- return scrollPositionProperty.GetVector3() - offset;
+ current = inputs[0]->GetVector3() - offset;
}
AlphaFunction mFunctionX;
mInternalActor = Actor::New();
mInternalActor.SetDrawMode(DrawMode::OVERLAY);
self.Add(mInternalActor);
- mInternalActor.ApplyConstraint( Constraint::New<Vector3>( Actor::Property::SIZE, ParentSource( Actor::Property::SIZE ), EqualToConstraint() ) );
+ Constraint constraint = Constraint::New<Vector3>( mInternalActor, Actor::Property::SIZE, EqualToConstraint() );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.Apply();
mInternalActor.SetParentOrigin(ParentOrigin::CENTER);
mInternalActor.SetAnchorPoint(AnchorPoint::CENTER);
if( mScrollMainInternalPrePositionConstraint )
{
- self.RemoveConstraint(mScrollMainInternalPrePositionConstraint);
+ mScrollMainInternalPrePositionConstraint.Remove();
}
}
if( mScrollMainInternalPrePositionConstraint )
{
- self.RemoveConstraint(mScrollMainInternalPrePositionConstraint);
+ mScrollMainInternalPrePositionConstraint.Remove();
}
if( mOvershootIndicator )
if(mScrollMainInternalPositionConstraint)
{
- self.RemoveConstraint(mScrollMainInternalPositionConstraint);
- self.RemoveConstraint(mScrollMainInternalDeltaConstraint);
- self.RemoveConstraint(mScrollMainInternalFinalConstraint);
- self.RemoveConstraint(mScrollMainInternalRelativeConstraint);
+ mScrollMainInternalPositionConstraint.Remove();
+ mScrollMainInternalDeltaConstraint.Remove();
+ mScrollMainInternalFinalConstraint.Remove();
+ mScrollMainInternalRelativeConstraint.Remove();
}
if( mScrollMainInternalPrePositionConstraint )
{
- self.RemoveConstraint(mScrollMainInternalPrePositionConstraint);
+ mScrollMainInternalPrePositionConstraint.Remove();
}
// TODO: It's probably better to use a local displacement value as this will give a displacement when scrolling just commences
{
initialPanMask.x = 0.0f;
}
- Constraint constraint;
if( mPanning )
{
- constraint = Constraint::New<Vector3>( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION,
- Source( detector, PanGestureDetector::Property::LOCAL_POSITION ),
- Source( self, Actor::Property::SIZE ),
- InternalPrePositionConstraint( mPanStartPosition, initialPanMask, mAxisAutoLock, mAxisAutoLockGradient, mLockAxis, mMaxOvershoot, mRulerX->GetDomain(), mRulerY->GetDomain() ) );
- mScrollMainInternalPrePositionConstraint = self.ApplyConstraint( constraint );
+ mScrollMainInternalPrePositionConstraint = Constraint::New<Vector3>( self,
+ Toolkit::ScrollView::Property::SCROLL_PRE_POSITION,
+ InternalPrePositionConstraint( mPanStartPosition,
+ initialPanMask,
+ mAxisAutoLock,
+ mAxisAutoLockGradient,
+ mLockAxis,
+ mMaxOvershoot,
+ mRulerX->GetDomain(),
+ mRulerY->GetDomain() ) );
+ mScrollMainInternalPrePositionConstraint.AddSource( Source( detector, PanGestureDetector::Property::LOCAL_POSITION ) );
+ mScrollMainInternalPrePositionConstraint.AddSource( Source( self, Actor::Property::SIZE ) );
+ mScrollMainInternalPrePositionConstraint.Apply();
}
// 2. Second calculate the clamped position (actual position)
- constraint = Constraint::New<Vector3>( Toolkit::ScrollView::Property::SCROLL_POSITION,
- LocalSource( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ),
- LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source( self, Actor::Property::SIZE ),
- InternalPositionConstraint( mRulerX->GetDomain(),
- mRulerY->GetDomain(), mWrapMode ) );
- mScrollMainInternalPositionConstraint = self.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector3>( Toolkit::ScrollView::Property::SCROLL_POSITION_DELTA,
- LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ),
- LocalSource( Toolkit::ScrollView::Property::SCROLL_DOMAIN_OFFSET ),
- InternalPositionDeltaConstraint );
- mScrollMainInternalDeltaConstraint = self.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector3>( Toolkit::ScrollView::Property::SCROLL_FINAL,
- LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ),
- LocalSource( Toolkit::ScrollView::Property::OVERSHOOT_X ),
- LocalSource( Toolkit::ScrollView::Property::OVERSHOOT_Y ),
- InternalFinalConstraint( FinalDefaultAlphaFunction,
- FinalDefaultAlphaFunction ) );
- mScrollMainInternalFinalConstraint = self.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector3>( Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION,
- LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ),
- LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- LocalSource( Actor::Property::SIZE ),
- InternalRelativePositionConstraint );
- mScrollMainInternalRelativeConstraint = self.ApplyConstraint( constraint );
+ mScrollMainInternalPositionConstraint = Constraint::New<Vector3>( self,
+ Toolkit::ScrollView::Property::SCROLL_POSITION,
+ InternalPositionConstraint( mRulerX->GetDomain(),
+ mRulerY->GetDomain(),
+ mWrapMode ) );
+ mScrollMainInternalPositionConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ) );
+ mScrollMainInternalPositionConstraint.AddSource( LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ mScrollMainInternalPositionConstraint.AddSource( LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ mScrollMainInternalPositionConstraint.AddSource( Source( self, Actor::Property::SIZE ) );
+ mScrollMainInternalPositionConstraint.Apply();
+
+ mScrollMainInternalDeltaConstraint = Constraint::New<Vector3>( self, Toolkit::ScrollView::Property::SCROLL_POSITION_DELTA, InternalPositionDeltaConstraint );
+ mScrollMainInternalDeltaConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ mScrollMainInternalDeltaConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_DOMAIN_OFFSET ) );
+ mScrollMainInternalDeltaConstraint.Apply();
+
+ mScrollMainInternalFinalConstraint = Constraint::New<Vector3>( self, Toolkit::ScrollView::Property::SCROLL_FINAL,
+ InternalFinalConstraint( FinalDefaultAlphaFunction,
+ FinalDefaultAlphaFunction ) );
+ mScrollMainInternalFinalConstraint .AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ mScrollMainInternalFinalConstraint .AddSource( LocalSource( Toolkit::ScrollView::Property::OVERSHOOT_X ) );
+ mScrollMainInternalFinalConstraint .AddSource( LocalSource( Toolkit::ScrollView::Property::OVERSHOOT_Y ) );
+ mScrollMainInternalFinalConstraint.Apply();
+
+ mScrollMainInternalRelativeConstraint = Constraint::New<Vector3>( self, Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION, InternalRelativePositionConstraint );
+ mScrollMainInternalRelativeConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ mScrollMainInternalRelativeConstraint.AddSource( LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ mScrollMainInternalRelativeConstraint.AddSource( LocalSource( Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ mScrollMainInternalRelativeConstraint.AddSource( LocalSource( Actor::Property::SIZE ) );
+ mScrollMainInternalRelativeConstraint.Apply();
// When panning we want to make sure overshoot values are affected by pre position and post position
SetOvershootConstraintsEnabled(!mWrapMode);
// remove and reset, it may now be in wrong order with the main internal constraints
if( mScrollMainInternalOvershootXConstraint )
{
- self.RemoveConstraint(mScrollMainInternalOvershootXConstraint);
+ mScrollMainInternalOvershootXConstraint.Remove();
mScrollMainInternalOvershootXConstraint.Reset();
- self.RemoveConstraint(mScrollMainInternalOvershootYConstraint);
+ mScrollMainInternalOvershootYConstraint.Remove();
mScrollMainInternalOvershootYConstraint.Reset();
}
if( enabled )
{
- Constraint constraint = Constraint::New<float>( Toolkit::ScrollView::Property::OVERSHOOT_X,
- LocalSource( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ),
- LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ),
- LocalSource( Toolkit::Scrollable::Property::CAN_SCROLL_HORIZONTAL ),
- OvershootXConstraint(mMaxOvershoot.x) );
- mScrollMainInternalOvershootXConstraint = self.ApplyConstraint( constraint );
+ mScrollMainInternalOvershootXConstraint= Constraint::New<float>( self, Toolkit::ScrollView::Property::OVERSHOOT_X, OvershootXConstraint(mMaxOvershoot.x) );
+ mScrollMainInternalOvershootXConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ) );
+ mScrollMainInternalOvershootXConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ mScrollMainInternalOvershootXConstraint.AddSource( LocalSource( Toolkit::Scrollable::Property::CAN_SCROLL_HORIZONTAL ) );
+ mScrollMainInternalOvershootXConstraint.Apply();
- constraint = Constraint::New<float>( Toolkit::ScrollView::Property::OVERSHOOT_Y,
- LocalSource( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ),
- LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ),
- LocalSource( Toolkit::Scrollable::Property::CAN_SCROLL_VERTICAL ),
- OvershootYConstraint(mMaxOvershoot.y) );
- mScrollMainInternalOvershootYConstraint = self.ApplyConstraint( constraint );
+ mScrollMainInternalOvershootYConstraint = Constraint::New<float>( self, Toolkit::ScrollView::Property::OVERSHOOT_Y, OvershootYConstraint(mMaxOvershoot.y) );
+ mScrollMainInternalOvershootYConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_PRE_POSITION ) );
+ mScrollMainInternalOvershootYConstraint.AddSource( LocalSource( Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ mScrollMainInternalOvershootYConstraint.AddSource( LocalSource( Toolkit::Scrollable::Property::CAN_SCROLL_VERTICAL ) );
+ mScrollMainInternalOvershootYConstraint.Apply();
}
else
{
Constraint constraint;
// MoveActor (scrolling)
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- Source( self, Toolkit::ScrollView::Property::SCROLL_POSITION ),
- MoveActorConstraint );
+ constraint = Constraint::New<Vector3>( self, Actor::Property::POSITION, MoveActorConstraint );
+ constraint.AddSource( Source( self, Toolkit::ScrollView::Property::SCROLL_POSITION ) );
constraint.SetRemoveAction(Constraint::Discard);
ApplyConstraintToBoundActors(constraint);
// WrapActor (wrap functionality)
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- LocalSource( Actor::Property::SCALE ),
- LocalSource( Actor::Property::ANCHOR_POINT ),
- LocalSource( Actor::Property::SIZE ),
- Source( self, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source( self, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source( self, Toolkit::ScrollView::Property::WRAP ),
- WrapActorConstraint );
+ constraint = Constraint::New<Vector3>( self, Actor::Property::POSITION, WrapActorConstraint );
+ constraint.AddSource( LocalSource( Actor::Property::SCALE ) );
+ constraint.AddSource( LocalSource( Actor::Property::ANCHOR_POINT ) );
+ constraint.AddSource( LocalSource( Actor::Property::SIZE ) );
+ constraint.AddSource( Source( self, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source( self, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source( self, Toolkit::ScrollView::Property::WRAP ) );
constraint.SetRemoveAction(Constraint::Discard);
ApplyConstraintToBoundActors(constraint);
}
Vector2 mMouseWheelScrollDistanceStep; ///< The step of scroll distance in actor coordinates in X and Y axes for each mouse wheel event received.
//ScrollInternalConstraintsPtr mScrollInternalConstraints;
- ActiveConstraint mScrollMainInternalPrePositionConstraint;
- ActiveConstraint mScrollMainInternalPositionConstraint;
- ActiveConstraint mScrollMainInternalOvershootXConstraint;
- ActiveConstraint mScrollMainInternalOvershootYConstraint;
- ActiveConstraint mScrollMainInternalDeltaConstraint;
- ActiveConstraint mScrollMainInternalFinalConstraint;
- ActiveConstraint mScrollMainInternalRelativeConstraint;
+ Constraint mScrollMainInternalPrePositionConstraint;
+ Constraint mScrollMainInternalPositionConstraint;
+ Constraint mScrollMainInternalOvershootXConstraint;
+ Constraint mScrollMainInternalOvershootYConstraint;
+ Constraint mScrollMainInternalDeltaConstraint;
+ Constraint mScrollMainInternalFinalConstraint;
+ Constraint mScrollMainInternalRelativeConstraint;
ScrollOvershootIndicatorPtr mOvershootIndicator;
#include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-page-carousel-effect-impl.h>
// EXTERNAL INCLUDES
-#include <boost/bind.hpp>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/property-input.h>
}
/**
- * @param[in] current The current color of this Actor
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollWrap Whether scroll wrap has been enabled or not (WRAP)
+ * @param[in,out] current The current color of this Actor
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * Whether scroll wrap has been enabled or not (SCROLL_WRAP)
* @return The new color of this Actor.
*/
- Vector4 ColorConstraint(const Vector4& current,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollWrap)
+ void ColorConstraint( Vector4& current, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: if we're looking straight on at the page.
if( IsStraightOnView( position ) )
{
- return current;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
+ const Vector3& pageSize = inputs[4]->GetVector3();
- if( scrollWrap.GetBoolean() )
+ if( inputs[5]->GetBoolean() )
{
- WrapPositionWithinDomain( position, pageSize, scrollPositionMin.GetVector3(), scrollPositionMax.GetVector3() );
+ WrapPositionWithinDomain( position, pageSize, inputs[2]->GetVector3(), inputs[3]->GetVector3() );
}
// short circuit: for pages outside of view.
{
// note preserve color channels incase there is a shader/further constraint
// that wishes to do something with that information.
- return Vector4(current.r, current.g, current.b, 0.0f);
+ current.a = 0.0f;
+ return;
}
- Vector4 color( current );
Vector2 distance( position / pageSize * PAGE_SIZE_MULTIPLIER );
- color.a = Clamp( 1.0f - distance.Length(), 0.0f, 1.0f );
-
- return color;
+ current.a = Clamp( 1.0f - distance.Length(), 0.0f, 1.0f );
}
/**
- * @param[in] current The current position
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollWrap Whether scroll wrap has been enabled or not (WRAP)
+ * @param[in,out] current The current position
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * Whether scroll wrap has been enabled or not (SCROLL_WRAP)
* @return The new position of this Actor.
*/
- Vector3 PositionConstraint(const Vector3& current,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollWrap)
+ void PositionConstraint( Vector3& current, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: if we're looking straight on at the page.
if( IsStraightOnView( position ) )
{
- return current + scrollPosition;
+ current += scrollPosition;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
+ const Vector3& pageSize = inputs[4]->GetVector3();
- if( scrollWrap.GetBoolean() )
+ if( inputs[5]->GetBoolean() )
{
- WrapPositionWithinDomain( position, pageSize, scrollPositionMin.GetVector3(), scrollPositionMax.GetVector3() );
+ WrapPositionWithinDomain( position, pageSize, inputs[2]->GetVector3(), inputs[3]->GetVector3() );
}
// short circuit: for pages outside of view.
{
// position actors at: scrollposition (Property) + pagePosition (Parent) + current (this)
// they will be invisible so doesn't have to be precise, just away from stage.
- return current + scrollPosition;
+ current += scrollPosition;
+ return;
}
Vector3 angle( position / pageSize * PAGE_SIZE_MULTIPLIER );
zMovement *= mPositionToPageSizeRatio;
position.z = - ( ( zMovement.x - ( zMovement.x * cos( angle.x ) ) ) + ( zMovement.y - ( zMovement.y * cos( angle.y ) ) ) );
- return position;
+ current = position;
}
const Vector2 mPositionToPageSizeRatio; ///< The page will move its position according to this ratio.
{
// Apply constraints to this actor //
Constraint constraint;
- constraint = Constraint::New<Vector4>( Actor::Property::COLOR,
- LocalSource(Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::WRAP ),
- boost::bind( &ScrollPageCarouselEffectInfo::ColorConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
-
+ constraint = Constraint::New<Vector4>( child, Actor::Property::COLOR, info, &ScrollPageCarouselEffectInfo::ColorConstraint );
+ constraint.AddSource( LocalSource(Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::WRAP ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- LocalSource(Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::WRAP ),
- boost::bind( &ScrollPageCarouselEffectInfo::PositionConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
-
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector3>( child, Actor::Property::POSITION, info, &ScrollPageCarouselEffectInfo::PositionConstraint );
+ constraint.AddSource( LocalSource(Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::WRAP ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
+ constraint.Apply();
}
} // unnamed namespace
#include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-page-cube-effect-impl.h>
// EXTERNAL INCLUDES
-#include <boost/bind.hpp>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/property-input.h>
}
/**
- * @param[in] current The current orientation of this Actor
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollWrap Whether scroll wrap has been enabled or not (WRAP)
+ * @param[in,out] current The current orientation of this Actor
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * Whether scroll wrap has been enabled or not (SCROLL_WRAP)
* @return The new orientation of this Actor.
*/
- Quaternion RotationConstraint(const Quaternion& current,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollWrap)
+ void RotationConstraint( Quaternion& current, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: if we're looking straight on at the page.
if( IsStraightOnView( position ) )
{
- return current;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
+ const Vector3& pageSize = inputs[4]->GetVector3();
- if( scrollWrap.GetBoolean() )
+ if( inputs[5]->GetBoolean() )
{
- WrapPositionWithinDomain( position, pageSize, scrollPositionMin.GetVector3(), scrollPositionMax.GetVector3() );
+ WrapPositionWithinDomain( position, pageSize, inputs[2]->GetVector3(), inputs[3]->GetVector3() );
}
// short circuit: for pages outside of view.
if( IsOutsideView( position, pageSize ) )
{
- return current;
+ return;
}
// Our target is a 90 degree (PI/2) rotation per page, so calculate the angle we should be rotate
// our page by calculating the amount we've moved as a fraction of the total size of the page.
Vector2 angle( position / pageSize * Dali::Math::PI_2 );
- Quaternion rotation = Quaternion( -angle.x * mAngleSwing.x, Vector3::YAXIS ) *
- Quaternion( angle.y * mAngleSwing.y, Vector3::XAXIS ) *
- current;
-
- return rotation;
+ current = Quaternion( -angle.x * mAngleSwing.x, Vector3::YAXIS ) *
+ Quaternion( angle.y * mAngleSwing.y, Vector3::XAXIS ) *
+ current;
}
/**
- * @param[in] current The current color of this Actor
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollWrap Whether scroll wrap has been enabled or not (WRAP)
+ * @param[in,out] current The current color of this Actor
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * Whether scroll wrap has been enabled or not (SCROLL_WRAP)
* @return The new color of this Actor.
*/
- Vector4 ColorConstraint(const Vector4& current,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollWrap)
+ void ColorConstraint( Vector4& current, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: if we're looking straight on at the page.
if( IsStraightOnView( position ) )
{
- return current;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
+ const Vector3& pageSize = inputs[4]->GetVector3();
- if( scrollWrap.GetBoolean() )
+ if( inputs[5]->GetBoolean() )
{
- WrapPositionWithinDomain( position, pageSize, scrollPositionMin.GetVector3(), scrollPositionMax.GetVector3() );
+ WrapPositionWithinDomain( position, pageSize, inputs[2]->GetVector3(), inputs[3]->GetVector3() );
}
// short circuit: for pages outside of view.
{
// note preserve color channels incase there is a shader/further constraint
// that wishes to do something with that information.
- return Vector4(current.r, current.g, current.b, 0.0f);
+ current.a = 0.0f;
+ return;
}
// Calculate the distance of this page from our view and ensure it falls within the appropriate
if ( distanceFactor > 1.0f )
{
- return Vector4(current.r, current.g, current.b, 0.0f);
+ current.a = 0.0f;
}
-
- return current;
}
/**
- * @param[in] current The current position
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollWrap Whether scroll wrap has been enabled or not (WRAP)
+ * @param[in,out] current The current position
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * Whether scroll wrap has been enabled or not (SCROLL_WRAP)
* @return The new position of this Actor.
*/
- Vector3 PositionConstraint(const Vector3& current,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollWrap)
+ void PositionConstraint( Vector3& current, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: if we're looking straight on at the page.
if( IsStraightOnView( position ) )
{
- return current + scrollPosition;
+ current += scrollPosition;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
+ const Vector3& pageSize = inputs[4]->GetVector3();
- if( scrollWrap.GetBoolean() )
+ if( inputs[5]->GetBoolean() )
{
- WrapPositionWithinDomain( position, pageSize, scrollPositionMin.GetVector3(), scrollPositionMax.GetVector3() );
+ WrapPositionWithinDomain( position, pageSize, inputs[2]->GetVector3(), inputs[3]->GetVector3() );
}
// short circuit: for pages outside of view.
{
// position actors at: scrollposition (Property) + pagePosition (Parent) + current (this)
// they will be invisible so doesn't have to be precise, just away from stage.
- return current + scrollPosition;
+ current += scrollPosition;
+ return;
}
// Our target when scrolling is moving from the origin to the following points around a curve:
Vector2 angle( position / pageSize * Dali::Math::PI_2 );
Vector2 radius( pageSize * 0.5 );
- position.x = radius.x * sin( angle.x );
- position.y = radius.y * sin( angle.y );
- position.z = ( radius.x - ( radius.x * cos( angle.x ) ) ) + ( radius.y - ( radius.y * cos( angle.y ) ) );
-
- return position;
+ current.x = radius.x * sin( angle.x );
+ current.y = radius.y * sin( angle.y );
+ current.z = ( radius.x - ( radius.x * cos( angle.x ) ) ) + ( radius.y - ( radius.y * cos( angle.y ) ) );
}
Vector2 mAngleSwing; ///< Maximum amount in X and Y axes to rotate.
{
// Apply constraints to this actor //
Constraint constraint;
- constraint = Constraint::New<Quaternion>( Actor::Property::ORIENTATION,
- LocalSource(Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::WRAP ),
- boost::bind( &ScrollPageCubeEffectInfo::RotationConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
-
+ constraint = Constraint::New<Quaternion>( child, Actor::Property::ORIENTATION, info, &ScrollPageCubeEffectInfo::RotationConstraint );
+ constraint.AddSource( LocalSource(Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::WRAP ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector4>( Actor::Property::COLOR,
- LocalSource(Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::WRAP ),
- boost::bind( &ScrollPageCubeEffectInfo::ColorConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
-
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector4>( child, Actor::Property::COLOR, info, &ScrollPageCubeEffectInfo::ColorConstraint );
+ constraint.AddSource( LocalSource(Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::WRAP ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- LocalSource(Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::WRAP ),
- boost::bind( &ScrollPageCubeEffectInfo::PositionConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
-
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector3>( child, Actor::Property::POSITION, info, &ScrollPageCubeEffectInfo::PositionConstraint );
+ constraint.AddSource( LocalSource(Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::WRAP ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
+ constraint.Apply();
}
} // unnamed namespace
// CLASS HEADER
#include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-page-spiral-effect-impl.h>
-// EXTERNAL INCLUDES
-#include <boost/bind.hpp>
-
// INTERNAL INCLUDES
#include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-helper-functions.h>
#include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h>
}
/**
- * @param[in] current The current orientation of this Actor
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollPageStartPositionProperty The position of the page where scrolling started. (START_PAGE_POSITION)
+ * @param[in,out] current The current orientation of this Actor
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * The position of the page where scrolling started. (SCROLL_START_PAGE_POSITION)
* @return The new orientation of this Actor.
*/
- Quaternion RotationConstraint(const Quaternion& current,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollStartPagePositionProperty)
+ void RotationConstraint( Quaternion& current, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
- const Vector3& scrollStartPagePosition = scrollStartPagePositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
+ const Vector3& scrollStartPagePosition = inputs[5]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: if we're looking straight on at the page.
if( IsStraightOnView( position ) )
{
- return current;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
- const Vector3& minScrollPosition( scrollPositionMin.GetVector3() );
- const Vector3& maxScrollPosition( scrollPositionMax.GetVector3() );
+ const Vector3& pageSize = inputs[4]->GetVector3();
+ const Vector3& minScrollPosition( inputs[2]->GetVector3() );
+ const Vector3& maxScrollPosition( inputs[3]->GetVector3() );
if( mScrollWrap )
{
// short circuit: for pages outside of view.
if( IsOutsideView( position, pageSize ) )
{
- return current;
+ return;
}
Vector2 angle( position / ( pageSize * PAGE_SIZE_RELATIVE_ANGLE_FACTOR ) * Vector3( mSpiralAngle ) );
}
ClampInPlace( angle.y, -angleMaxMin.y, angleMaxMin.y );
- Quaternion rotation = Quaternion( angle.x, Vector3::YAXIS ) *
- Quaternion( angle.y, Vector3::XAXIS ) *
- current;
-
- return rotation;
+ current = Quaternion( angle.x, Vector3::YAXIS ) *
+ Quaternion( angle.y, Vector3::XAXIS ) *
+ current;
}
/**
- * @param[in] current The current color of this Actor
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollPageStartPositionProperty The position of the page where scrolling started. (START_PAGE_POSITION)
+ * @param[in,out] current The current color of this Actor
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * The position of the page where scrolling started. (SCROLL_START_PAGE_POSITION)
* @return The new color of this Actor.
*/
- Vector4 ColorConstraint(const Vector4& current,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollStartPagePositionProperty)
+ void ColorConstraint( Vector4& color, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
- const Vector3& scrollStartPagePosition = scrollStartPagePositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
+ const Vector3& scrollStartPagePosition = inputs[5]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: if we're looking straight on at the page.
if( IsStraightOnView( position ) )
{
- return current;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
- const Vector3& minScrollPosition( scrollPositionMin.GetVector3() );
- const Vector3& maxScrollPosition( scrollPositionMax.GetVector3() );
+ const Vector3& pageSize = inputs[4]->GetVector3();
+ const Vector3& minScrollPosition( inputs[2]->GetVector3() );
+ const Vector3& maxScrollPosition( inputs[3]->GetVector3() );
if( mScrollWrap )
{
{
// note preserve color channels incase there is a shader/further constraint
// that wishes to do something with that information.
- return Vector4(current.r, current.g, current.b, 0.0f);
+ color.a = 0.0f;
+ return;
}
- Vector4 color( current );
Vector2 distance( position / pageSize );
float distanceLength( distance.Length() );
const Vector2 epsilon( pageSize * PAGE_EPSILON_FACTOR );
{
color.a = 0.0f;
}
-
- return color;
}
/**
- * @param[in] current The current position
- * @param[in] pagePositionProperty The page's position.
- * @param[in] scrollPositionProperty The scroll-view's position property (SCROLL_POSITION)
- * @param[in] scrollPositionMin The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
- * @param[in] scrollPositionMax The maximum extent of this scroll domain. (SCROLL_POSITION_MAX)
- * @param[in] pageSizeProperty The size of the page. (scrollView SIZE)
- * @param[in] scrollPageStartPositionProperty The position of the page where scrolling started. (START_PAGE_POSITION)
+ * @param[in,out] current The current position
+ * @param[in] inputs Contains:
+ * The page's position.
+ * The scroll-view's position property (SCROLL_POSITION)
+ * The minimum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The maximum extent of this scroll domain. (SCROLL_POSITION_MIN)
+ * The size of the page. (scrollView SIZE)
+ * The position of the page where scrolling started. (SCROLL_START_PAGE_POSITION)
* @return The new position of this Actor.
*/
- Vector3 PositionConstraint(const Vector3& current,
- const PropertyInput& pagePositionProperty,
- const PropertyInput& scrollPositionProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& pageSizeProperty,
- const PropertyInput& scrollStartPagePositionProperty)
+ void PositionConstraint( Vector3& current, const PropertyInputContainer& inputs )
{
- const Vector3& pagePosition = pagePositionProperty.GetVector3();
- const Vector3& scrollPosition = scrollPositionProperty.GetVector3();
- const Vector3& scrollStartPagePosition = scrollStartPagePositionProperty.GetVector3();
+ const Vector3& pagePosition = inputs[0]->GetVector3();
+ const Vector3& scrollPosition = inputs[1]->GetVector3();
+ const Vector3& scrollStartPagePosition = inputs[5]->GetVector3();
// Get position of page.
Vector3 position = pagePosition + scrollPosition;
// short circuit: if we're looking straight on at the page.
if( IsStraightOnView( position ) )
{
- return current + scrollPosition;
+ current += scrollPosition;
+ return;
}
- const Vector3& pageSize = pageSizeProperty.GetVector3();
- const Vector3& minScrollPosition( scrollPositionMin.GetVector3() );
- const Vector3& maxScrollPosition( scrollPositionMax.GetVector3() );
+ const Vector3& pageSize = inputs[4]->GetVector3();
+ const Vector3& minScrollPosition( inputs[2]->GetVector3() );
+ const Vector3& maxScrollPosition( inputs[3]->GetVector3() );
if( mScrollWrap )
{
{
// position actors at: scrollposition (Property) + pagePosition (Parent) + current (this)
// they will be invisible so doesn't have to be precise, just away from stage.
- return current + scrollPosition;
+ current += scrollPosition;
+ return;
}
const Vector2 angle( position / pageSize * ( Dali::Math::PI_4 ) );
position.z += fabsf( position.y ) * NON_SCROLL_PAGE_Z_POSITION_FACTOR;
}
- return position;
+ current = position;
}
Vector2 mSpiralAngle; ///< The angle of the spirald page
{
// Apply constraints to this actor //
Constraint constraint;
- constraint = Constraint::New<Quaternion>( Actor::Property::ORIENTATION,
- LocalSource(Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::START_PAGE_POSITION ),
- boost::bind( &ScrollPageSpiralEffectInfo::RotationConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
-
+ constraint = Constraint::New<Quaternion>( child, Actor::Property::ORIENTATION, info, &ScrollPageSpiralEffectInfo::RotationConstraint );
+ constraint.AddSource( LocalSource(Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::START_PAGE_POSITION ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector4>( Actor::Property::COLOR,
- LocalSource(Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::START_PAGE_POSITION ),
- boost::bind( &ScrollPageSpiralEffectInfo::ColorConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
-
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector4>( child, Actor::Property::COLOR, info, &ScrollPageSpiralEffectInfo::ColorConstraint );
+ constraint.AddSource( LocalSource(Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::START_PAGE_POSITION ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
-
- constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- LocalSource(Actor::Property::POSITION),
- Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ),
- Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ),
- Source(scrollView, Actor::Property::SIZE ),
- Source(scrollView, Toolkit::ScrollView::Property::START_PAGE_POSITION ),
- boost::bind( &ScrollPageSpiralEffectInfo::PositionConstraint, info, _1, _2, _3, _4, _5, _6, _7) );
-
+ constraint.Apply();
+
+ constraint = Constraint::New<Vector3>( child, Actor::Property::POSITION, info, &ScrollPageSpiralEffectInfo::PositionConstraint );
+ constraint.AddSource( LocalSource(Actor::Property::POSITION) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::SCROLL_FINAL ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN ) );
+ constraint.AddSource( Source(scrollView, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX ) );
+ constraint.AddSource( Source(scrollView, Actor::Property::SIZE ) );
+ constraint.AddSource( Source(scrollView, Toolkit::ScrollView::Property::START_PAGE_POSITION ) );
constraint.SetRemoveAction( Constraint::Discard );
- child.ApplyConstraint( constraint );
+ constraint.Apply();
}
} // unnamed namespace
}
/**
- * @param[out] current The new wobble value
- * @param[in] propertyTime The current time since the wobble effect started
- * @param[in] propertyPosition The scroll-position
- * @param[in] propertyOffset The scroll-overshoot
+ * @param[in,out] direction The new wobble value
+ * @param[in] inputs Contains:
+ * The current time since the wobble effect started
+ * The scroll-position
+ * The scroll-overshoot x & y
*/
- Vector3 operator()(const Vector3& current,
- const PropertyInput& propertyTime,
- const PropertyInput& propertyPosition,
- const PropertyInput& propertyOffsetX,
- const PropertyInput& propertyOffsetY)
+ void operator()( Vector3& direction, const PropertyInputContainer& inputs )
{
- Vector3 dir;
-
if(mStabilized)
{
// check if animation cycle id has changed (if so then this spells
else
{
// not stable (i.e. wobbling)
- Vector3 offset(propertyOffsetX.GetFloat(), propertyOffsetY.GetFloat(), 0.0f);
- const Vector3& position = propertyPosition.GetVector3() - offset;
- const float time = propertyTime.GetFloat();
+ Vector3 offset(inputs[2]->GetFloat(), inputs[3]->GetFloat(), 0.0f);
+ const Vector3& position = inputs[1]->GetVector3() - offset;
+ const float time = inputs[0]->GetFloat();
const float timePassed = time - mTime;
mTime = time;
}
}
- dir.x = propertyPosition.GetVector3().x - mChase.x;
- dir.y = propertyPosition.GetVector3().y - mChase.y;
+ direction.x = position.x - mChase.x;
+ direction.y = position.y - mChase.y;
} // end else
-
- return dir;
}
Vector3 mChase; ///< Chaser position
Actor scrollView = GetScrollView();
- Constraint constraint = Constraint::New<Vector3>( propertyEffectOvershoot,
- Source(scrollView, mPropertyTime),
- Source(actor, Toolkit::ScrollView::Property::SCROLL_POSITION),
- Source(actor, Toolkit::ScrollView::Property::OVERSHOOT_X),
- Source(actor, Toolkit::ScrollView::Property::OVERSHOOT_Y),
- ScrollViewWobbleEffectConstraint(*this) );
- actor.ApplyConstraint(constraint);
+ Constraint constraint = Constraint::New<Vector3>( actor, propertyEffectOvershoot, ScrollViewWobbleEffectConstraint(*this) );
+ constraint.AddSource( Source( scrollView, mPropertyTime ) );
+ constraint.AddSource( Source( actor, Toolkit::ScrollView::Property::SCROLL_POSITION ) );
+ constraint.AddSource( Source( actor, Toolkit::ScrollView::Property::OVERSHOOT_X ) );
+ constraint.AddSource( Source( actor, Toolkit::ScrollView::Property::OVERSHOOT_Y ) );
+ constraint.Apply();
}
void ScrollViewWobbleEffect::DetachActor(Actor actor)
// EXTERNAL INCLUDES
#include <sstream>
#include <iomanip>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/common/stage.h>
#include <dali/public-api/object/type-registry.h>
" gl_FragColor = vec4(uShadowColor.rgb, uShadowColor.a * alpha);\n"
"}\n";
-// TODO: Add this to dali-core constraints.h
-/**
- * EqualToConstraintMatrix
- *
- * f(current, property) = property
- */
-struct EqualToConstraintMatrix
-{
- EqualToConstraintMatrix(){}
-
- Dali::Matrix operator()(const Dali::Matrix& current, const PropertyInput& property) {return property.GetMatrix();}
-};
-
} // namespace
ShadowView::ShadowView( float downsampleWidthScale, float downsampleHeightScale )
// Constrain camera to look directly at center of shadow plane. (mPointLight position
// is under control of application, can't use transform inheritance)
- Constraint cameraOrientationConstraint =
- Constraint::New<Quaternion> ( Actor::Property::ORIENTATION,
- Source( mShadowPlane, Actor::Property::WORLD_POSITION ),
- Source( mPointLight, Actor::Property::WORLD_POSITION ),
- Source( mShadowPlane, Actor::Property::WORLD_ORIENTATION ),
- &LookAt );
+ Constraint cameraOrientationConstraint = Constraint::New<Quaternion> ( mCameraActor, Actor::Property::ORIENTATION, &LookAt );
+ cameraOrientationConstraint.AddSource( Source( mShadowPlane, Actor::Property::WORLD_POSITION ) );
+ cameraOrientationConstraint.AddSource( Source( mPointLight, Actor::Property::WORLD_POSITION ) );
+ cameraOrientationConstraint.AddSource( Source( mShadowPlane, Actor::Property::WORLD_ORIENTATION ) );
+ cameraOrientationConstraint.Apply();
- mCameraActor.ApplyConstraint( cameraOrientationConstraint );
-
- Constraint pointLightPositionConstraint = Constraint::New<Vector3>( Actor::Property::POSITION, Source( mPointLight, Actor::Property::WORLD_POSITION ), EqualToConstraint() );
-
- mCameraActor.ApplyConstraint( pointLightPositionConstraint );
+ Constraint pointLightPositionConstraint = Constraint::New<Vector3>( mCameraActor, Actor::Property::POSITION, EqualToConstraint() );
+ pointLightPositionConstraint.AddSource( Source( mPointLight, Actor::Property::WORLD_POSITION ) );
+ pointLightPositionConstraint.Apply();
}
}
Property::Index lightCameraProjectionMatrixPropertyIndex = mShadowRenderShader.GetPropertyIndex(SHADER_LIGHT_CAMERA_PROJECTION_MATRIX_PROPERTY_NAME);
Property::Index lightCameraViewMatrixPropertyIndex = mShadowRenderShader.GetPropertyIndex(SHADER_LIGHT_CAMERA_VIEW_MATRIX_PROPERTY_NAME);
- Constraint projectionMatrixConstraint = Constraint::New<Dali::Matrix>( lightCameraProjectionMatrixPropertyIndex, Source( mCameraActor, CameraActor::Property::PROJECTION_MATRIX ), EqualToConstraintMatrix());
- Constraint viewMatrixConstraint = Constraint::New<Dali::Matrix>( lightCameraViewMatrixPropertyIndex, Source( mCameraActor, CameraActor::Property::VIEW_MATRIX ), EqualToConstraintMatrix());
+ Constraint projectionMatrixConstraint = Constraint::New<Dali::Matrix>( mShadowRenderShader, lightCameraProjectionMatrixPropertyIndex, EqualToConstraint() );
+ projectionMatrixConstraint.AddSource( Source( mCameraActor, CameraActor::Property::PROJECTION_MATRIX ) );
- mShadowRenderShader.ApplyConstraint(projectionMatrixConstraint);
- mShadowRenderShader.ApplyConstraint(viewMatrixConstraint);
+ Constraint viewMatrixConstraint = Constraint::New<Dali::Matrix>( mShadowRenderShader, lightCameraViewMatrixPropertyIndex, EqualToConstraint() );
+ viewMatrixConstraint.AddSource( Source( mCameraActor, CameraActor::Property::VIEW_MATRIX ) );
+
+ projectionMatrixConstraint.Apply();
+ viewMatrixConstraint.Apply();
// Register a property that the user can use to control the blur in the internal object
mBlurStrengthPropertyIndex = self.RegisterProperty(BLUR_STRENGTH_PROPERTY_NAME, BLUR_STRENGTH_DEFAULT);
- mBlurFilter.GetHandleForAnimateBlurStrength().ApplyConstraint( Constraint::New<float>( mBlurFilter.GetBlurStrengthPropertyIndex() ,
- Source( self, mBlurStrengthPropertyIndex),
- EqualToConstraint()) );
+
+ Constraint blurStrengthConstraint = Constraint::New<float>( mBlurFilter.GetHandleForAnimateBlurStrength(), mBlurFilter.GetBlurStrengthPropertyIndex(), EqualToConstraint() );
+ blurStrengthConstraint.AddSource( Source( self, mBlurStrengthPropertyIndex) );
+ blurStrengthConstraint.Apply();
// Register a property that the user can use to control the color of the shadow.
Property::Index index = mShadowRenderShader.GetPropertyIndex(SHADER_SHADOW_COLOR_PROPERTY_NAME);
mShadowColorPropertyIndex = self.RegisterProperty(SHADOW_COLOR_PROPERTY_NAME, mCachedShadowColor);
- mShadowRenderShader.ApplyConstraint(Constraint::New<Dali::Vector4>( index, Source( self, mShadowColorPropertyIndex ), EqualToConstraint()) );
+ Constraint shadowRenderShaderConstraint = Constraint::New<Dali::Vector4>( mShadowRenderShader, index, EqualToConstraint() );
+ shadowRenderShaderConstraint.AddSource( Source( self, mShadowColorPropertyIndex ) );
+ shadowRenderShaderConstraint.Apply();
}
} // namespace Internal
}
}
- if( mHandleValueTextView )
+ if( mHandleValueTextLabel )
{
std::stringstream ss;
ss.precision( GetValuePrecision() );
ss << std::fixed << clampledValue;
- mHandleValueTextView.SetText( ss.str() );
+ mHandleValueTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, ss.str() );
}
}
return arrow;
}
-Toolkit::TextView Slider::CreatePopupText()
+Toolkit::TextLabel Slider::CreatePopupText()
{
- Toolkit::TextView textView = Toolkit::TextView::New();
- textView.SetParentOrigin( ParentOrigin::CENTER );
- textView.SetAnchorPoint( AnchorPoint::CENTER );
- textView.SetZ( VALUE_DISPLAY_TEXT_Z );
- return textView;
+ Toolkit::TextLabel textLabel = Toolkit::TextLabel::New();
+ textLabel.SetParentOrigin( ParentOrigin::CENTER );
+ textLabel.SetAnchorPoint( AnchorPoint::CENTER );
+ textLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
+ textLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
+ textLabel.SetZ( VALUE_DISPLAY_TEXT_Z );
+ return textLabel;
}
ImageActor Slider::CreatePopup()
popup.SetParentOrigin( ParentOrigin::TOP_CENTER );
popup.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
- mValueTextView = CreatePopupText();
- popup.Add( mValueTextView );
+ mValueTextLabel = CreatePopupText();
+ popup.Add( mValueTextLabel );
return popup;
}
void Slider::CreateHandleValueDisplay()
{
- if( mHandle && !mHandleValueTextView )
+ if( mHandle && !mHandleValueTextLabel )
{
- 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 );
+ mHandleValueTextLabel = Toolkit::TextLabel::New();
+ mHandleValueTextLabel.SetParentOrigin( ParentOrigin::CENTER );
+ mHandleValueTextLabel.SetAnchorPoint( AnchorPoint::CENTER );
+ mHandleValueTextLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
+ mHandleValueTextLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
+ mHandleValueTextLabel.SetDrawMode( DrawMode::OVERLAY );
+ mHandle.Add( mHandleValueTextLabel );
}
}
void Slider::DestroyHandleValueDisplay()
{
- if(mHandleValueTextView)
- {
- mHandleValueTextView.Unparent();
- mHandleValueTextView.Reset();
- }
+ UnparentAndReset(mHandleValueTextLabel);
}
void Slider::SetPopupTextColor( const Vector4& color )
void Slider::DisplayPopup( float value )
{
// Value displayDoConnectSignal
- if( mValueTextView )
+ if( mValueTextLabel )
{
std::stringstream ss;
ss.precision( GetValuePrecision() );
ss << std::fixed << value;
- mValueTextView.SetText( ss.str() );
- TextStyle style;
- style.SetTextColor( GetPopupTextColor() );
- mValueTextView.SetStyleToCurrentText( style, TextStyle::COLOR);
+ mValueTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, ss.str() );
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 );
// 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>
+#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
namespace Dali
{
*
* @return The textview created for the popup
*/
- Toolkit::TextView CreatePopupText();
+ Toolkit::TextLabel 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
+ Toolkit::TextLabel mValueTextLabel; //< The text value in popup
+ Toolkit::TextLabel mHandleValueTextLabel; ///< The text value on handle
Vector2 mHandleLastTouchPoint; ///< The last touch point for the handle
Timer mValueTimer; ///< Timer used to hide value view
// EXTERNAL INCLUDES
#include <cmath>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/common/stage.h>
#include <dali/public-api/object/type-registry.h>
mRange = Vector2( index*rangeLength, (index+1.f)*rangeLength );
}
- float operator()( float current, const PropertyInput& blurProperty )
+ void operator()( float& current, const PropertyInputContainer& inputs )
{
- float blurStrength = blurProperty.GetFloat();
+ float blurStrength = inputs[0]->GetFloat();
if(blurStrength <= mRange.x)
{
- return 1.f;
+ current = 1.f;
}
else if(blurStrength > mRange.y)
{
- return 0.f;
+ current = 0.f;
}
else
{
- return (mRange.y - blurStrength)/(mRange.y-mRange.x);
+ current = ( mRange.y - blurStrength) / ( mRange.y - mRange.x );
}
}
for(unsigned int i=0; i<=mBlurLevels;i++)
{
mImageActors[i] = ImageActor::New( );
+ mImageActors[i].SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
mImageActors[i].SetParentOrigin( ParentOrigin::CENTER );
mImageActors[i].SetZ(-static_cast<float>(i)*0.01f);
mImageActors[i].SetColorMode( USE_OWN_MULTIPLY_PARENT_ALPHA );
for(unsigned int i=0; i < mBlurLevels; i++)
{
- mImageActors[i].ApplyConstraint( Constraint::New<float>( Actor::Property::COLOR_ALPHA, ParentSource( mBlurStrengthPropertyIndex ), ActorOpacityConstraint(mBlurLevels, i) ) );
+ Constraint constraint = Constraint::New<float>( mImageActors[i], Actor::Property::COLOR_ALPHA, ActorOpacityConstraint(mBlurLevels, i) );
+ constraint.AddSource( ParentSource( mBlurStrengthPropertyIndex ) );
+ constraint.Apply();
}
Self().SetSize(Stage::GetCurrent().GetSize());
}
}
-void SuperBlurView::OnRelayout( const Vector2& size, RelayoutContainer& container )
-{
- unsigned int numChildren = Self().GetChildCount();
-
- for( unsigned int i=0; i<numChildren; ++i )
- {
- Self().GetChildAt(i).SetSize(size);
- }
-}
-
void SuperBlurView::OnControlSizeSet( const Vector3& targetSize )
{
if( mTargetSize != Vector2(targetSize) )
*/
virtual void OnControlSizeSet(const Vector3& targetSize);
- /**
- * @copydoc Control::OnRelayout()
- */
- virtual void OnRelayout( const Vector2& size, RelayoutContainer& container );
-
private:
/**
{
Dali::Toolkit::Internal::TableView::CellData data = array[i][j];
char actor = ' ';
+ std::string actorName;
if( data.actor )
{
actor = 'A';
+ actorName = data.actor.GetName();
}
- TV_LOG("Array[%d,%d]=%c %d,%d,%d,%d ", i, j, actor,
+ TV_LOG("Array[%d,%d]=%c %s %d,%d,%d,%d ", i, j, actor, actorName.c_str(),
data.position.rowIndex, data.position.columnIndex,
data.position.rowSpan, data.position.columnSpan );
}
// adopt the child
Self().Add( child );
- // put the actor to the main cell
- CellData& data = mCellData[ position.rowIndex ][ position.columnIndex ];
- data.actor = child;
- data.position = position;
-
// if child spans multiple rows of columns
- bool spanned = false;
- if( position.rowSpan > 1 )
+ if( ( position.rowSpan > 1 ) && ( position.rowIndex + position.rowSpan > mCellData.GetRows() ) )
{
- // span might go outside table
- if( position.rowIndex + position.rowSpan > mCellData.GetRows() )
- {
- // increase table size for the full span, only increasing rows
- ResizeContainers( position.rowIndex + position.rowSpan, mCellData.GetColumns() );
- }
-
- spanned = true;
+ // increase table size for the full span, only increasing rows
+ ResizeContainers( position.rowIndex + position.rowSpan, mCellData.GetColumns() );
}
- if( position.columnSpan > 1 )
+ if( ( position.columnSpan > 1 ) && ( position.columnIndex + position.columnSpan > mCellData.GetColumns() ) )
{
- // span might go outside table
- if( position.columnIndex + position.columnSpan > mCellData.GetColumns() )
- {
- // increase table size for the full span, only increasing columns
- ResizeContainers( mCellData.GetRows(), position.columnIndex + position.columnSpan );
- }
-
- spanned = true;
+ // increase table size for the full span, only increasing columns
+ ResizeContainers( mCellData.GetRows(), position.columnIndex + position.columnSpan );
}
- // if it spanned multiple rows, put the cellinfo in all of those
- if( spanned )
+ // Fill in all cells that need the data
+ CellData data;
+ data.actor = child;
+ data.position = position;
+
+ for( unsigned int row = position.rowIndex; row < ( position.rowIndex + position.rowSpan ); ++row )
{
- for( unsigned int row = position.rowIndex; row < ( position.rowIndex + position.rowSpan ); ++row )
+ // store same information to all cells, this way we can identify
+ // if a cell is the prime location of an actor or a spanned one
+ for( unsigned int column = position.columnIndex; column < ( position.columnIndex + position.columnSpan ); ++column )
{
// store same information to all cells, this way we can identify
// if a cell is the prime location of an actor or a spanned one
- for( unsigned int column = position.columnIndex; column < ( position.columnIndex + position.columnSpan ); ++column )
- {
- // store same information to all cells, this way we can identify
- // if a cell is the prime location of an actor or a spanned one
- mCellData[ row ][ column ] = data;
- }
+ mCellData[ row ][ column ] = data;
}
}
// Accumulate the width
for( unsigned int i = 0; i < position.columnSpan; ++i )
{
+ DALI_ASSERT_DEBUG( column + i < mColumnData.Size() );
cellSize += mColumnData[ column + i ].size;
}
// Accumulate the height
for( unsigned int i = 0; i < position.rowSpan; ++i )
{
+ DALI_ASSERT_DEBUG( row + i < mRowData.Size() );
cellSize += mRowData[ row + i ].size;
}
--- /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 <string>
+#include <dali/public-api/adaptor-framework/key.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/images/resource-image.h>
+#include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/scripting/scripting.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/adaptor-framework/virtual-keyboard.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/rendering-backend.h>
+#include <dali-toolkit/internal/text/layouts/layout-engine.h>
+#include <dali-toolkit/internal/text/rendering/text-backend.h>
+#include <dali-toolkit/internal/styling/style-manager-impl.h>
+
+using namespace Dali::Toolkit::Text;
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+ const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
+}
+
+namespace
+{
+
+const Scripting::StringEnum< Toolkit::Text::LayoutEngine::HorizontalAlignment > HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+{
+ { "BEGIN", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN },
+ { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
+ { "END", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END },
+};
+const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
+
+const Scripting::StringEnum< Toolkit::Text::LayoutEngine::VerticalAlignment > VERTICAL_ALIGNMENT_STRING_TABLE[] =
+{
+ { "TOP", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP },
+ { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
+ { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
+};
+const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
+
+// Type registration
+BaseHandle Create()
+{
+ return Toolkit::TextField::New();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextField, Toolkit::Control, Create );
+
+DALI_PROPERTY_REGISTRATION( TextField, "rendering-backend", INTEGER, RENDERING_BACKEND )
+DALI_PROPERTY_REGISTRATION( TextField, "placeholder-text", STRING, PLACEHOLDER_TEXT )
+DALI_PROPERTY_REGISTRATION( TextField, "text", STRING, TEXT )
+DALI_PROPERTY_REGISTRATION( TextField, "font-family", STRING, FONT_FAMILY )
+DALI_PROPERTY_REGISTRATION( TextField, "font-style", STRING, FONT_STYLE )
+DALI_PROPERTY_REGISTRATION( TextField, "point-size", FLOAT, POINT_SIZE )
+DALI_PROPERTY_REGISTRATION( TextField, "exceed-policy", INTEGER, EXCEED_POLICY )
+DALI_PROPERTY_REGISTRATION( TextField, "primary-cursor-color", VECTOR4, PRIMARY_CURSOR_COLOR )
+DALI_PROPERTY_REGISTRATION( TextField, "secondary-cursor-color", VECTOR4, SECONDARY_CURSOR_COLOR )
+DALI_PROPERTY_REGISTRATION( TextField, "enable-cursor-blink", BOOLEAN, ENABLE_CURSOR_BLINK )
+DALI_PROPERTY_REGISTRATION( TextField, "cursor-blink-interval", FLOAT, CURSOR_BLINK_INTERVAL )
+DALI_PROPERTY_REGISTRATION( TextField, "cursor-blink-duration", FLOAT, CURSOR_BLINK_DURATION )
+DALI_PROPERTY_REGISTRATION( TextField, "grab-handle-image", STRING, GRAB_HANDLE_IMAGE )
+DALI_PROPERTY_REGISTRATION( TextField, "decoration-bounding-box", RECTANGLE, DECORATION_BOUNDING_BOX )
+DALI_PROPERTY_REGISTRATION( TextField, "horizontal-alignment", STRING, HORIZONTAL_ALIGNMENT )
+DALI_PROPERTY_REGISTRATION( TextField, "vertical-alignment", STRING, VERTICAL_ALIGNMENT )
+DALI_TYPE_REGISTRATION_END()
+
+} // 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:
+ {
+ int backend = value.Get< 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::FONT_FAMILY:
+ {
+ if( impl.mController )
+ {
+ std::string fontFamily = value.Get< std::string >();
+
+ if( impl.mController->GetDefaultFontFamily() != fontFamily )
+ {
+ impl.mController->SetDefaultFontFamily( fontFamily );
+ impl.RequestTextRelayout();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::FONT_STYLE:
+ {
+ if( impl.mController )
+ {
+ std::string fontStyle = value.Get< std::string >();
+
+ if( impl.mController->GetDefaultFontStyle() != fontStyle )
+ {
+ impl.mController->SetDefaultFontStyle( fontStyle );
+ impl.RequestTextRelayout();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::POINT_SIZE:
+ {
+ if( impl.mController )
+ {
+ float pointSize = value.Get< float >();
+
+ if( impl.mController->GetDefaultPointSize() != pointSize /*TODO - epsilon*/ )
+ {
+ impl.mController->SetDefaultPointSize( pointSize );
+ impl.RequestTextRelayout();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::EXCEED_POLICY:
+ {
+ impl.mExceedPolicy = value.Get< int >();
+ 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 >() );
+ }
+ 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;
+ }
+ case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
+ {
+ LayoutEngine& engine = impl.mController->GetLayoutEngine();
+ const LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+ if( engine.GetHorizontalAlignment() != alignment )
+ {
+ engine.SetHorizontalAlignment( alignment );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
+ {
+ LayoutEngine& engine = impl.mController->GetLayoutEngine();
+ const LayoutEngine::VerticalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
+ VERTICAL_ALIGNMENT_STRING_TABLE,
+ VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+ if( engine.GetVerticalAlignment() != alignment )
+ {
+ engine.SetVerticalAlignment( alignment );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ } // switch
+ } // textfield
+}
+
+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:
+ {
+ if( impl.mController )
+ {
+ std::string text;
+ impl.mController->GetPlaceholderText( text );
+ value = text;
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::TEXT:
+ {
+ if( impl.mController )
+ {
+ std::string text;
+ impl.mController->GetText( text );
+ value = text;
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::EXCEED_POLICY:
+ {
+ value = impl.mExceedPolicy;
+ 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();
+ 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::DECORATION_BOUNDING_BOX:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetBoundingBox();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
+ {
+ if( impl.mController )
+ {
+ value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
+ {
+ if( impl.mController )
+ {
+ value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetLayoutEngine().GetVerticalAlignment(),
+ VERTICAL_ALIGNMENT_STRING_TABLE,
+ VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+ }
+ break;
+ }
+ } //switch
+ }
+
+ return value;
+}
+
+void TextField::OnInitialize()
+{
+ Actor self = Self();
+
+ 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);
+ GetTapGestureDetector().SetMaximumTapsRequired( 2 );
+ EnableGestureDetection(Gesture::Pan);
+
+ // 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 ) );
+ }
+
+ // Fill-parent area by default
+ self.SetResizePolicy( FILL_TO_PARENT, WIDTH );
+ self.SetResizePolicy( FILL_TO_PARENT, HEIGHT );
+}
+
+void TextField::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange change )
+{
+ GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+}
+
+Vector3 TextField::GetNaturalSize()
+{
+ return mController->GetNaturalSize();
+}
+
+float TextField::GetHeightForWidth( float width )
+{
+ return mController->GetHeightForWidth( width );
+}
+
+void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
+{
+ if( mController->Relayout( size ) ||
+ !mRenderer )
+ {
+ const Vector2& scrollPosition = mController->GetScrollPosition();
+ const Vector2& alignmentOffset = mController->GetAlignmentOffset();
+
+ Vector2 offset = scrollPosition + alignmentOffset;
+
+ if( mDecorator )
+ {
+ mDecorator->Relayout( size, offset );
+ }
+
+ if( !mRenderer )
+ {
+ mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
+ }
+
+ RenderableActor renderableActor;
+ if( mRenderer )
+ {
+ renderableActor = mRenderer->Render( mController->GetView() );
+ }
+
+ EnableClipping( (Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy), size );
+
+ if( renderableActor != mRenderableActor )
+ {
+ UnparentAndReset( mRenderableActor );
+ mRenderableActor = renderableActor;
+ }
+
+ if( mRenderableActor )
+ {
+ mRenderableActor.SetPosition( offset.x, offset.y );
+
+ // Make sure the actor is parented correctly with/without clipping
+ if( mClipper )
+ {
+ mClipper->GetRootActor().Add( mRenderableActor );
+ }
+ else
+ {
+ Self().Add( mRenderableActor );
+ }
+ }
+ }
+}
+
+void TextField::OnKeyInputFocusGained()
+{
+ VirtualKeyboard::StatusChangedSignal().Connect( this, &TextField::KeyboardStatusChanged );
+
+ ImfManager imfManager = ImfManager::Get();
+
+ if ( imfManager )
+ {
+ imfManager.EventReceivedSignal().Connect( this, &TextField::OnImfEvent );
+
+ // 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 );
+ }
+
+ mController->KeyboardFocusGainEvent();
+}
+
+void TextField::OnKeyInputFocusLost()
+{
+ VirtualKeyboard::StatusChangedSignal().Disconnect( this, &TextField::KeyboardStatusChanged );
+
+ 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, &TextField::OnImfEvent );
+ }
+
+ mController->KeyboardFocusLostEvent();
+}
+
+void TextField::OnTap( const TapGesture& gesture )
+{
+ // Show the keyboard if it was hidden.
+ if (!VirtualKeyboard::IsVisible())
+ {
+ VirtualKeyboard::Show();
+ }
+
+ SetKeyInputFocus();
+
+ mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
+}
+
+void TextField::OnPan( const PanGesture& gesture )
+{
+ mController->PanEvent( gesture.state, gesture.displacement );
+}
+
+bool TextField::OnKeyEvent( const KeyEvent& event )
+{
+ if( Dali::DALI_KEY_ESCAPE == event.keyCode )
+ {
+ ClearKeyInputFocus();
+ }
+
+ return mController->KeyEvent( event );
+}
+
+ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
+{
+ switch ( imfEvent.eventName )
+ {
+ case ImfManager::COMMIT:
+ {
+ KeyEvent event( "", imfEvent.predictiveString, 0, 0, 0, KeyEvent::Down );
+ mController->KeyEvent( event );
+ break;
+ }
+ case ImfManager::PREEDIT: // fall through
+ case ImfManager::DELETESURROUNDING:
+ case ImfManager::GETSURROUNDING:
+ case ImfManager::VOID:
+ {
+ // do nothing
+ }
+ } // end switch
+
+ return ImfManager::ImfCallbackData();
+}
+
+void TextField::RequestTextRelayout()
+{
+ RelayoutRequest();
+}
+
+void TextField::EnableClipping( bool clipping, const Vector2& size )
+{
+ if( clipping )
+ {
+ // Not worth to created clip actor if width or height is equal to zero.
+ if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
+ {
+ if( !mClipper )
+ {
+ Actor self = Self();
+
+ mClipper = Clipper::New( size );
+ self.Add( mClipper->GetRootActor() );
+ self.Add( mClipper->GetImageActor() );
+ }
+ else if ( mClipper )
+ {
+ mClipper->Refresh( size );
+ }
+ }
+ }
+ else
+ {
+ // Note - this will automatically remove the root & image actors
+ mClipper.Reset();
+ }
+}
+
+void TextField::KeyboardStatusChanged(bool keyboardShown)
+{
+ // Just hide the grab handle when keyboard is hidden.
+ if (!keyboardShown )
+ {
+ mController->KeyboardFocusLostEvent();
+ }
+}
+
+TextField::TextField()
+: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
+ mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
+ mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP )
+{
+}
+
+TextField::~TextField()
+{
+ mClipper.Reset();
+}
+
+} // 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/imf-manager.h>
+
+// 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/internal/text/clipping/text-clipper.h>
+#include <dali-toolkit/internal/text/decorator/text-decorator.h>
+#include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * @brief A control which renders a short text string.
+ */
+class TextField : public Control, public Text::ControlInterface
+{
+public:
+
+ /**
+ * @copydoc Dali::Toollkit::TextField::New()
+ */
+ static Toolkit::TextField New();
+
+ // Properties
+
+ /**
+ * @brief 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 );
+
+ /**
+ * @brief 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::OnStyleChange()
+ */
+ virtual void OnStyleChange( Toolkit::StyleManager styleManager, StyleChange change );
+
+ /**
+ * @copydoc Control::GetNaturalSize()
+ */
+ virtual Vector3 GetNaturalSize();
+
+ /**
+ * @copydoc Control::GetHeightForWidth()
+ */
+ virtual float GetHeightForWidth( float width );
+
+ /**
+ * @copydoc Control::OnInitialize()
+ */
+ virtual void OnRelayout( const Vector2& size, RelayoutContainer& container );
+
+ /**
+ * @copydoc Control::OnKeyInputFocusGained()
+ */
+ virtual void OnKeyInputFocusGained();
+
+ /**
+ * @copydoc Control::OnKeyInputFocusLost()
+ */
+ virtual void OnKeyInputFocusLost();
+
+ /**
+ * @copydoc Control::OnTap()
+ */
+ virtual void OnTap( const TapGesture& tap );
+
+ /**
+ * @copydoc Control::OnPan()
+ */
+ virtual void OnPan( const PanGesture& gesture );
+
+ /**
+ * @copydoc Dali::CustomActorImpl::OnKeyEvent(const KeyEvent&)
+ */
+ virtual bool OnKeyEvent(const KeyEvent& event);
+
+ /**
+ * @brief Event received from IMF manager
+ *
+ * @param[in] imfManager The IMF manager.
+ * @param[in] imfEvent The event received.
+ * @return A data struture indicating if update is needed, cursor position and current text.
+ */
+ ImfManager::ImfCallbackData OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent );
+
+ /**
+ * @copydoc Text::ControlInterface::RequestTextRelayout()
+ */
+ virtual void RequestTextRelayout();
+
+private: // Implementation
+
+ /**
+ * @brief Enable or disable clipping.
+ *
+ * @param[in] clipping True if clipping should be enabled.
+ * @param[in] size The area to clip within.
+ */
+ void EnableClipping( bool clipping, const Vector2& size );
+
+ /**
+ * @brief Callback when keyboard is shown/hidden.
+ *
+ * @param[in] keyboardShown True if keyboard is shown.
+ */
+ void KeyboardStatusChanged( bool keyboardShown );
+
+ /**
+ * 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;
+ Text::ClipperPtr mClipper; ///< For EXCEED_POLICY_CLIP
+
+ RenderableActor mRenderableActor;
+
+ int mRenderingBackend;
+ int mExceedPolicy;
+};
+
+} // 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/public-api/object/type-registry-helper.h>
+#include <dali/public-api/scripting/scripting.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/rendering-backend.h>
+#include <dali-toolkit/internal/text/layouts/layout-engine.h>
+#include <dali-toolkit/internal/text/rendering/text-backend.h>
+#include <dali-toolkit/internal/styling/style-manager-impl.h>
+
+using Dali::Toolkit::Text::LayoutEngine;
+using Dali::Toolkit::Text::Backend;
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+ const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
+}
+
+namespace
+{
+
+const Scripting::StringEnum< Toolkit::Text::LayoutEngine::HorizontalAlignment > HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+{
+ { "BEGIN", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN },
+ { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
+ { "END", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END },
+};
+const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
+
+const Scripting::StringEnum< Toolkit::Text::LayoutEngine::VerticalAlignment > VERTICAL_ALIGNMENT_STRING_TABLE[] =
+{
+ { "TOP", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP },
+ { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
+ { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
+};
+const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
+
+// Type registration
+BaseHandle Create()
+{
+ return Toolkit::TextLabel::New();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextLabel, Toolkit::Control, Create );
+
+DALI_PROPERTY_REGISTRATION( TextLabel, "rendering-backend", INTEGER, RENDERING_BACKEND )
+DALI_PROPERTY_REGISTRATION( TextLabel, "text", STRING, TEXT )
+DALI_PROPERTY_REGISTRATION( TextLabel, "font-family", STRING, FONT_FAMILY )
+DALI_PROPERTY_REGISTRATION( TextLabel, "font-style", STRING, FONT_STYLE )
+DALI_PROPERTY_REGISTRATION( TextLabel, "point-size", FLOAT, POINT_SIZE )
+DALI_PROPERTY_REGISTRATION( TextLabel, "multi-line", BOOLEAN, MULTI_LINE )
+DALI_PROPERTY_REGISTRATION( TextLabel, "horizontal-alignment", STRING, HORIZONTAL_ALIGNMENT )
+DALI_PROPERTY_REGISTRATION( TextLabel, "vertical-alignment", STRING, VERTICAL_ALIGNMENT )
+DALI_PROPERTY_REGISTRATION( TextLabel, "text-color", VECTOR4, TEXT_COLOR )
+DALI_PROPERTY_REGISTRATION( TextLabel, "shadow-offset", VECTOR2, SHADOW_OFFSET )
+DALI_PROPERTY_REGISTRATION( TextLabel, "shadow-color", VECTOR4, SHADOW_COLOR )
+DALI_PROPERTY_REGISTRATION( TextLabel, "underline-enabled", BOOLEAN, UNDERLINE_ENABLED )
+DALI_PROPERTY_REGISTRATION( TextLabel, "underline-color", VECTOR4, UNDERLINE_COLOR )
+DALI_TYPE_REGISTRATION_END()
+
+} // 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:
+ {
+ int backend = value.Get< int >();
+
+ if( impl.mRenderingBackend != backend )
+ {
+ impl.mRenderingBackend = backend;
+ impl.mRenderer.Reset();
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::TEXT:
+ {
+ if( impl.mController )
+ {
+ impl.mController->SetText( value.Get< std::string >() );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::FONT_FAMILY:
+ {
+ if( impl.mController )
+ {
+ std::string fontFamily = value.Get< std::string >();
+
+ if( impl.mController->GetDefaultFontFamily() != fontFamily )
+ {
+ impl.mController->SetDefaultFontFamily( fontFamily );
+ impl.RequestTextRelayout();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::FONT_STYLE:
+ {
+ if( impl.mController )
+ {
+ std::string fontStyle = value.Get< std::string >();
+
+ if( impl.mController->GetDefaultFontStyle() != fontStyle )
+ {
+ impl.mController->SetDefaultFontStyle( fontStyle );
+ impl.RequestTextRelayout();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::POINT_SIZE:
+ {
+ if( impl.mController )
+ {
+ float pointSize = value.Get< float >();
+
+ if( fabsf(impl.mController->GetDefaultPointSize() - pointSize) > Math::MACHINE_EPSILON_1 )
+ {
+ impl.mController->SetDefaultPointSize( pointSize );
+ impl.RequestTextRelayout();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::MULTI_LINE:
+ {
+ if( impl.mController )
+ {
+ LayoutEngine& engine = impl.mController->GetLayoutEngine();
+ LayoutEngine::Layout layout = value.Get< bool >() ? LayoutEngine::MULTI_LINE_BOX : LayoutEngine::SINGLE_LINE_BOX;
+
+ if( engine.GetLayout() != layout )
+ {
+ engine.SetLayout( layout );
+ impl.RequestTextRelayout();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
+ {
+ LayoutEngine& engine = impl.mController->GetLayoutEngine();
+ const LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+ if( engine.GetHorizontalAlignment() != alignment )
+ {
+ engine.SetHorizontalAlignment( alignment );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
+ {
+ LayoutEngine& engine = impl.mController->GetLayoutEngine();
+ const LayoutEngine::VerticalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
+ VERTICAL_ALIGNMENT_STRING_TABLE,
+ VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+ if( engine.GetVerticalAlignment() != alignment )
+ {
+ engine.SetVerticalAlignment( alignment );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+
+ case Toolkit::TextLabel::Property::TEXT_COLOR:
+ {
+ if ( impl.mController )
+ {
+ Vector4 textColor = value.Get< Vector4 >();
+ if ( impl.mController->GetTextColor() != textColor )
+ {
+ impl.mController->SetTextColor( textColor );
+ impl.RequestTextRelayout();
+ }
+ }
+ break;
+ }
+
+ case Toolkit::TextLabel::Property::SHADOW_OFFSET:
+ {
+ if( impl.mController )
+ {
+ Vector2 shadowOffset = value.Get< Vector2 >();
+ if ( impl.mController->GetShadowOffset() != shadowOffset )
+ {
+ impl.mController->SetShadowOffset( shadowOffset );
+ impl.RequestTextRelayout();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::SHADOW_COLOR:
+ {
+ if( impl.mController )
+ {
+ Vector4 shadowColor = value.Get< Vector4 >();
+ if ( impl.mController->GetShadowColor() != shadowColor )
+ {
+ impl.mController->SetShadowColor( shadowColor );
+ impl.RequestTextRelayout();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
+ {
+ if( impl.mController )
+ {
+ Vector4 color = value.Get< Vector4 >();
+ if ( impl.mController->GetUnderlineColor() != color )
+ {
+ impl.mController->SetUnderlineColor( color );
+ impl.RequestTextRelayout();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
+ {
+ if( impl.mController )
+ {
+ bool enabled = value.Get< bool >();
+ if ( impl.mController->IsUnderlineEnabled() != enabled )
+ {
+ impl.mController->SetUnderlineEnabled( enabled );
+ impl.RequestTextRelayout();
+ }
+ }
+ 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:
+ {
+ if( impl.mController )
+ {
+ std::string text;
+ impl.mController->GetText( text );
+ value = text;
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::MULTI_LINE:
+ {
+ if( impl.mController )
+ {
+ value = static_cast<bool>( LayoutEngine::MULTI_LINE_BOX == impl.mController->GetLayoutEngine().GetLayout() );
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
+ {
+ if( impl.mController )
+ {
+ value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
+ {
+ if( impl.mController )
+ {
+ value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetLayoutEngine().GetVerticalAlignment(),
+ VERTICAL_ALIGNMENT_STRING_TABLE,
+ VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::TEXT_COLOR:
+ {
+ if ( impl.mController )
+ {
+ value = impl.mController->GetTextColor();
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::SHADOW_OFFSET:
+ {
+ if ( impl.mController )
+ {
+ value = impl.mController->GetShadowOffset();
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::SHADOW_COLOR:
+ {
+ if ( impl.mController )
+ {
+ value = impl.mController->GetShadowColor();
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
+ {
+ if ( impl.mController )
+ {
+ value = impl.mController->GetUnderlineColor();
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
+ {
+ if ( impl.mController )
+ {
+ value = impl.mController->IsUnderlineEnabled();
+ }
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
+void TextLabel::OnInitialize()
+{
+ Actor self = Self();
+
+ mController = Text::Controller::New( *this );
+
+ // Use height-for-width negotiation by default
+ self.SetResizePolicy( FILL_TO_PARENT, WIDTH );
+ self.SetResizePolicy( DIMENSION_DEPENDENCY, HEIGHT );
+}
+
+void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange change )
+{
+ GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+}
+
+Vector3 TextLabel::GetNaturalSize()
+{
+ return mController->GetNaturalSize();
+}
+
+float TextLabel::GetHeightForWidth( float width )
+{
+ return mController->GetHeightForWidth( width );
+}
+
+void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
+{
+ if( mController->Relayout( size ) ||
+ !mRenderer )
+ {
+ if( !mRenderer )
+ {
+ mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
+ }
+
+ RenderableActor renderableActor;
+ if( mRenderer )
+ {
+ renderableActor = mRenderer->Render( mController->GetView() );
+ }
+
+ if( renderableActor != mRenderableActor )
+ {
+ UnparentAndReset( mRenderableActor );
+
+ if( renderableActor )
+ {
+ const Vector2& alignmentOffset = mController->GetAlignmentOffset();
+ renderableActor.SetPosition( alignmentOffset.x, alignmentOffset.y );
+
+ Self().Add( renderableActor );
+ }
+
+ mRenderableActor = renderableActor;
+ }
+ }
+}
+
+void TextLabel::RequestTextRelayout()
+{
+ RelayoutRequest();
+}
+
+TextLabel::TextLabel()
+: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
+ 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/internal/text/text-controller.h>
+#include <dali-toolkit/internal/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:
+
+ /**
+ * @copydoc Dali::Toollkit::TextLabel::New()
+ */
+ static Toolkit::TextLabel New();
+
+ // Properties
+
+ /**
+ * @brief 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 );
+
+ /**
+ * @brief 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::OnStyleChange()
+ */
+ virtual void OnStyleChange( Toolkit::StyleManager styleManager, StyleChange change );
+
+ /**
+ * @copydoc Control::OnRelayout()
+ */
+ virtual void OnRelayout( const Vector2& size, RelayoutContainer& 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;
+ RenderableActor mRenderableActor;
+
+ 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) 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-selection-popup-impl.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/buttons/push-button.h>
+#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/images/nine-patch-image.h>
+#include <dali/public-api/images/resource-image.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/math/vector4.h>
+#include <libintl.h>
+
+// todo Move this to adaptor??
+#define GET_LOCALE_TEXT(string) dgettext("elementary", string)
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+const Dali::Vector4 DEFAULT_POPUP_BACKGROUND( Dali::Vector4( .20f, 0.29f, 0.44f, 1.0f ) );
+const Dali::Vector4 DEFAULT_POPUP_BACKGROUND_PRESSED( Dali::Vector4( 0.07f, 0.10f, 0.17f, 1.0f ) );
+const Dali::Vector4 DEFAULT_POPUP_LINE_COLOR( Dali::Vector4( 0.36f, 0.45f, 0.59f, 1.0f ) );
+const Dali::Vector4 DEFAULT_OPTION_ICON( Dali::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
+const Dali::Vector4 DEFAULT_OPTION_ICON_PRESSED( Dali::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
+const Dali::Vector4 DEFAULT_OPTION_TEXT( Dali::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
+const Dali::Vector4 DEFAULT_OPTION_TEXT_PRESSED( Dali::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
+
+const std::string DEFAULT_POPUP_BACKGROUND_IMAGE( DALI_IMAGE_DIR "popup_bubble_bg.#.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" );
+
+const Dali::Vector2 DEFAULT_POPUP_MAX_SIZE( 470.0f, 120.0f ); ///< The maximum size of the popup.
+
+const float OPTION_TEXT_LINE_HEIGHT( 32.0f ); ///< The line height of the text.
+const Dali::Vector2 OPTION_ICON_SIZE( 0.f, 0.f ); ///< The size of the icon.
+const float OPTION_GAP_ICON_TEXT( 6.f ); ///< The gap between the icon and the text
+const float OPTION_MARGIN_WIDTH( 10.f ); ///< The margin between the right or lefts edge and the text or icon.
+const float OPTION_MAX_WIDTH( DEFAULT_POPUP_MAX_SIZE.width / 6 ); ///< The maximum width of the option (currently set to the max)
+const float OPTION_MIN_WIDTH( 86.0f ); ///< The minimum width of the option.
+
+const float POPUP_DIVIDER_WIDTH( 1.f ); ///< The size of the divider.
+
+const Dali::Vector2 POPUP_TAIL_SIZE( 20.0f, 16.0f ); ///< The size of the tail.
+const float POPUP_TAIL_Y_OFFSET( 5.f ); ///< The y offset of the tail (when its position is on the bottom).
+const float POPUP_TAIL_TOP_Y_OFFSET( 3.f ); ///< The y offset of the tail (when its position is on the top).
+
+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.
+
+const char* const OPTION_SELECT_WORD = "option-select_word"; // "Select Word" popup option.
+const char* const OPTION_SELECT_ALL("option-select_all"); // "Select All" popup option.
+const char* const OPTION_CUT("option-cut"); // "Cut" popup option.
+const char* const OPTION_COPY("option-copy"); // "Copy" popup option.
+const char* const OPTION_PASTE("option-paste"); // "Paste" popup option.
+const char* const OPTION_CLIPBOARD("option-clipboard"); // "Clipboard" popup option.
+
+} // namespace
+
+//// Comparison function for ButtonRequirement Priority
+//bool TextSelectionPopup::PriorityCompare( ButtonRequirement const& a, ButtonRequirement const& b )
+//{
+// return a.priority < b.priority;
+//}
+
+
+Dali::Toolkit::TextSelectionPopup TextSelectionPopup::New()
+{
+ // Create the implementation, temporarily owned by this handle on stack
+ IntrusivePtr< TextSelectionPopup > impl = new TextSelectionPopup();
+
+ // Pass ownership to CustomActor handle
+ Dali::Toolkit::TextSelectionPopup 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 TextSelectionPopup::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+ Toolkit::TextSelectionPopup selectionPopup = Toolkit::TextSelectionPopup::DownCast( Dali::BaseHandle( object ) );
+
+ if( selectionPopup )
+ {
+ TextSelectionPopup& impl( GetImpl( selectionPopup ) );
+
+ switch( index )
+ {
+ case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
+ {
+ impl.SetPopupMaxSize( value.Get< Vector2 >() );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_BACKGROUND_IMAGE:
+ {
+ ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ impl.SetPopupImage( POPUP_BACKGROUND, image );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ impl.SetPopupImage( POPUP_CLIPBOARD_BUTTON, image );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ impl.SetPopupImage( POPUP_CUT_BUTTON_ICON, image );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ impl.SetPopupImage( POPUP_COPY_BUTTON_ICON, image );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ impl.SetPopupImage( POPUP_PASTE_BUTTON_ICON, image );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ impl.SetPopupImage( POPUP_SELECT_BUTTON_ICON, image );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ impl.SetPopupImage( POPUP_SELECT_ALL_BUTTON_ICON, image );
+ break;
+ }
+ } // switch
+ } // TextSelectionPopup
+}
+
+Property::Value TextSelectionPopup::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::TextSelectionPopup selectionPopup = Toolkit::TextSelectionPopup::DownCast( Dali::BaseHandle( object ) );
+
+ if( selectionPopup )
+ {
+ TextSelectionPopup& impl( GetImpl( selectionPopup ) );
+
+ switch( index )
+ {
+ case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
+ {
+ value = impl.GetPopupMaxSize();
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_BACKGROUND_IMAGE:
+ {
+ ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_BACKGROUND ) );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_CLIPBOARD_BUTTON ) );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_CUT_BUTTON_ICON ) );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_COPY_BUTTON_ICON ) );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_PASTE_BUTTON_ICON ) );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_SELECT_BUTTON_ICON ) );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
+ {
+ ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_SELECT_ALL_BUTTON_ICON ) );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ break;
+ }
+ } // switch
+ }
+ return value;
+}
+
+void TextSelectionPopup::OnInitialize()
+{
+ CreatePopup();
+}
+
+void TextSelectionPopup::OnRelayout( const Vector2& size, RelayoutContainer& container )
+{
+
+}
+
+void TextSelectionPopup::SetPopupMaxSize( const Size& maxSize )
+{
+ mMaxSize = maxSize;
+}
+
+const Dali::Vector2& TextSelectionPopup::GetPopupMaxSize() const
+{
+ return mMaxSize;
+}
+
+void TextSelectionPopup::SetPopupImage( PopupParts part, Dali::Image image )
+{
+ switch ( part )
+ {
+ case POPUP_BACKGROUND :
+ {
+ mBackgroundImage = image;
+ }
+ break;
+ case POPUP_CLIPBOARD_BUTTON :
+ {
+ mClipboardIconImage = image;
+ }
+ break;
+ case POPUP_CUT_BUTTON_ICON :
+ {
+ mCutIconImage = image;
+ }
+ break;
+ case POPUP_COPY_BUTTON_ICON :
+ {
+ mCopyIconImage = image;
+ }
+ break;
+ case POPUP_PASTE_BUTTON_ICON :
+ {
+ mPasteIconImage = image;
+ }
+ break;
+ case POPUP_SELECT_BUTTON_ICON :
+ {
+ mSelectIconImage = image;
+ }
+ break;
+ case POPUP_SELECT_ALL_BUTTON_ICON :
+ {
+ mSelectAllIconImage = image;
+ }
+ break;
+
+ } // switch
+}
+
+Dali::Image TextSelectionPopup::GetPopupImage( PopupParts part )
+{
+ switch ( part )
+ {
+ case POPUP_BACKGROUND :
+ {
+ return mBackgroundImage;
+ }
+ break;
+ case POPUP_CLIPBOARD_BUTTON :
+ {
+ return mClipboardIconImage;
+ }
+ break;
+ case POPUP_CUT_BUTTON_ICON :
+ {
+ return mCutIconImage;
+ }
+ break;
+ case POPUP_COPY_BUTTON_ICON :
+ {
+ return mCopyIconImage;
+ }
+ break;
+ case POPUP_PASTE_BUTTON_ICON :
+ {
+ return mPasteIconImage;
+ }
+ break;
+ case POPUP_SELECT_BUTTON_ICON :
+ {
+ return mSelectIconImage;
+ }
+ break;
+ case POPUP_SELECT_ALL_BUTTON_ICON :
+ {
+ return mSelectAllIconImage;
+ }
+ break;
+ default :
+ {
+ DALI_ASSERT_DEBUG( "Unknown Popup Part" );
+ }
+ } // switch
+
+ return Dali::Image();
+}
+
+ void TextSelectionPopup::CreateOrderedListOfPopupOptions()
+ {
+ mOrderListOfButtons.clear();
+
+ // Create button for each possible option using Option priority
+ if ( !mCutIconImage )
+ {
+ mCutIconImage = ResourceImage::New( OPTION_ICON_CUT );
+ }
+ mOrderListOfButtons.push_back( ButtonRequirement( ButtonsCut, mCutOptionPriority, OPTION_CUT, GET_LOCALE_TEXT("IDS_COM_BODY_CUT"), mCutIconImage, true ) );
+
+ if ( !mCopyIconImage )
+ {
+ mCopyIconImage = ResourceImage::New( OPTION_ICON_COPY );
+ }
+ mOrderListOfButtons.push_back( ButtonRequirement( ButtonsCopy, mCopyOptionPriority, OPTION_COPY, GET_LOCALE_TEXT("IDS_COM_BODY_COPY"), mCopyIconImage, true ) );
+
+ if ( !mPasteIconImage )
+ {
+ mPasteIconImage = ResourceImage::New( OPTION_ICON_PASTE );
+ }
+ mOrderListOfButtons.push_back( ButtonRequirement( ButtonsPaste, mPasteOptionPriority, OPTION_PASTE, GET_LOCALE_TEXT("IDS_COM_BODY_PASTE"), mPasteIconImage, true ) );
+
+ if ( !mSelectIconImage )
+ mSelectIconImage = ResourceImage::New( OPTION_ICON_SELECT );
+ mOrderListOfButtons.push_back( ButtonRequirement( ButtonsSelect, mSelectOptionPriority, OPTION_SELECT_WORD, GET_LOCALE_TEXT("IDS_COM_SK_SELECT"), mSelectIconImage, true ) );
+
+ if ( !mSelectAllIconImage )
+ {
+ mSelectAllIconImage = ResourceImage::New( OPTION_ICON_SELECT_ALL );
+ }
+ mOrderListOfButtons.push_back( ButtonRequirement( ButtonsSelectAll, mSelectAllOptionPriority, OPTION_SELECT_ALL, GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL"), mSelectAllIconImage, true ) );
+
+ if ( !mClipboardIconImage )
+ {
+ mClipboardIconImage = ResourceImage::New( OPTION_ICON_CLIPBOARD );
+ }
+ mOrderListOfButtons.push_back( ButtonRequirement( ButtonsClipboard, mClipboardOptionPriority, OPTION_CLIPBOARD, GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD"), mClipboardIconImage, true ) );
+
+ // Sort the buttons according their priorities.
+ std::sort( mOrderListOfButtons.begin(), mOrderListOfButtons.end(), TextSelectionPopup::ButtonPriorityCompare() );
+ }
+
+ void TextSelectionPopup::CreateBackground()
+ {
+ if ( !mBackgroundImage )
+ {
+ mBackgroundImage = ResourceImage::New( DEFAULT_POPUP_BACKGROUND_IMAGE );
+ }
+
+ NinePatchImage backgroundImageNinePatch = NinePatchImage::DownCast( mBackgroundImage );
+ if( backgroundImageNinePatch )
+ {
+ const Size ninePatchImageSize = Size( static_cast<float>( mBackgroundImage.GetWidth() ), static_cast<float>( mBackgroundImage.GetHeight() ) );
+ Rect<int> childRect = backgroundImageNinePatch.GetChildRectangle();
+
+ // -1u because of the cropping.
+ mNinePatchMargins.x = childRect.x - 1u;
+ mNinePatchMargins.y = ninePatchImageSize.width - ( childRect.x + childRect.width ) - 1u;
+ mNinePatchMargins.z = childRect.y - 1u;
+ mNinePatchMargins.w = ninePatchImageSize.height - ( childRect.y + childRect.height ) - 1u;
+ }
+
+ SetBackgroundImage( mBackgroundImage );
+ SetBackgroundColor( mBackgroundColor );
+ }
+
+ void TextSelectionPopup::AddOption( Actor& parent, const std::string& name, const std::string& caption, const Image iconImage, bool finalOption, bool showIcons )
+ {
+ // 1. Create the backgrounds for the popup option both normal and pressed.
+ // Both containers will be added to a button.
+ Actor optionContainer = Actor::New();
+ optionContainer.SetRelayoutEnabled( true );
+ optionContainer.SetResizePolicy( FIXED, ALL_DIMENSIONS );
+ optionContainer.SetDrawMode( DrawMode::OVERLAY );
+ optionContainer.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ ImageActor optionPressedContainer = Toolkit::CreateSolidColorActor( mBackgroundPressedColor );
+ optionPressedContainer.SetResizePolicy( FIXED, ALL_DIMENSIONS );
+ optionPressedContainer.SetDrawMode( DrawMode::OVERLAY );
+ optionPressedContainer.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ // 2. Add text.
+ Toolkit::TextLabel captionTextLabel = Toolkit::TextLabel::New();
+ captionTextLabel.SetResizePolicy( FIXED, ALL_DIMENSIONS );
+ captionTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, caption );
+ // optionContainer.Add( captionTextLabel ); Temporary removed.
+
+ Toolkit::TextLabel pressedCaptionTextLabel = Toolkit::TextLabel::New();
+ pressedCaptionTextLabel.SetResizePolicy( FIXED, ALL_DIMENSIONS );
+ pressedCaptionTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, caption );
+ // optionPressedContainer.Add( pressedCaptionTextLabel ); Temporary removed.
+
+ // Calculates the icon/text position.
+ float iconTextOffsetY = 0.0f;
+
+ if ( showIcons )
+ {
+ // 3. Create the icons
+ ImageActor pressedIcon = ImageActor::New( iconImage );
+ ImageActor icon = ImageActor::New( iconImage );
+
+ optionContainer.Add( icon );
+ optionPressedContainer.Add( pressedIcon );
+
+ iconTextOffsetY = 0.5f * ( ( DEFAULT_POPUP_MAX_SIZE.height - mNinePatchMargins.z - mNinePatchMargins.w ) - ( OPTION_ICON_SIZE.height + OPTION_GAP_ICON_TEXT + OPTION_TEXT_LINE_HEIGHT ) );
+
+ icon.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ icon.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ icon.SetY( iconTextOffsetY );
+
+ pressedIcon.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ pressedIcon.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ pressedIcon.SetY( iconTextOffsetY );
+
+ // Layout icon + gap + text
+ captionTextLabel.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
+ pressedCaptionTextLabel.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
+ pressedCaptionTextLabel.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
+ captionTextLabel.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
+ pressedCaptionTextLabel.SetY( -iconTextOffsetY );
+ captionTextLabel.SetY( -iconTextOffsetY );
+ }
+ else
+ {
+ // Centre option text
+ captionTextLabel.SetAnchorPoint( AnchorPoint::CENTER );
+ captionTextLabel.SetParentOrigin( ParentOrigin::CENTER );
+ pressedCaptionTextLabel.SetAnchorPoint( AnchorPoint::CENTER );
+ pressedCaptionTextLabel.SetParentOrigin( ParentOrigin::CENTER );
+ }
+
+ // Calculate the size of the text.
+ Vector3 textSize = captionTextLabel.GetNaturalSize();
+ textSize.width = std::min( textSize.width, OPTION_MAX_WIDTH - 2.f * OPTION_MARGIN_WIDTH );
+
+ // Set the size to the text. Text will be ellipsized if exceeds the max width.
+ captionTextLabel.SetSize( textSize.GetVectorXY() );
+ pressedCaptionTextLabel.SetSize( textSize.GetVectorXY() );
+
+ // 4. Calculate the size of option.
+
+ // The width is the max size of the text or the icon plus the margins clamped between the option min and max size.
+ // The height is the whole popup height minus the ninepatch margins.
+ const Vector2 optionSize( std::min( OPTION_MAX_WIDTH, std::max( OPTION_MIN_WIDTH, std::max( textSize.width, OPTION_ICON_SIZE.width ) + 2.f * OPTION_MARGIN_WIDTH ) ),
+ DEFAULT_POPUP_MAX_SIZE.height - mNinePatchMargins.z - mNinePatchMargins.w );
+
+ optionContainer.SetSize( optionSize );
+ optionPressedContainer.SetSize( optionSize );
+
+ // 5. Create a option.
+ Toolkit::PushButton option = Toolkit::PushButton::New();
+ option.SetResizePolicy( FIXED, ALL_DIMENSIONS );
+ option.SetSize( optionSize );
+ option.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ option.SetX( mContentSize.width );
+ option.SetName( name );
+ option.SetAnimationTime( 0.0f );
+ //option.ClickedSignal().Connect( this, &TextInputPopup::OnButtonPressed );
+
+ parent.Add( option );
+
+ // 6. Set the normal option image.
+ option.SetButtonImage( optionContainer );
+
+ // 7. Set the pressed option image
+ option.SetSelectedImage( optionPressedContainer );
+
+ // 8. Update the content size.
+ mContentSize.width += optionSize.width;
+ mContentSize.height = std::max ( optionSize.height, mContentSize.height );
+
+ // 9. Add the divider
+ if( !finalOption )
+ {
+ const Size size( POPUP_DIVIDER_WIDTH, mContentSize.height );
+
+ ImageActor divider = Toolkit::CreateSolidColorActor( Color::WHITE );
+ divider.SetResizePolicy( FIXED, ALL_DIMENSIONS );
+ divider.SetSize( size );
+ divider.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ divider.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ divider.SetPosition( mContentSize.width - POPUP_DIVIDER_WIDTH, 0.0f );
+ parent.Add( divider );
+ }
+ }
+
+ void TextSelectionPopup::SetUpPopup( Size& size )
+ {
+ Actor self = Self();
+
+ // Create Layer and Stencil.
+ mStencilLayer = Layer::New();
+ ImageActor stencil = CreateSolidColorActor( Color::RED );
+ stencil.SetDrawMode( DrawMode::STENCIL );
+ stencil.SetVisible( true );
+ Actor scrollview = Actor::New(); //todo make a scrollview
+ stencil.SetRelayoutEnabled( true );
+
+ self.SetResizePolicy( FIXED, ALL_DIMENSIONS );
+ self.SetSize( mRequiredPopUpSize ); // control matches stencil size
+
+ mStencilLayer.SetResizePolicy( FIXED, ALL_DIMENSIONS );
+ mStencilLayer.SetSize( size ); // matches stencil size
+
+ stencil.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
+ scrollview.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
+ mButtons.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
+
+ mStencilLayer.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+ scrollview.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+ mButtons.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ mStencilLayer.SetPosition( mNinePatchMargins.x, mNinePatchMargins.y );
+
+ self.Add( mStencilLayer );
+ mStencilLayer.Add( stencil );
+ mStencilLayer.Add( scrollview );
+ scrollview.Add( mButtons );
+ }
+
+ void TextSelectionPopup::AddPopupOptions( bool createTail, bool showIcons )
+ {
+ mShowIcons = showIcons;
+
+ mContentSize = Vector2::ZERO;
+
+ mButtons = Actor::New();
+ mButtons.SetRelayoutEnabled( true );
+
+ // Add the options into the buttons container.
+
+ // 1. Determine how many buttons are active and should be added to container.
+ std::size_t numberOfOptions = 0u;
+ for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
+ {
+ const ButtonRequirement& button( *it );
+ if( button.enabled )
+ {
+ ++numberOfOptions;
+ }
+ }
+
+ // 2. Iterate list of buttons and add active ones.
+ std::size_t optionsAdded = 0u;
+ for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
+ {
+ const ButtonRequirement& button( *it );
+ if ( button.enabled )
+ {
+ ++optionsAdded;
+ AddOption( mButtons, button.name, button.caption, button.icon, optionsAdded == numberOfOptions, mShowIcons );
+ }
+ }
+
+ // Calculate the size of the whole popup which may not be all visible.
+ mRequiredPopUpSize = Size( std::min( mMaxSize.width, mContentSize.width + mNinePatchMargins.x + mNinePatchMargins.y ), DEFAULT_POPUP_MAX_SIZE.height );
+
+ // Size of the contents within the popup
+ mVisiblePopUpSize = Size( mRequiredPopUpSize.width - mNinePatchMargins.x - mNinePatchMargins.y, mRequiredPopUpSize.height - mNinePatchMargins.z - mNinePatchMargins.w );
+ }
+
+ void TextSelectionPopup::CreatePopup()
+ {
+ if ( !mStencilLayer )
+ {
+ CreateOrderedListOfPopupOptions(); //todo Currently causes all options to be shown
+ CreateBackground();
+ AddPopupOptions( true, true );
+ SetUpPopup( mVisiblePopUpSize );
+ }
+
+ mStencilLayer.RaiseToTop();
+ }
+
+TextSelectionPopup::TextSelectionPopup()
+: Control( ControlBehaviour( CONTROL_BEHAVIOUR_NONE ) ),
+ mMaxSize ( DEFAULT_POPUP_MAX_SIZE ),
+ mVisiblePopUpSize( DEFAULT_POPUP_MAX_SIZE ),
+ mRequiredPopUpSize( DEFAULT_POPUP_MAX_SIZE ),
+ 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 ),
+ mShowIcons( true )
+{
+}
+
+TextSelectionPopup::~TextSelectionPopup()
+{
+}
+
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_POPUP_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_POPUP_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-selection-popup.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/actors/image-actor.h>
+#include <dali/public-api/actors/layer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+enum PopupParts
+{
+ POPUP_BACKGROUND,
+ POPUP_CLIPBOARD_BUTTON,
+ POPUP_CUT_BUTTON_ICON,
+ POPUP_COPY_BUTTON_ICON,
+ POPUP_PASTE_BUTTON_ICON,
+ POPUP_SELECT_BUTTON_ICON,
+ POPUP_SELECT_ALL_BUTTON_ICON,
+};
+
+} // namespace
+
+class TextSelectionPopup : public Control
+{
+public:
+
+ enum Buttons
+ {
+ ButtonsCut,
+ ButtonsCopy,
+ ButtonsPaste,
+ ButtonsSelect,
+ ButtonsSelectAll,
+ ButtonsClipboard,
+ ButtonsEnumEnd
+ };
+
+ struct ButtonRequirement
+ {
+ ButtonRequirement()
+ : id( ButtonsEnumEnd ),
+ priority( 0u ),
+ name(),
+ caption(),
+ icon(),
+ enabled( false )
+ {}
+
+ ButtonRequirement( Buttons buttonId,
+ std::size_t buttonPriority,
+ const std::string& buttonName,
+ const std::string& buttonCaption,
+ Dali::Image& buttonIcon,
+ bool buttonEnabled )
+ : id( buttonId ),
+ priority( buttonPriority ),
+ name( buttonName ),
+ caption( buttonCaption ),
+ icon( buttonIcon ),
+ enabled( buttonEnabled )
+ {}
+
+ Buttons id;
+ std::size_t priority;
+ std::string name;
+ std::string caption;
+ Dali::Image icon;
+ bool enabled;
+ };
+
+ struct ButtonPriorityCompare
+ {
+ bool operator()( const ButtonRequirement& lhs, const ButtonRequirement& rhs ) const {
+ return lhs.priority < rhs.priority;
+ }
+ };
+
+// static inline bool ButtonPriorityCompare( ButtonRequirement a, ButtonRequirement b )
+// {
+// return a.priority < b.priority ? true : false;
+// }
+
+ /**
+ * @copydoc Dali::Toollkit::TextSelectionPopup::New()
+ */
+ static Toolkit::TextSelectionPopup New();
+
+ // Properties
+
+ /**
+ * @brief 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 );
+
+ /**
+ * @brief 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 );
+
+ void CreatePopup();
+
+ void DestroyPopup();
+
+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, RelayoutContainer& container );
+//
+// /**
+// * Received for single & double taps
+// */
+// virtual void OnTap( const TapGesture& tap );
+//
+// /**
+// * @copydoc Text::ControlInterface::RequestTextRelayout()
+// */
+// virtual void RequestTextRelayout();
+
+ /**
+ * Set max size of Popup
+ * @param[in] maxSize Size (Vector2)
+ */
+ void SetPopupMaxSize( const Size& maxSize );
+
+ /**
+ * Get Max size of Popup
+ * @return Vector2 the max size of the Popup
+ */
+ const Dali::Vector2& GetPopupMaxSize() const;
+
+ /**
+ * @brief Sets the image for the given part of the Popup.
+ *
+ * @param[in] part The part of the pop from the Enum PopupParts
+ * @param[in] image The image to use.
+ */
+ void SetPopupImage( PopupParts part, Dali::Image image );
+
+ /**
+ * @brief Retrieves the image of the given part used by the popup
+ *
+ * @param[in] part The part of the popup
+ * @return The image used for that part.
+ */
+ Dali::Image GetPopupImage( PopupParts part );
+
+ void CreateOrderedListOfPopupOptions();
+
+ void CreateBackground();
+
+ void AddOption( Actor& parent, const std::string& name, const std::string& caption, const Image iconImage, bool finalOption, bool showIcons );
+
+ void SetUpPopup( Size& size );
+
+ void AddPopupOptions( bool createTail, bool showIcons );
+
+private: // Implementation
+
+ /**
+ * Construct a new TextField.
+ */
+ TextSelectionPopup();
+
+ /**
+ * A reference counted object may only be deleted by calling Unreference()
+ */
+ virtual ~TextSelectionPopup();
+
+private:
+
+ // Undefined copy constructor and assignment operators
+ TextSelectionPopup(const TextSelectionPopup&);
+ TextSelectionPopup& operator=(const TextSelectionPopup& rhs);
+
+private: // Data
+
+ Actor mButtons; // Actor which holds all the buttons, sensitivity can be set oActor buttons via this actor
+ Layer mStencilLayer; // Layer to enable clipping when buttons exceed popup
+
+ // Images to be used by the Popup
+ Image mBackgroundImage;
+ Image mCutIconImage;
+ Image mCopyIconImage;
+ Image mPasteIconImage;
+ Image mClipboardIconImage;
+ Image mSelectIconImage;
+ Image mSelectAllIconImage;
+
+ ImageActor mBackground; // The background popup panel
+ ImageActor mTail; // The tail for the popup
+ ImageActor mTailEffect; //todo remove // the tail effect
+ ImageActor mTailLine; //todo remove // The border/outline around the tail
+
+ Size mMaxSize; // Max size of the Popup
+ Size mVisiblePopUpSize; // Visible Size of popup excluding content that needs scrolling.
+ Size mRequiredPopUpSize; // Total size of popup including any invisible margin
+
+ Vector4 mNinePatchMargins; // Margins between the edge of the cropped image and the nine patch rect (left, right, top, bottom).
+
+ Size mContentSize; // Size of Content (i.e. Buttons)
+ //Animation mAnimation; // Popup Hide/Show animation.
+
+ 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
+
+ bool mShowIcons; // Flag to show icons
+
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Toolkit::Internal::TextSelectionPopup& GetImpl( Toolkit::TextSelectionPopup& textSelectionPopup )
+{
+ DALI_ASSERT_ALWAYS( textSelectionPopup );
+
+ Dali::RefObject& handle = textSelectionPopup.GetImplementation();
+
+ return static_cast<Toolkit::Internal::TextSelectionPopup&>(handle);
+}
+
+inline const Toolkit::Internal::TextSelectionPopup& GetImpl( const Toolkit::TextSelectionPopup& textSelectionPopup )
+{
+ DALI_ASSERT_ALWAYS( textSelectionPopup );
+
+ const Dali::RefObject& handle = textSelectionPopup.GetImplementation();
+
+ return static_cast<const Toolkit::Internal::TextSelectionPopup&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_POPUP_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.SetOrientation( 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::WORLD_POSITION_X, LessThanCondition( mBoundingRectangleWorldCoordinates.x + handlesize.x) );
- leftNotification.NotifySignal().Connect( this, &Decorator::OnLeftBoundaryExceeded );
-
- PropertyNotification rightNotification = selectionHandleTwo.AddPropertyNotification( Actor::Property::WORLD_POSITION_X, GreaterThanCondition( mBoundingRectangleWorldCoordinates.z - handlesize.x ) );
- rightNotification.NotifySignal().Connect( this, &Decorator::OnRightBoundaryExceeded );
-
- // Within horizontal boundary
- PropertyNotification leftLeaveNotification = selectionHandleOne.AddPropertyNotification( Actor::Property::WORLD_POSITION_X, GreaterThanCondition( mBoundingRectangleWorldCoordinates.x + 2*handlesize.x ) );
- leftLeaveNotification.NotifySignal().Connect( this, &Decorator::OnReturnToLeftBoundary );
-
- PropertyNotification rightLeaveNotification = selectionHandleTwo.AddPropertyNotification( Actor::Property::WORLD_POSITION_X, LessThanCondition( mBoundingRectangleWorldCoordinates.z - 2*handlesize.x ) );
- rightLeaveNotification.NotifySignal().Connect( this, &Decorator::OnReturnToRightBoundary );
-
- // Exceeding vertical boundary
- PropertyNotification verticalExceedNotificationOne = selectionHandleOne.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
- OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalExceedNotificationOne.NotifySignal().Connect( this, &Decorator::OnHandleOneLeavesBoundary );
-
- PropertyNotification verticalExceedNotificationTwo = selectionHandleTwo.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
- OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalExceedNotificationTwo.NotifySignal().Connect( this, &Decorator::OnHandleTwoLeavesBoundary );
-
- // Within vertical boundary
- PropertyNotification verticalWithinNotificationOne = selectionHandleOne.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
- InsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalWithinNotificationOne.NotifySignal().Connect( this, &Decorator::OnHandleOneWithinBoundary );
-
- PropertyNotification verticalWithinNotificationTwo = selectionHandleTwo.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
- 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::WORLD_POSITION_Y,
- 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.SetResizePolicy( SIZE_RELATIVE_TO_PARENT, ALL_DIMENSIONS );
- 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/type-registry-helper.h>
-#include <dali/public-api/object/property-notification.h>
-#include <dali/public-api/size-negotiation/relayout-container.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 char* const 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
-{
-
-namespace Internal
-{
-
-namespace // Unnamed namespace
-{
-
-BaseHandle Create()
-{
- return Toolkit::TextInput::New();
-}
-
-// Setup properties, signals and actions using the type-registry.
-DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextInput, Toolkit::Control, Create )
-
-DALI_PROPERTY_REGISTRATION( TextInput, "highlight-color", VECTOR4, HIGHLIGHT_COLOR )
-DALI_PROPERTY_REGISTRATION( TextInput, "cut-and-paste-bg-color", VECTOR4, CUT_AND_PASTE_COLOR )
-DALI_PROPERTY_REGISTRATION( TextInput, "cut-and-paste-pressed-color", VECTOR4, CUT_AND_PASTE_PRESSED_COLOR )
-DALI_PROPERTY_REGISTRATION( TextInput, "cut-and-paste-border-color", VECTOR4, CUT_AND_PASTE_BORDER_COLOR )
-DALI_PROPERTY_REGISTRATION( TextInput, "cut-and-paste-icon-color", VECTOR4, CUT_AND_PASTE_ICON_COLOR )
-DALI_PROPERTY_REGISTRATION( TextInput, "cut-and-paste-icon-pressed-color", VECTOR4, CUT_AND_PASTE_ICON_PRESSED_COLOR )
-DALI_PROPERTY_REGISTRATION( TextInput, "cut-and-paste-text-color", VECTOR4, CUT_AND_PASTE_TEXT_COLOR )
-DALI_PROPERTY_REGISTRATION( TextInput, "cut-and-paste-text-pressed-color", VECTOR4, CUT_AND_PASTE_TEXT_PRESSED_COLOR )
-DALI_PROPERTY_REGISTRATION( TextInput, "cut-button-position-priority", UNSIGNED_INTEGER, CUT_BUTTON_POSITION_PRIORITY )
-DALI_PROPERTY_REGISTRATION( TextInput, "copy-button-position-priority", UNSIGNED_INTEGER, COPY_BUTTON_POSITION_PRIORITY )
-DALI_PROPERTY_REGISTRATION( TextInput, "paste-button-position-priority", UNSIGNED_INTEGER, PASTE_BUTTON_POSITION_PRIORITY )
-DALI_PROPERTY_REGISTRATION( TextInput, "select-button-position-priority", UNSIGNED_INTEGER, SELECT_BUTTON_POSITION_PRIORITY )
-DALI_PROPERTY_REGISTRATION( TextInput, "select-all-button-position-priority", UNSIGNED_INTEGER, SELECT_ALL_BUTTON_POSITION_PRIORITY )
-DALI_PROPERTY_REGISTRATION( TextInput, "clipboard-button-position-priority", UNSIGNED_INTEGER, CLIPBOARD_BUTTON_POSITION_PRIORITY )
-DALI_PROPERTY_REGISTRATION( TextInput, "popup-offset-from-text", VECTOR4, POP_UP_OFFSET_FROM_TEXT )
-DALI_PROPERTY_REGISTRATION( TextInput, "cursor-color", VECTOR4, CURSOR_COLOR )
-
-DALI_SIGNAL_REGISTRATION( TextInput, "start-input", SIGNAL_START_INPUT )
-DALI_SIGNAL_REGISTRATION( TextInput, "end-input", SIGNAL_END_INPUT )
-DALI_SIGNAL_REGISTRATION( TextInput, "style-changed", SIGNAL_STYLE_CHANGED )
-DALI_SIGNAL_REGISTRATION( TextInput, "max-input-characters-reached", SIGNAL_MAX_INPUT_CHARACTERS_REACHED )
-DALI_SIGNAL_REGISTRATION( TextInput, "toolbar-displayed", SIGNAL_TOOLBAR_DISPLAYED )
-DALI_SIGNAL_REGISTRATION( TextInput, "text-exceed-boundaries", SIGNAL_TEXT_EXCEED_BOUNDARIES )
-
-DALI_TYPE_REGISTRATION_END()
-
-}
-
-// [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, RelayoutContainer& container )
-{
- container.Add( mDisplayedTextView, size );
- container.Add( mPopupPanel.GetRootActor(), size );
-
- 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.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.SetOrientation( 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.SetResizePolicy( SIZE_RELATIVE_TO_PARENT, ALL_DIMENSIONS );
- 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::WORLD_POSITION_X, LessThanCondition( mBoundingRectangleWorldCoordinates.x + handlesize.x) );
- leftNotification.NotifySignal().Connect( this, &TextInput::OnLeftBoundaryExceeded );
-
- PropertyNotification rightNotification = mSelectionHandleTwo.AddPropertyNotification( Actor::Property::WORLD_POSITION_X, GreaterThanCondition( mBoundingRectangleWorldCoordinates.z - handlesize.x ) );
- rightNotification.NotifySignal().Connect( this, &TextInput::OnRightBoundaryExceeded );
-
- // Within horizontal boundary
- PropertyNotification leftLeaveNotification = mSelectionHandleOne.AddPropertyNotification( Actor::Property::WORLD_POSITION_X, GreaterThanCondition( mBoundingRectangleWorldCoordinates.x + 2*handlesize.x ) );
- leftLeaveNotification.NotifySignal().Connect( this, &TextInput::OnReturnToLeftBoundary );
-
- PropertyNotification rightLeaveNotification = mSelectionHandleTwo.AddPropertyNotification( Actor::Property::WORLD_POSITION_X, LessThanCondition( mBoundingRectangleWorldCoordinates.z - 2*handlesize.x ) );
- rightLeaveNotification.NotifySignal().Connect( this, &TextInput::OnReturnToRightBoundary );
-
- // Exceeding vertical boundary
- PropertyNotification verticalExceedNotificationOne = mSelectionHandleOne.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
- OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalExceedNotificationOne.NotifySignal().Connect( this, &TextInput::OnHandleOneLeavesBoundary );
-
- PropertyNotification verticalExceedNotificationTwo = mSelectionHandleTwo.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
- OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalExceedNotificationTwo.NotifySignal().Connect( this, &TextInput::OnHandleTwoLeavesBoundary );
-
- // Within vertical boundary
- PropertyNotification verticalWithinNotificationOne = mSelectionHandleOne.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
- InsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
- mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
- verticalWithinNotificationOne.NotifySignal().Connect( this, &TextInput::OnHandleOneWithinBoundary );
-
- PropertyNotification verticalWithinNotificationTwo = mSelectionHandleTwo.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
- 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.SetResizePolicy( SIZE_RELATIVE_TO_PARENT, ALL_DIMENSIONS );
- 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.SetResizePolicy( SIZE_RELATIVE_TO_PARENT, ALL_DIMENSIONS );
- 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::Property::HIGHLIGHT_COLOR:
- {
- textInputImpl.SetMaterialDiffuseColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_COLOR:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_PRESSED_COLOR:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupPressedColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_BORDER_COLOR:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupBorderColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_ICON_COLOR:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupIconColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_ICON_PRESSED_COLOR:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupIconPressedColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_TEXT_COLOR:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupTextColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_TEXT_PRESSED_COLOR:
- {
- textInputImpl.mPopupPanel.SetCutPastePopupTextPressedColor( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::Property::CUT_BUTTON_POSITION_PRIORITY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCut, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::Property::COPY_BUTTON_POSITION_PRIORITY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCopy, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::Property::PASTE_BUTTON_POSITION_PRIORITY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsPaste, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::Property::SELECT_BUTTON_POSITION_PRIORITY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelect, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::Property::SELECT_ALL_BUTTON_POSITION_PRIORITY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::Property::CLIPBOARD_BUTTON_POSITION_PRIORITY:
- {
- textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsClipboard, value.Get<unsigned int>() );
- break;
- }
- case Toolkit::TextInput::Property::POP_UP_OFFSET_FROM_TEXT:
- {
- textInputImpl.SetOffsetFromText( value.Get< Vector4 >() );
- break;
- }
- case Toolkit::TextInput::Property::CURSOR_COLOR:
- {
- textInputImpl.mCursor.SetColor( value.Get< Vector4 >() );
- break;
- }
- }
- }
-}
-
-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::Property::HIGHLIGHT_COLOR:
- {
- value = textInputImpl.GetMaterialDiffuseColor();
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_COLOR:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupColor();
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_PRESSED_COLOR:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupPressedColor();
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_BORDER_COLOR :
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupBorderColor();
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_ICON_COLOR:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupIconColor();
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_ICON_PRESSED_COLOR:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupIconPressedColor();
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_TEXT_COLOR:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupTextColor();
- break;
- }
- case Toolkit::TextInput::Property::CUT_AND_PASTE_TEXT_PRESSED_COLOR:
- {
- value = textInputImpl.mPopupPanel.GetCutPastePopupTextPressedColor();
- break;
- }
- case Toolkit::TextInput::Property::CUT_BUTTON_POSITION_PRIORITY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCut );
- break;
- }
- case Toolkit::TextInput::Property::COPY_BUTTON_POSITION_PRIORITY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCopy );
- break;
- }
- case Toolkit::TextInput::Property::PASTE_BUTTON_POSITION_PRIORITY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsPaste );
- break;
- }
- case Toolkit::TextInput::Property::SELECT_BUTTON_POSITION_PRIORITY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelect );
- break;
- }
- case Toolkit::TextInput::Property::SELECT_ALL_BUTTON_POSITION_PRIORITY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll );
- break;
- }
- case Toolkit::TextInput::Property::CLIPBOARD_BUTTON_POSITION_PRIORITY:
- {
- value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsClipboard );
- break;
- }
- case Toolkit::TextInput::Property::POP_UP_OFFSET_FROM_TEXT:
- {
- value = textInputImpl.GetOffsetFromText();
- break;
- }
- case Toolkit::TextInput::Property::CURSOR_COLOR:
- {
- 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:
-
- /**
- * 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, RelayoutContainer& 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 char* const POPUP_BACKGROUND = DALI_IMAGE_DIR "popup_bubble_bg.#.png";
-const char* const POPUP_BACKGROUND_EFFECT = DALI_IMAGE_DIR "popup_bubble_bg_ef.#.png";
-const char* const POPUP_BACKGROUND_LINE = DALI_IMAGE_DIR "popup_bubble_bg_line.#.png";
-
-const char* const POPUP_TAIL_BOTTOM = DALI_IMAGE_DIR "popup_bubble_tail_bottom.png";
-const char* const POPUP_TAIL_BOTTOM_EFFECT = DALI_IMAGE_DIR "popup_bubble_tail_bottom_ef.png";
-const char* const POPUP_TAIL_BOTTOM_LINE = DALI_IMAGE_DIR "popup_bubble_tail_bottom_line.png";
-const char* const POPUP_TAIL_TOP = DALI_IMAGE_DIR "popup_bubble_tail_top.png";
-const char* const POPUP_TAIL_TOP_EFFECT = DALI_IMAGE_DIR "popup_bubble_tail_top_ef.png";
-const char* const POPUP_TAIL_TOP_LINE = DALI_IMAGE_DIR "popup_bubble_tail_top_line.png";
-
-const char* const OPTION_ICON_CLIPBOARD = DALI_IMAGE_DIR "copy_paste_icon_clipboard.png";
-const char* const OPTION_ICON_COPY = DALI_IMAGE_DIR "copy_paste_icon_copy.png";
-const char* const OPTION_ICON_CUT = DALI_IMAGE_DIR "copy_paste_icon_cut.png";
-const char* const OPTION_ICON_PASTE = DALI_IMAGE_DIR "copy_paste_icon_paste.png";
-const char* const OPTION_ICON_SELECT = DALI_IMAGE_DIR "copy_paste_icon_select.png";
-const char* const 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.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.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
- 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.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
- 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.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
- 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.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
- 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.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::COLOR_ALPHA), 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::COLOR_ALPHA, 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::COLOR_ALPHA), 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::COLOR_ALPHA, 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 );
- textActor.SetRelayoutEnabled( false );
- }
- 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 );
- }
-
- // Exclude from size negotiation
- textActor.SetRelayoutEnabled( false );
-
- 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/object/type-registry-helper.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
-{
-
-namespace Internal
-{
-
-namespace
-{
-
-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();
-}
-
-// Setup properties, signals and actions using the type-registry.
-DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextView, Toolkit::Control, Create );
-
-DALI_PROPERTY_REGISTRATION( TextView, "markup-enabled", BOOLEAN, MARKUP_ENABLED )
-DALI_PROPERTY_REGISTRATION( TextView, "text", STRING, TEXT )
-DALI_PROPERTY_REGISTRATION( TextView, "multiline-policy", STRING, MULTILINE_POLICY )
-DALI_PROPERTY_REGISTRATION( TextView, "width-exceed-policy", STRING, WIDTH_EXCEED_POLICY )
-DALI_PROPERTY_REGISTRATION( TextView, "height-exceed-policy", STRING, HEIGHT_EXCEED_POLICY )
-DALI_PROPERTY_REGISTRATION( TextView, "line-justification", STRING, LINE_JUSTIFICATION )
-DALI_PROPERTY_REGISTRATION( TextView, "fade-boundary", VECTOR4, FADE_BOUNDARY )
-DALI_PROPERTY_REGISTRATION( TextView, "line-height-offset", FLOAT, LINE_HEIGHT_OFFSET )
-DALI_PROPERTY_REGISTRATION( TextView, "horizontal-alignment", STRING, HORIZONTAL_ALIGNMENT )
-DALI_PROPERTY_REGISTRATION( TextView, "vertical-alignment", STRING, VERTICAL_ALIGNMENT )
-
-DALI_SIGNAL_REGISTRATION( TextView, "scrolled", SIGNAL_TEXT_SCROLLED )
-
-DALI_TYPE_REGISTRATION_END()
-
-/**
- * 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.SetInheritOrientation( 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()
-{
- // The actor handle needs to be inialised for this to work
- Self().SetResizePolicy( USE_NATURAL_SIZE, ALL_DIMENSIONS );
-}
-
-
-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, RelayoutContainer& 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.SetOrientation(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:
-
- /**
- * 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, RelayoutContainer& 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 char* const 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__
}
backgroundImage.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
- backgroundImage.SetRelayoutEnabled( false ); // We will scale its size manually
+ backgroundImage.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
+ backgroundImage.SetSizeScalePolicy( FILL_WITH_ASPECT_RATIO );
mBackgroundLayer.Add( backgroundImage );
RelayoutRequest();
}
}
-void View::OnRelayout( const Vector2& size, RelayoutContainer& container )
-{
- if( mBackgroundLayer )
- {
- if( mBackgroundLayer && mBackgroundLayer.GetChildCount() > 0 )
- {
- Actor background = mBackgroundLayer.GetChildAt(0);
- background.SetScale( FillXYKeepAspectRatio( Vector3( size.width, size.height, 1.0f ), background.GetTargetSize() ) );
- }
- }
-}
-
View::Orientation View::DegreeToViewOrientation( Degree degree )
{
View::Orientation orientation = PORTRAIT;
*/
virtual void OnInitialize();
- /**
- * @copydoc Toolkit::Control::OnRelayout()
- */
- virtual void OnRelayout( const Vector2& size, RelayoutContainer& container );
-
private:
# Add local source files here
toolkit_src_files = \
+ $(toolkit_src_dir)/atlas-manager/atlas-manager.cpp \
+ $(toolkit_src_dir)/atlas-manager/atlas-manager-impl.cpp \
$(toolkit_src_dir)/builder/builder-actor.cpp \
$(toolkit_src_dir)/builder/builder-animations.cpp \
$(toolkit_src_dir)/builder/builder-impl.cpp \
$(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/text-controls/text-selection-popup-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/bidirectional-support.cpp \
+ $(toolkit_src_dir)/text/character-set-conversion.cpp \
+ $(toolkit_src_dir)/text/clipping/text-clipper.cpp \
+ $(toolkit_src_dir)/text/logical-model-impl.cpp \
+ $(toolkit_src_dir)/text/multi-language-support.cpp \
+ $(toolkit_src_dir)/text/segmentation.cpp \
+ $(toolkit_src_dir)/text/shaper.cpp \
+ $(toolkit_src_dir)/text/text-control-interface.cpp \
+ $(toolkit_src_dir)/text/text-controller.cpp \
+ $(toolkit_src_dir)/text/text-io.cpp \
+ $(toolkit_src_dir)/text/text-view.cpp \
+ $(toolkit_src_dir)/text/text-view-interface.cpp \
+ $(toolkit_src_dir)/text/visual-model-impl.cpp \
+ $(toolkit_src_dir)/text/decorator/text-decorator.cpp \
+ $(toolkit_src_dir)/text/layouts/layout-engine.cpp \
+ $(toolkit_src_dir)/text/multi-language-support-impl.cpp \
+ $(toolkit_src_dir)/text/rendering/text-backend.cpp \
+ $(toolkit_src_dir)/text/rendering/text-renderer.cpp \
+ $(toolkit_src_dir)/text/rendering/atlas/text-atlas-renderer.cpp \
+ $(toolkit_src_dir)/text/rendering/atlas/atlas-glyph-manager.cpp \
+ $(toolkit_src_dir)/text/rendering/atlas/atlas-glyph-manager-impl.cpp \
+ $(toolkit_src_dir)/text/rendering/basic/text-basic-renderer.cpp \
+ $(toolkit_src_dir)/text/rendering/shaders/text-basic-shader.cpp \
+ $(toolkit_src_dir)/text/rendering/shaders/text-basic-shadow-shader.cpp \
+ $(toolkit_src_dir)/text/rendering/shaders/text-bgra-shader.cpp \
+ $(toolkit_src_dir)/text/rendering/text-backend-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 \
// EXTERNAL HEADERS
#include <sstream>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/common/stage.h>
// when the vanishing point is very far away(pageHeight*THRESHOLD), make it infinitely, in this case, the page bent horizontally
const float THRESHOLD(20.0);
-struct CommonParametersConstraint
+void CommonParametersConstraint( Matrix& current, const PropertyInputContainer& inputs )
{
- Matrix operator()( const Matrix& current,
- const PropertyInput& originalCenterProperty,
- const PropertyInput& currentCenterProperty,
- const PropertyInput& pageSizeProperty)
+ const Vector2& originalCenter = inputs[0]->GetVector2();
+ Vector2 currentCenter = inputs[1]->GetVector2();
+ const Vector2& pageSize = inputs[2]->GetVector2();
+
+ // calculate the curve direction and the vanishing point
+ // here, the vanishing point is the intersection of spine with the line passing through original center and vertical to curve direction
+ Vector2 curveDirection( currentCenter - originalCenter );
+ curveDirection.Normalize();
+ if( fabs(curveDirection.y) < 0.01f) // eliminate the possibility of division by zero in the next step
{
- const Vector2& originalCenter = originalCenterProperty.GetVector2();
- Vector2 currentCenter = currentCenterProperty.GetVector2();
- const Vector2& pageSize = pageSizeProperty.GetVector2();
-
- // calculate the curve direction and the vanishing point
- // here, the vanishing point is the intersection of spine with the line passing through original center and vertical to curve direction
- Vector2 curveDirection( currentCenter - originalCenter );
- curveDirection.Normalize();
- if( fabs(curveDirection.y) < 0.01f) // eliminate the possibility of division by zero in the next step
- {
- curveDirection.y = 0.01f;
- }
- float vanishingPointY = originalCenter.y + curveDirection.x * originalCenter.x / curveDirection.y;
-
- float curveEndY, cosTheta ,sinTheta ,translateX, translateY;
- // when the vanishing point is very far away, make it infinitely, in this case, the page bent horizontally
- if( fabs(vanishingPointY-pageSize.y*0.5f) >= pageSize.y*THRESHOLD )
- {
- curveDirection = Vector2(-1.f,0.f);
- currentCenter.y = originalCenter.y;
-
- curveEndY = originalCenter.y;
- cosTheta = 1.f;
- sinTheta = 0.f;
- translateX = currentCenter.x - originalCenter.x;
- translateY = vanishingPointY;
- }
- else
- {
- curveEndY = currentCenter.y - curveDirection.y * (currentCenter.x/curveDirection.x) ;
- Vector2 v1( currentCenter.x, currentCenter.y - vanishingPointY );
- v1.Normalize();
- Vector2 v2( originalCenter.x, originalCenter.y - vanishingPointY );
- v2.Normalize();
- cosTheta = v1.x*v2.x + v1.y*v2.y;
- sinTheta = ( vanishingPointY > pageSize.y*0.5f ) ? sqrt(1.0-cosTheta*cosTheta) : -sqrt(1.0-cosTheta*cosTheta);
- translateX = currentCenter.x - cosTheta*originalCenter.x - sinTheta*( originalCenter.y-vanishingPointY );
- translateY = currentCenter.y + sinTheta*originalCenter.x - cosTheta*( originalCenter.y-vanishingPointY );
- }
+ curveDirection.y = 0.01f;
+ }
+ float vanishingPointY = originalCenter.y + curveDirection.x * originalCenter.x / curveDirection.y;
- float originalLength = fabs(originalCenter.x/curveDirection.x);
- float currentLength = fabs(currentCenter.x/curveDirection.x);
- float curveHeight = 0.45f*sqrt(originalLength*originalLength - currentLength*currentLength);
-
- Matrix commonParameters( false );
- float* parameterArray = commonParameters.AsFloat();
- parameterArray[0] = cosTheta;
- parameterArray[1] = -sinTheta;
- parameterArray[2] = originalCenter.x;
- parameterArray[3] = originalCenter.y;
- parameterArray[4] = sinTheta;
- parameterArray[5] = cosTheta;
- parameterArray[6] = currentCenter.x;
- parameterArray[7] = currentCenter.y;
- parameterArray[8] = translateX;
- parameterArray[9] = translateY;
- parameterArray[10] = vanishingPointY;
- parameterArray[11] = curveEndY;
- parameterArray[12] = curveDirection.x;
- parameterArray[13] = curveDirection.y;
- parameterArray[14] = curveHeight;
- parameterArray[15] = currentLength;
-
- return commonParameters;
+ float curveEndY, cosTheta ,sinTheta ,translateX, translateY;
+ // when the vanishing point is very far away, make it infinitely, in this case, the page bent horizontally
+ if( fabs(vanishingPointY-pageSize.y*0.5f) >= pageSize.y*THRESHOLD )
+ {
+ curveDirection = Vector2(-1.f,0.f);
+ currentCenter.y = originalCenter.y;
+
+ curveEndY = originalCenter.y;
+ cosTheta = 1.f;
+ sinTheta = 0.f;
+ translateX = currentCenter.x - originalCenter.x;
+ translateY = vanishingPointY;
+ }
+ else
+ {
+ curveEndY = currentCenter.y - curveDirection.y * (currentCenter.x/curveDirection.x) ;
+ Vector2 v1( currentCenter.x, currentCenter.y - vanishingPointY );
+ v1.Normalize();
+ Vector2 v2( originalCenter.x, originalCenter.y - vanishingPointY );
+ v2.Normalize();
+ cosTheta = v1.x*v2.x + v1.y*v2.y;
+ sinTheta = ( vanishingPointY > pageSize.y*0.5f ) ? sqrt(1.0-cosTheta*cosTheta) : -sqrt(1.0-cosTheta*cosTheta);
+ translateX = currentCenter.x - cosTheta*originalCenter.x - sinTheta*( originalCenter.y-vanishingPointY );
+ translateY = currentCenter.y + sinTheta*originalCenter.x - cosTheta*( originalCenter.y-vanishingPointY );
}
-};
+
+ float originalLength = fabs(originalCenter.x/curveDirection.x);
+ float currentLength = fabs(currentCenter.x/curveDirection.x);
+ float curveHeight = 0.45f*sqrt(originalLength*originalLength - currentLength*currentLength);
+
+ float* parameterArray = current.AsFloat();
+ parameterArray[0] = cosTheta;
+ parameterArray[1] = -sinTheta;
+ parameterArray[2] = originalCenter.x;
+ parameterArray[3] = originalCenter.y;
+ parameterArray[4] = sinTheta;
+ parameterArray[5] = cosTheta;
+ parameterArray[6] = currentCenter.x;
+ parameterArray[7] = currentCenter.y;
+ parameterArray[8] = translateX;
+ parameterArray[9] = translateY;
+ parameterArray[10] = vanishingPointY;
+ parameterArray[11] = curveEndY;
+ parameterArray[12] = curveDirection.x;
+ parameterArray[13] = curveDirection.y;
+ parameterArray[14] = curveHeight;
+ parameterArray[15] = currentLength;
+}
}//namespace
shaderImpl->mOriginalCenterPropertyIndex = handle.RegisterProperty( ORIGINAL_CENTER_PROPERTY_NAME, Vector2( defaultPageSize[0], defaultPageSize[1]*0.5f ) );
shaderImpl->mCurrentCenterPropertyIndex = handle.RegisterProperty( CURRENT_CENTER_PROPERTY_NAME, Vector2( defaultPageSize[0], defaultPageSize[1]*0.5f ) );
- shaderImpl->mInternalConstraint = Constraint::New<Matrix>( handle.GetPropertyIndex( "uCommonParameters" ),
- LocalSource( shaderImpl->mOriginalCenterPropertyIndex ),
- LocalSource( shaderImpl->mCurrentCenterPropertyIndex ),
- LocalSource( handle.GetPropertyIndex( PAGE_SIZE_PROPERTY_NAME ) ),
- CommonParametersConstraint() );
- handle.ApplyConstraint( shaderImpl->mInternalConstraint );
+
+ shaderImpl->ApplyInternalConstraint();
// setting isTurningBack to -1.0f here means turning page forward
handle.SetUniform( IS_TURNING_BACK_PROPERTY_NAME, -1.0f );
void PageTurnEffect::ApplyInternalConstraint()
{
- mShaderEffect.ApplyConstraint( mInternalConstraint );
+ Constraint constraint = Constraint::New<Matrix>( mShaderEffect, mShaderEffect.GetPropertyIndex( "uCommonParameters" ), CommonParametersConstraint );
+ constraint.AddSource( LocalSource( mOriginalCenterPropertyIndex ) );
+ constraint.AddSource( LocalSource( mCurrentCenterPropertyIndex ) );
+ constraint.AddSource( LocalSource( mShaderEffect.GetPropertyIndex( PAGE_SIZE_PROPERTY_NAME ) ) );
+ constraint.Apply();
}
const std::string& PageTurnEffect::GetPageSizePropertyName() const
Property::Index mOriginalCenterPropertyIndex;
Property::Index mCurrentCenterPropertyIndex;
- Constraint mInternalConstraint;
private:
//undefined copy constructor.
const char* LANDSCAPE_QUALIFIER = "landscape";
const char* PORTRAIT_QUALIFIER = "portrait";
+const char* FONT_SIZE_QUALIFIER = "font-size-";
const char* DEFAULT_THEME = DALI_STYLE_DIR "tizen-default-theme.json";
}
StyleManager::StyleManager()
- : mOrientationDegrees( 0 ) // Portrait
+: mOrientationDegrees( 0 ), // Portrait
+ mDefaultFontSize( -1 )
{
// Add theme builder constants
mThemeBuilderConstants[ PACKAGE_PATH_KEY ] = DEFAULT_PACKAGE_PATH;
if( styleMonitor )
{
styleMonitor.StyleChangeSignal().Connect( this, &StyleManager::StyleMonitorChange );
+
+ mDefaultFontSize = styleMonitor.GetDefaultFontSize();
}
}
void StyleManager::ApplyStyle( Toolkit::Builder builder, Toolkit::Control control )
{
- // Convert control name to lower case
- std::string styleName = control.GetTypeName();
- std::transform( styleName.begin(), styleName.end(), styleName.begin(), ::tolower );
+ std::string styleName = control.GetStyleName();
+ if( styleName.empty() )
+ {
+ // Convert control name to lower case
+ styleName = control.GetTypeName();
+ std::transform( styleName.begin(), styleName.end(), styleName.begin(), ::tolower );
+ }
// Apply the style after choosing the correct actual style (e.g. landscape or portrait)
StringList qualifiers;
// Remove the last qualifier in an attempt to find a style that is valid
qualifiers.pop_back();
}
+
+ if( mDefaultFontSize >= 0 )
+ {
+ // Apply the style for logical font size
+ std::stringstream fontSizeQualifier;
+ fontSizeQualifier << styleName << "-" << FONT_SIZE_QUALIFIER << mDefaultFontSize;
+ builder.ApplyStyle( fontSizeQualifier.str(), control );
+ }
}
void StyleManager::ApplyThemeStyle( Toolkit::Control control )
void StyleManager::StyleMonitorChange( StyleMonitor styleMonitor, StyleChange styleChange )
{
+ if( styleChange.defaultFontSizeChange )
+ {
+ mDefaultFontSize = styleMonitor.GetDefaultFontSize();
+ }
+
mStyleChangeSignal.Emit( Toolkit::StyleManager::Get(), styleChange );
}
Orientation mOrientation; ///< Handle to application orientation object
int mOrientationDegrees; ///< Directly set value of orientation
+ int mDefaultFontSize; ///< Logical size, not a point-size
+
std::string mThemeFile; ///< The full path of the current theme file
Property::Map mThemeBuilderConstants; ///< Contants to give the theme builder
--- /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/internal/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.
+ CharacterDirection direction; ///< Direction of the first character of the paragraph.
+};
+
+} // 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/internal/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/internal/text/bidirectional-support.h>
+
+// EXTERNAL INCLUDES
+#include <memory.h>
+#include <dali/public-api/text-abstraction/bidirectional-support.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace
+{
+
+/**
+ * @brief Get the lines of a paragraph.
+ *
+ * @param[in] paragraphInfo The paragraph.
+ * @param[in] lines The lines.
+ * @param[in] lineIndex Index pointing the first line to be checked.
+ * @param[out] firstLine Index to the first line of the paragraph.
+ * @param[out] numberOfLines The number of lines.
+ */
+void GetLines( const BidirectionalParagraphInfoRun& paragraphInfo,
+ const Vector<LineRun>& lines,
+ unsigned int lineIndex,
+ unsigned int& firstLine,
+ unsigned int& numberOfLines )
+{
+ firstLine = lineIndex;
+ numberOfLines = 0u;
+
+ const CharacterIndex lastCharacterIndex = paragraphInfo.characterRun.characterIndex + paragraphInfo.characterRun.numberOfCharacters;
+ bool firstLineFound = false;
+
+ for( Vector<LineRun>::ConstIterator it = lines.Begin() + lineIndex,
+ endIt = lines.End();
+ it != endIt;
+ ++it )
+ {
+ const LineRun& line = *it;
+
+ if( ( line.characterRun.characterIndex + line.characterRun.numberOfCharacters > paragraphInfo.characterRun.characterIndex ) &&
+ ( lastCharacterIndex > line.characterRun.characterIndex ) )
+ {
+ firstLineFound = true;
+ ++numberOfLines;
+ }
+ else if( lastCharacterIndex <= line.characterRun.characterIndex )
+ {
+ // nothing else to do.
+ break;
+ }
+
+ if( !firstLineFound )
+ {
+ ++firstLine;
+ }
+ }
+}
+
+} // namespace
+
+void SetBidirectionalInfo( const Vector<Character>& text,
+ const Vector<ScriptRun>& scripts,
+ const Vector<LineBreakInfo>& lineBreakInfo,
+ Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo )
+{
+ // Traverse the script runs. If there is one with a right to left script, create the bidirectional info for the paragraph containing that script is needed.
+ // From the bidirectional point of view, a paragraph is the piece of text between two LINE_MUST_BREAK.
+
+ // Index pointing the first character of the current paragraph.
+ CharacterIndex paragraphCharacterIndex = 0u;
+
+ // Pointer to the text buffer.
+ const Character* textBuffer = text.Begin();
+
+ // Pointer to the line break info buffer.
+ const LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
+
+ // The number of characters.
+ const Length numberOfCharacters = text.Count();
+
+ // Handle to the bidirectional info module in text-abstraction.
+ TextAbstraction::BidirectionalSupport bidirectionalSupport = TextAbstraction::BidirectionalSupport::Get();
+
+ for( Vector<ScriptRun>::ConstIterator it = scripts.Begin(),
+ endIt = scripts.End();
+ it != endIt;
+ ++it )
+ {
+ const ScriptRun& scriptRun = *it;
+ const CharacterIndex lastScriptRunIndex = scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters;
+
+ if( TextAbstraction::IsRightToLeftScript( scriptRun.script ) && // The script is right to left.
+ ( lastScriptRunIndex > paragraphCharacterIndex ) ) // It isn't part of a previous paragraph.
+ {
+ // Find the paragraphs which contains this script run.
+ // Consider:
+ // 1) Different paragraphs may contain this script run.
+ // ------||------------------- rtl sr ------------------------||-------------------
+ // --||----- p -----||------------------ p -------------||-------- p ------||------
+ //
+ // 2) The paragraph which contains this script run may contain other right to left script runs.
+ // -----||--- rtl sr ---||---- ltr sr ----||---------- rtl sr -----------||--------
+ // -----||---------------------------------- p -----------------------------------|
+
+ while( lastScriptRunIndex > paragraphCharacterIndex )
+ {
+ // There is a paragraph which contains the current script.
+
+ Length index = paragraphCharacterIndex;
+ while( ( index < numberOfCharacters ) && ( paragraphCharacterIndex < lastScriptRunIndex ) )
+ {
+ if( TextAbstraction::LINE_MUST_BREAK == *( lineBreakInfoBuffer + index ) )
+ {
+ if( index >= scriptRun.characterRun.characterIndex )
+ {
+ // The Bidirectional run must have the same number of characters than the paragraph.
+ BidirectionalParagraphInfoRun bidirectionalRun;
+ bidirectionalRun.characterRun.characterIndex = paragraphCharacterIndex;
+ bidirectionalRun.characterRun.numberOfCharacters = ( index - paragraphCharacterIndex ) + 1u; // The must break character is part of the paragrah.
+
+ // Create the bidirectional info for the whole paragraph and store the index to the table with this info in the run.
+ bidirectionalRun.bidirectionalInfoIndex = bidirectionalSupport.CreateInfo( textBuffer + bidirectionalRun.characterRun.characterIndex,
+ bidirectionalRun.characterRun.numberOfCharacters );
+
+ bidirectionalInfo.PushBack( bidirectionalRun );
+ }
+
+ // Update the character index of the next paragraph.
+ paragraphCharacterIndex = index + 1u;
+ }
+ ++index;
+ }
+
+ // The last character is always a must-break, so there is no need to check if there is characters left.
+ }
+ }
+ }
+}
+
+void ReplaceBidirectionalInfo( LogicalModel& model,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert )
+{
+}
+
+void ReorderLines( const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
+ Vector<LineRun>& lineRuns,
+ Vector<BidirectionalLineInfoRun>& lineInfoRuns )
+{
+ // Handle to the bidirectional info module in text-abstraction.
+ TextAbstraction::BidirectionalSupport bidirectionalSupport = TextAbstraction::BidirectionalSupport::Get();
+
+ // Keep an index to the first line to be checked if it's contained inside the paragraph.
+ // Avoids check the lines from the beginning for each paragraph.
+ unsigned int lineIndex = 0u;
+
+ for( Vector<BidirectionalParagraphInfoRun>::ConstIterator it = bidirectionalInfo.Begin(),
+ endIt = bidirectionalInfo.End();
+ it != endIt;
+ ++it )
+ {
+ const BidirectionalParagraphInfoRun& paragraphInfo = *it;
+ const CharacterDirection direction = bidirectionalSupport.GetParagraphDirection( paragraphInfo.bidirectionalInfoIndex );
+
+ // Get the lines for this paragraph.
+ unsigned int firstLine = 0u;
+ unsigned int numberOfLines = 0u;
+
+ // Get an index to the first line and the number of lines of the current paragraph.
+ GetLines( paragraphInfo,
+ lineRuns,
+ lineIndex,
+ firstLine,
+ numberOfLines );
+
+ lineIndex = firstLine + numberOfLines;
+
+ // Traverse the lines and reorder them
+ for( Vector<LineRun>::Iterator lineIt = lineRuns.Begin() + firstLine,
+ endLineIt = lineRuns.Begin() + firstLine + numberOfLines;
+ lineIt != endLineIt;
+ ++lineIt )
+ {
+ LineRun& line = *lineIt;
+
+ // Sets the paragraph's direction.
+ line.direction = direction;
+
+ // Creates a bidirectional info for the line run.
+ BidirectionalLineInfoRun lineInfoRun;
+ lineInfoRun.characterRun.characterIndex = line.characterRun.characterIndex;
+ lineInfoRun.characterRun.numberOfCharacters = line.characterRun.numberOfCharacters;
+ lineInfoRun.direction = direction;
+
+ // Allocate space for the conversion maps.
+ // The memory is freed after the visual to logical to visual conversion tables are built in the logical model.
+ lineInfoRun.visualToLogicalMap = reinterpret_cast<CharacterIndex*>( malloc( line.characterRun.numberOfCharacters * sizeof( CharacterIndex ) ) );
+
+ // Reorders the line.
+ bidirectionalSupport.Reorder( paragraphInfo.bidirectionalInfoIndex,
+ line.characterRun.characterIndex - paragraphInfo.characterRun.characterIndex,
+ line.characterRun.numberOfCharacters,
+ lineInfoRun.visualToLogicalMap );
+
+ // Push the run into the vector.
+ lineInfoRuns.PushBack( lineInfoRun );
+ }
+ }
+}
+
+void ReorderLines( LogicalModel& logicalModel,
+ const VisualModel& visualModel,
+ CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ Length numberOfCharactersToInsert )
+{
+}
+
+bool GetMirroredText( const Vector<Character>& text,
+ Vector<Character>& mirroredText )
+{
+ // Handle to the bidirectional info module in text-abstraction.
+ TextAbstraction::BidirectionalSupport bidirectionalSupport = TextAbstraction::BidirectionalSupport::Get();
+
+ mirroredText = text;
+
+ return bidirectionalSupport.GetMirroredText( mirroredText.Begin(),
+ mirroredText.Count() );
+}
+
+void GetCharactersDirection( const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
+ Vector<CharacterDirection>& directions )
+{
+ // Handle to the bidirectional info module in text-abstraction.
+ TextAbstraction::BidirectionalSupport bidirectionalSupport = TextAbstraction::BidirectionalSupport::Get();
+
+ CharacterIndex index = 0u;
+ CharacterDirection* directionsBuffer = directions.Begin();
+ for( Vector<BidirectionalParagraphInfoRun>::ConstIterator it = bidirectionalInfo.Begin(),
+ endIt = bidirectionalInfo.End();
+ it != endIt;
+ ++it )
+ {
+ const BidirectionalParagraphInfoRun& paragraph = *it;
+
+ // Fills with left to right those paragraphs without right to left characters.
+ memset( directionsBuffer + index, false, ( paragraph.characterRun.characterIndex - index ) * sizeof( bool ) );
+ index += paragraph.characterRun.numberOfCharacters;
+
+ bidirectionalSupport.GetCharactersDirection( paragraph.bidirectionalInfoIndex,
+ directionsBuffer + paragraph.characterRun.characterIndex,
+ paragraph.characterRun.numberOfCharacters );
+ }
+
+ // Fills with left to right those paragraphs without right to left characters.
+ memset( directionsBuffer + index, false, ( directions.Count() - index ) * sizeof( bool ) );
+}
+
+} // 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/bidirectional-line-info-run.h>
+#include <dali-toolkit/internal/text/bidirectional-paragraph-info-run.h>
+#include <dali-toolkit/internal/text/line-run.h>
+#include <dali-toolkit/internal/text/script-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] scripts Vector containing the script runs for the whole text.
+ * @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<ScriptRun>& scripts,
+ 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 map tables.
+ *
+ * Any map tables previously set are removed.
+ * It sets the paragraph's direction to each line.
+ *
+ * @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,out] lineRuns The line runs converted to characters.
+ * @param[out] lineInfoRuns line runs with the visual to logical conversion maps.
+ */
+void ReorderLines( const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
+ Vector<LineRun>& 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 );
+
+/**
+ * @brief Replaces any character which could be mirrored.
+ *
+ * @param[in] text The text.
+ * @param[in] mirroredText The mirroredText.
+ *
+ * @return @e true if a character has been replaced.
+ */
+bool GetMirroredText( const Vector<Character>& text,
+ Vector<Character>& mirroredText );
+
+/**
+ * @brief Retrieves the character's directions.
+ *
+ * @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.
+ *
+ * @param[in] bidirectionalInfo Vector with the bidirectional infor for each paragraph.
+ * @param[out] directions The direction, @e false is left to right and @e true is right to left, of each character of the paragraph.
+ */
+void GetCharactersDirection( const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
+ Vector<CharacterDirection>& directions );
+
+} // 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/internal/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/internal/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 & 0x0fu;
+ begin++;
+ code <<= 6u;
+ code |= *begin++ & 0x3fu;
+ code <<= 6u;
+ code |= *begin++ & 0x3fu;
+ break;
+ }
+
+ case U4:
+ {
+ uint32_t& code = *utf32++;
+ code = leadByte & 0x07u;
+ begin++;
+ code <<= 6u;
+ code |= *begin++ & 0x3fu;
+ code <<= 6u;
+ code |= *begin++ & 0x3fu;
+ code <<= 6u;
+ code |= *begin++ & 0x3fu;
+ break;
+ }
+ }
+ }
+
+ return numberOfCharacters;
+}
+
+uint32_t Utf32ToUtf8( const uint32_t* const utf32, uint32_t numberOfCharacters, uint8_t* utf8 )
+{
+ const uint32_t* begin = utf32;
+ const uint32_t* end = utf32 + numberOfCharacters;
+
+ uint8_t* utf8Begin = utf8;
+
+ 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
+ }
+ }
+
+ return utf8 - utf8Begin;
+}
+
+} // 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <stdint.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.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.
+ *
+ * @return The number of bytes.
+ */
+DALI_IMPORT_API uint32_t Utf32ToUtf8( const uint32_t* const utf32, uint32_t numberOfCharacters, uint8_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/internal/text/clipping/text-clipper.h>
+
+// EXTERNAL INCLUDES
+#include <algorithm>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/render-tasks/render-task-list.h>
+#include <dali/integration-api/debug.h>
+
+namespace
+{
+
+// 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;
+
+} // namespace
+
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+ClipperPtr Clipper::New( const Vector2& size )
+{
+ ClipperPtr clipper( new Clipper() );
+
+ // Second-phase init
+ clipper->Initialize( size );
+
+ return clipper;
+}
+
+Actor Clipper::GetRootActor() const
+{
+ return mOffscreenRootActor;
+}
+
+ImageActor Clipper::GetImageActor() const
+{
+ return mImageActor;
+}
+
+void Clipper::Refresh( const Vector2& size )
+{
+ const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE, size.width ),
+ std::min( MAX_OFFSCREEN_RENDERING_SIZE, size.height ) );
+
+ const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
+
+ if( sizeChanged )
+ {
+ // Reconfigure camera for current size.
+ mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
+
+ // Recreate frame buffer for offscreen rendering when the size changes.
+ FrameBufferImage frameBufferImage = FrameBufferImage::New( offscreenSize.width,
+ offscreenSize.height,
+ Pixel::RGBA8888 );
+
+ mImageActor.SetSize( offscreenSize );
+ mImageActor.SetImage( frameBufferImage );
+ mRenderTask.SetTargetFrameBuffer( frameBufferImage );
+
+ // Stores current sizPe to avoid create new Dali resources if text changes.
+ mCurrentOffscreenSize = offscreenSize;
+ }
+
+ mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
+}
+
+void Clipper::Initialize( const Vector2& size )
+{
+ const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE, size.width ),
+ std::min( MAX_OFFSCREEN_RENDERING_SIZE, size.height ) );
+
+ // Create a root actor and an image actor for offscreen rendering.
+ mOffscreenRootActor = Layer::New();
+ mOffscreenRootActor.SetRelayoutEnabled( false );
+ mOffscreenRootActor.SetColorMode( USE_OWN_COLOR );
+ mOffscreenRootActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
+ mOffscreenRootActor.SetInheritScale( false );
+ mOffscreenRootActor.SetDepthTestDisabled( true );
+ mOffscreenRootActor.SetSize( offscreenSize );
+
+ mImageActor = ImageActor::New();
+ mImageActor.SetRelayoutEnabled( false );
+ mImageActor.SetParentOrigin( ParentOrigin::CENTER );
+ mImageActor.SetBlendFunc( BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA,
+ BlendingFactor::ONE, BlendingFactor::ONE );
+ mImageActor.SetScale( Vector3( 1.0f, -1.0f, 1.0f ) );
+ mImageActor.SetSize( offscreenSize );
+
+ // Creates a new camera actor.
+ mOffscreenCameraActor = CameraActor::New();
+ mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
+ mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
+ mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
+
+ // Creates a new render task.
+ mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
+ mRenderTask.SetSourceActor( mOffscreenRootActor );
+ mRenderTask.SetClearColor( Color::TRANSPARENT );
+ mRenderTask.SetClearEnabled( true );
+ mRenderTask.SetExclusive( true );
+ mRenderTask.SetCameraActor( mOffscreenCameraActor );
+
+ // Creates a frame buffer for offscreen rendering
+ FrameBufferImage frameBufferImage = FrameBufferImage::New( offscreenSize.width,
+ offscreenSize.height,
+ Pixel::RGBA8888 );
+ mImageActor.SetImage( frameBufferImage );
+ mRenderTask.SetTargetFrameBuffer( frameBufferImage );
+
+ // Stores current size to avoid create new Dali resources if text changes.
+ mCurrentOffscreenSize = offscreenSize;
+}
+
+Clipper::Clipper()
+{
+}
+
+Clipper::~Clipper()
+{
+ if( Stage::IsInstalled() )
+ {
+ UnparentAndReset( mOffscreenRootActor );
+ UnparentAndReset( mImageActor );
+
+ Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
+ }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_CLIPPER_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_CLIPPER_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/layer.h>
+#include <dali/public-api/actors/image-actor.h>
+#include <dali/public-api/actors/camera-actor.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/render-tasks/render-task.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+class Clipper;
+typedef IntrusivePtr<Clipper> ClipperPtr;
+
+/**
+ * @brief A helper class for clipping actors using a FrameBufferImage.
+ */
+class Clipper : public RefObject
+{
+public:
+
+ /**
+ * @brief Create a clipper.
+ *
+ * @param[in] size The size of the clipping region.
+ */
+ static ClipperPtr New( const Vector2& size );
+
+ /**
+ * @brief Children added to this actor will be clipped with the specified region.
+ *
+ * @note This is done by rendering to a FrameBufferImage which must then be displayed; see also GetImageActor().
+ * @return The root actor.
+ */
+ Actor GetRootActor() const;
+
+ /**
+ * @brief This actor will display the resulting FrameBufferImage.
+ *
+ * @return The image actor.
+ */
+ ImageActor GetImageActor() const;
+
+ /**
+ * @brief Refresh the contents of the FrameBufferImage.
+ *
+ * @param[in] size The size of the clipping region.
+ */
+ void Refresh( const Vector2& size );
+
+private: // Implementation
+
+ /**
+ * @brief Second-phase init
+ *
+ * @param[in] size The size of the clipping region.
+ */
+ void Initialize( const Vector2& size );
+
+ /**
+ * Construct a new Clipper.
+ */
+ Clipper();
+
+ /**
+ * A reference counted object may only be deleted by calling Unreference()
+ */
+ virtual ~Clipper();
+
+private:
+
+ // Undefined copy constructor and assignment operators
+ Clipper(const Clipper&);
+ Clipper& operator=(const Clipper& rhs);
+
+private: // Data
+
+ Layer mOffscreenRootActor;
+ CameraActor mOffscreenCameraActor;
+ ImageActor mImageActor;
+ RenderTask mRenderTask;
+ Vector2 mCurrentOffscreenSize;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_CLIPPER_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/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/actors/mesh-actor.h>
+#include <dali/public-api/common/constants.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/geometry/mesh.h>
+#include <dali/public-api/geometry/mesh-data.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/images/nine-patch-image.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>
+#include <dali-toolkit/public-api/controls/buttons/push-button.h>
+#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-selection-popup.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 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;
+
+const float DISPLAYED_HIGHLIGHT_Z_OFFSET( -0.05f );
+
+/**
+ * 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)
+ {
+ }
+
+ Dali::Vector2 min; ///< top-left (minimum) position of quad
+ Dali::Vector2 max; ///< bottom-right (maximum) position of quad
+};
+
+typedef std::vector<QuadCoordinates> QuadContainer;
+
+} // end of namespace
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct Decorator::Impl : public ConnectionTracker
+{
+ struct CursorImpl
+ {
+ CursorImpl()
+ : x(0.0f),
+ y(0.0f),
+ cursorHeight(0.0f),
+ lineHeight(0.0f),
+ color(Dali::Color::WHITE)
+ {
+ }
+
+ float x;
+ float y;
+ float cursorHeight;
+ float lineHeight;
+
+ Vector4 color;
+ };
+
+ struct SelectionHandleImpl
+ {
+ SelectionHandleImpl()
+ : x(0.0f),
+ y(0.0f),
+ lineHeight(0.0f),
+ flipped(false)
+ {
+ }
+
+ float x;
+ float y;
+ float lineHeight; ///< Not the handle height
+ bool flipped;
+
+ ImageActor actor;
+ Actor grabArea;
+
+ Image pressedImage;
+ Image releasedImage;
+ };
+
+ Impl( Dali::Toolkit::Internal::Control& parent, Observer& observer )
+ : mTextControlParent(parent),
+ mObserver(observer),
+ mActiveCursor(ACTIVE_CURSOR_NONE),
+ mActiveGrabHandle(false),
+ mActiveSelection( false ),
+ mActiveCopyPastePopup( false ),
+ mCursorBlinkInterval( CURSOR_BLINK_INTERVAL ),
+ mCursorBlinkDuration( 0.0f ),
+ mCursorBlinkStatus( true ),
+ mGrabDisplacementX( 0.0f ),
+ mGrabDisplacementY( 0.0f ),
+ mHighlightColor( 0.07f, 0.41f, 0.59f, 1.0f ), // light blue
+ 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, const Vector2& scrollPosition )
+ {
+ // TODO - Remove this if nothing is active
+ CreateActiveLayer();
+
+ // Show or hide the cursors
+ CreateCursors();
+ if( mPrimaryCursor )
+ {
+ mPrimaryCursor.SetPosition( mCursor[PRIMARY_CURSOR].x + scrollPosition.x,
+ mCursor[PRIMARY_CURSOR].y + scrollPosition.y );
+ mPrimaryCursor.SetSize( Size( 1.0f, mCursor[PRIMARY_CURSOR].cursorHeight ) );
+ }
+ if( mSecondaryCursor )
+ {
+ mSecondaryCursor.SetPosition( mCursor[SECONDARY_CURSOR].x + scrollPosition.x,
+ mCursor[SECONDARY_CURSOR].y + scrollPosition.y );
+ mSecondaryCursor.SetSize( Size( 1.0f, mCursor[SECONDARY_CURSOR].cursorHeight ) );
+ }
+
+ // Show or hide the grab handle
+ if( mActiveGrabHandle )
+ {
+ SetupTouchEvents();
+
+ CreateGrabHandle();
+
+ mGrabHandle.SetPosition( mCursor[PRIMARY_CURSOR].x + scrollPosition.x,
+ mCursor[PRIMARY_CURSOR].lineHeight + scrollPosition.y );
+ }
+ else if( mGrabHandle )
+ {
+ UnparentAndReset( mGrabHandle );
+ }
+
+ // Show or hide the selection handles/highlight
+ if( mActiveSelection )
+ {
+ SetupTouchEvents();
+
+ CreateSelectionHandles();
+
+ SelectionHandleImpl& primary = mSelectionHandle[ PRIMARY_SELECTION_HANDLE ];
+ primary.actor.SetPosition( primary.x + scrollPosition.x,
+ primary.lineHeight + scrollPosition.y );
+
+ SelectionHandleImpl& secondary = mSelectionHandle[ SECONDARY_SELECTION_HANDLE ];
+ secondary.actor.SetPosition( secondary.x + scrollPosition.x,
+ secondary.lineHeight + scrollPosition.y );
+
+ CreateHighlight();
+ UpdateHighlight();
+ }
+ else
+ {
+ UnparentAndReset( mSelectionHandle[ PRIMARY_SELECTION_HANDLE ].actor );
+ UnparentAndReset( mSelectionHandle[ SECONDARY_SELECTION_HANDLE ].actor );
+ UnparentAndReset( mHighlightMeshActor );
+ }
+
+ if ( mActiveCopyPastePopup )
+ {
+ if ( !mCopyPastePopup )
+ {
+ mCopyPastePopup = TextSelectionPopup::New();
+ mActiveLayer.Add ( mCopyPastePopup );
+ }
+ mCopyPastePopup.SetPosition( Vector3( 200.0f, -100.0f, 0.0f ) ); //todo grabhandle or selection handle positions to be used
+ }
+ else
+ {
+ if ( mCopyPastePopup )
+ {
+ UnparentAndReset( mCopyPastePopup );
+ }
+ }
+ }
+
+ void CreateCursor( ImageActor& cursor )
+ {
+ cursor = CreateSolidColorActor( Color::WHITE );
+ cursor.SetParentOrigin( ParentOrigin::TOP_LEFT ); // Need to set the default parent origin as CreateSolidColorActor() sets a different one.
+ cursor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ cursor.SetRelayoutEnabled( false );
+ }
+
+ // Add or Remove cursor(s) from parent
+ void CreateCursors()
+ {
+ if( mActiveCursor == ACTIVE_CURSOR_NONE )
+ {
+ UnparentAndReset( mPrimaryCursor );
+ UnparentAndReset( mSecondaryCursor );
+ }
+ else
+ {
+ /* Create Primary and or Secondary Cursor(s) if active and add to parent */
+ if ( mActiveCursor == ACTIVE_CURSOR_PRIMARY ||
+ mActiveCursor == ACTIVE_CURSOR_BOTH )
+ {
+ if ( !mPrimaryCursor )
+ {
+ CreateCursor( mPrimaryCursor );
+#ifdef DECORATOR_DEBUG
+ mPrimaryCursor.SetName( "PrimaryCursorActor" );
+#endif
+ mActiveLayer.Add( mPrimaryCursor);
+ }
+ }
+
+ if ( mActiveCursor == ACTIVE_CURSOR_BOTH )
+ {
+ if ( !mSecondaryCursor )
+ {
+ CreateCursor( mSecondaryCursor );
+#ifdef DECORATOR_DEBUG
+ mSecondaryCursor.SetName( "SecondaryCursorActor" );
+#endif
+ mActiveLayer.Add( mSecondaryCursor);
+ }
+ }
+ else
+ {
+ UnparentAndReset( mSecondaryCursor );
+ }
+ }
+ }
+
+ bool OnCursorBlinkTimerTick()
+ {
+ // Cursor blinking
+ if ( mPrimaryCursor )
+ {
+ mPrimaryCursor.SetVisible( mCursorBlinkStatus );
+ }
+ if ( mSecondaryCursor )
+ {
+ 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 = mTextControlParent.Self();
+
+ mActiveLayer = Layer::New();
+#ifdef DECORATOR_DEBUG
+ mActiveLayer.SetName ( "ActiveLayerActor" );
+#endif
+
+ mActiveLayer.SetParentOrigin( ParentOrigin::CENTER );
+ mActiveLayer.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
+ 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.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ mGrabHandle.SetDrawMode( DrawMode::OVERLAY );
+ // Area that Grab handle responds to, larger than actual handle so easier to move
+#ifdef DECORATOR_DEBUG
+ mGrabArea = Toolkit::CreateSolidColorActor( Vector4(0.0f, 0.0f, 0.0f, 0.0f), true, Color::RED, 1 );
+ mGrabArea.SetName( "GrabArea" );
+#else
+ mGrabArea = Actor::New();
+ mGrabArea.SetRelayoutEnabled( true );
+#endif
+ mGrabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ mGrabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ mGrabArea.SetResizePolicy( SIZE_RELATIVE_TO_PARENT, ALL_DIMENSIONS );
+ 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.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
+ primary.grabArea.SetRelayoutEnabled( true );
+#ifdef DECORATOR_DEBUG
+ primary.grabArea.SetName("SelectionHandleOneGrabArea");
+#endif
+ primary.grabArea.SetResizePolicy( SIZE_RELATIVE_TO_PARENT, ALL_DIMENSIONS );
+ 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.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // Change to BOTTOM_LEFT 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
+ secondary.grabArea.SetRelayoutEnabled( true );
+#ifdef DECORATOR_DEBUG
+ secondary.grabArea.SetName("SelectionHandleTwoGrabArea");
+#endif
+ secondary.grabArea.SetResizePolicy( SIZE_RELATIVE_TO_PARENT, ALL_DIMENSIONS );
+ 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 CreateHighlight()
+ {
+ if ( !mHighlightMeshActor )
+ {
+ mHighlightMaterial = Material::New( "HighlightMaterial" );
+ mHighlightMaterial.SetDiffuseColor( mHighlightColor );
+
+ mHighlightMeshData.SetMaterial( mHighlightMaterial );
+ mHighlightMeshData.SetHasNormals( true );
+
+ mHighlightMesh = Mesh::New( mHighlightMeshData );
+
+ mHighlightMeshActor = MeshActor::New( mHighlightMesh );
+#ifdef DECORATOR_DEBUG
+ mHighlightMeshActor.SetName( "HighlightMeshActor" );
+#endif
+ mHighlightMeshActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ mHighlightMeshActor.SetPosition( 0.0f, 0.0f, DISPLAYED_HIGHLIGHT_Z_OFFSET );
+
+ Actor parent = mTextControlParent.Self();
+ parent.Add( mHighlightMeshActor );
+ }
+ }
+
+ void 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 ( mHighlightMesh && mHighlightMaterial && !mHighlightQuadList.empty() )
+ {
+ MeshData::VertexContainer vertices;
+ Dali::MeshData::FaceIndices faceIndices;
+
+ std::vector<QuadCoordinates>::iterator iter = mHighlightQuadList.begin();
+ std::vector<QuadCoordinates>::iterator endIter = mHighlightQuadList.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 );
+
+ mHighlightMeshData.SetFaceIndices( faceIndices );
+ }
+
+ BoneContainer bones(0); // passed empty as bones not required
+ mHighlightMeshData.SetData( vertices, faceIndices, bones, mHighlightMaterial );
+ mHighlightMesh.UpdateMeshData( mHighlightMeshData );
+ }
+ }
+
+ 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].lineHeight*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& mTextControlParent;
+ Observer& mObserver;
+
+ Layer mActiveLayer; // Layer for active handles and alike that ensures they are above all else.
+
+ unsigned int mActiveCursor;
+ bool mActiveGrabHandle;
+ bool mActiveSelection;
+ bool mActiveCopyPastePopup;
+
+ 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];
+
+ MeshActor mHighlightMeshActor; ///< Mesh Actor to display highlight
+ Mesh mHighlightMesh; ///< Mesh for highlight
+ MeshData mHighlightMeshData; ///< Mesh Data for highlight
+ Material mHighlightMaterial; ///< Material used for highlight
+ Vector4 mHighlightColor; ///< Color of the highlight
+ QuadContainer mHighlightQuadList; ///< Sub-selections that combine to create the complete selection highlight
+
+ TextSelectionPopup mCopyPastePopup;
+
+ 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, const Vector2& scrollPosition )
+{
+ mImpl->Relayout( size, scrollPosition );
+}
+
+/** 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 cursorHeight, float lineHeight )
+{
+ // 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].cursorHeight = cursorHeight;
+ mImpl->mCursor[cursor].lineHeight = lineHeight;
+}
+
+void Decorator::GetPosition( Cursor cursor, float& x, float& y, float& cursorHeight, float& lineHeight ) const
+{
+ x = mImpl->mCursor[cursor].x;
+ y = mImpl->mCursor[cursor].y;
+ cursorHeight = mImpl->mCursor[cursor].cursorHeight;
+ lineHeight = mImpl->mCursor[cursor].lineHeight;
+}
+
+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].lineHeight = 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].lineHeight;
+}
+
+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;
+}
+
+void Decorator::AddHighlight( float x1, float y1, float x2, float y2 )
+{
+ mImpl->mHighlightQuadList.push_back( QuadCoordinates(x1, y1, x2, y2) );
+}
+
+void Decorator::ClearHighlights()
+{
+ mImpl->mHighlightQuadList.clear();
+}
+
+void Decorator::SetPopupActive( bool active )
+{
+ mImpl->mActiveCopyPastePopup = active;
+}
+
+bool Decorator::IsPopupActive() const
+{
+ return mImpl->mActiveCopyPastePopup ;
+}
+
+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>
+#include <dali/public-api/math/vector2.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.
+ *
+ * The Popup decoration will be positioned either above the Grab handle or above the selection handles but if doing so
+ * would cause the Popup to exceed the Decoration Bounding Box ( see SetBoundingBox API ) the the Popup will be repositioned below the handle(s).
+ *
+ * Selection handles will be flipped around to ensure they do not exceed the Decoration Bounding Box. ( Stay visible ).
+ *
+ * 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.
+ * @param[in] scrollPosition The cursor, grab-handle positions etc. should be offset by this.
+ */
+ void Relayout( const Dali::Vector2& size, const Vector2& scrollPosition );
+
+ /**
+ * @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] cursorHeight The logical height of the cursor.
+ * @param[in] lineHeight The logical height of the line.
+ */
+ void SetPosition( Cursor cursor, float x, float y, float cursorHeight, float lineHeight );
+
+ /**
+ * @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] cursorHeight The logical height of the cursor.
+ * @param[out] lineHeight The logical height of the line.
+ */
+ void GetPosition( Cursor cursor, float& x, float& y, float& cursorHeight, float& lineHeight ) 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] lineHeight The logical line height at this position.
+ */
+ void SetPosition( SelectionHandle handle, float x, float y, float lineHeight );
+
+ /**
+ * @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;
+
+ /**
+ * @brief Adds a quad to the existing selection highlights.
+ *
+ * @param[in] x1 The top-left x position.
+ * @param[in] y1 The top-left y position.
+ * @param[in] x2 The bottom-right x position.
+ * @param[in] y3 The bottom-right y position.
+ */
+ void AddHighlight( float x1, float y1, float x2, float y2 );
+
+ /**
+ * @brief Removes all of the previously added highlights.
+ */
+ void ClearHighlights();
+
+ /**
+ * @brief Set the Selection Popup to show or hide via the active flaf
+ * @param[in] active true to show, false to hide
+ */
+ void SetPopupActive( bool active );
+
+ /**
+ * @brief Query whether the Selection Popup is active.
+ *
+ * @return True if the Selection Popup should be active.
+ */
+ bool IsPopupActive() 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/internal/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/internal/text/layouts/layout-engine.h>
+
+// EXTERNAL INCLUDES
+#include <limits>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/text-abstraction/font-client.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/layouts/layout-parameters.h>
+#include <dali-toolkit/internal/text/bidirectional-line-info-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace
+{
+
+const float MAX_FLOAT = std::numeric_limits<float>::max();
+
+} //namespace
+
+/**
+ * @brief Stores temporary layout info of the line.
+ */
+struct LineLayout
+{
+ GlyphIndex glyphIndex; ///< Index of the first glyph to be laid-out.
+ CharacterIndex characterIndex; ///< Index of the first character to be laid-out.
+ Length numberOfCharacters; ///< The number of characters which fit in one line.
+ Length numberOfGlyphs; ///< The number of glyph which fit in one line.
+ float length; ///< The length of the glyphs which fit in one line.
+ float widthAdvanceDiff; ///< The difference between the width and the advance of the last glyph.
+ float wsLengthEndOfLine; ///< The length of the white spaces at the end of the line.
+ float ascender; ///< The maximum ascender of all fonts in the line.
+ float descender; ///< The minimum descender of all fonts in the line.
+};
+
+struct LayoutEngine::Impl
+{
+ Impl()
+ : mLayout( LayoutEngine::SINGLE_LINE_BOX ),
+ mHorizontalAlignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN ),
+ mVerticalAlignment( LayoutEngine::VERTICAL_ALIGN_TOP )
+ {
+ mFontClient = TextAbstraction::FontClient::Get();
+ }
+
+ /**
+ * Retrieves the line layout for a given box width.
+ */
+ void GetLineLayoutForBox( const LayoutParameters& parameters,
+ LineLayout& lineLayout )
+ {
+ // Initializes the line layout.
+ lineLayout.numberOfCharacters = 0u;
+ lineLayout.numberOfGlyphs = 0u;
+ lineLayout.length = 0.f;
+ lineLayout.wsLengthEndOfLine = 0.f;
+ lineLayout.ascender = 0.f;
+ lineLayout.descender = MAX_FLOAT;
+
+ // Get the last glyph index.
+ const GlyphIndex lastGlyphIndex = parameters.totalNumberOfGlyphs - 1u;
+
+ FontId lastFontId = 0u;
+ for( GlyphIndex glyphIndex = lineLayout.glyphIndex;
+ glyphIndex < parameters.totalNumberOfGlyphs;
+ ++glyphIndex )
+ {
+ // Get the glyph info.
+ const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + glyphIndex );
+
+ // Check whether is a white space.
+ const Character character = *( parameters.textBuffer + lineLayout.numberOfCharacters );
+ const bool isWhiteSpace = TextAbstraction::IsWhiteSpace( character );
+
+ // Get the character indices for the current glyph. The last character index is needed
+ // because there are glyphs formed by more than one character but their break info is
+ // given only for the last character.
+ const Length charactersPerGlyph = *( parameters.charactersPerGlyphBuffer + glyphIndex );
+
+ // Increase the number of characters.
+ lineLayout.numberOfCharacters += charactersPerGlyph;
+
+ // Increase the number of glyphs.
+ lineLayout.numberOfGlyphs++;
+
+ // Increase the accumulated length.
+ const float glyphLength = ( glyphIndex == lastGlyphIndex ) ? glyphInfo.width : glyphInfo.advance;
+
+ if( isWhiteSpace )
+ {
+ // Add the length to the length of white spaces at the end of the line.
+ lineLayout.wsLengthEndOfLine += glyphLength;
+ }
+ else
+ {
+ // Add as well any previous white space length.
+ lineLayout.length += lineLayout.wsLengthEndOfLine + glyphLength;
+
+ // Clear the white space length at the end of the line.
+ lineLayout.wsLengthEndOfLine = 0.f;
+ }
+
+ if( lastFontId != glyphInfo.fontId )
+ {
+ Text::FontMetrics fontMetrics;
+ mFontClient.GetFontMetrics( glyphInfo.fontId, fontMetrics );
+
+ // Sets the maximum ascender.
+ if( fontMetrics.ascender > lineLayout.ascender )
+ {
+ lineLayout.ascender = fontMetrics.ascender;
+ }
+
+ // Sets the minimum descender.
+ if( fontMetrics.descender < lineLayout.descender )
+ {
+ lineLayout.descender = fontMetrics.descender;
+ }
+
+ lastFontId = glyphInfo.fontId;
+ }
+ }
+ }
+
+ /**
+ * Retrieves the line layout for a given box width.
+ */
+ void GetMultiLineLayoutForBox( const LayoutParameters& parameters,
+ LineLayout& lineLayout )
+ {
+ // Initializes the line layout.
+ lineLayout.numberOfCharacters = 0u;
+ lineLayout.numberOfGlyphs = 0u;
+ lineLayout.length = 0.f;
+ lineLayout.widthAdvanceDiff = 0.f;
+ lineLayout.wsLengthEndOfLine = 0.f;
+ lineLayout.ascender = 0.f;
+ lineLayout.descender = MAX_FLOAT;
+
+ // Stores temporary line layout which has not been added to the final line layout.
+ LineLayout tmpLineLayout;
+ tmpLineLayout.numberOfCharacters = 0u;
+ tmpLineLayout.numberOfGlyphs = 0u;
+ tmpLineLayout.length = 0.f;
+ tmpLineLayout.widthAdvanceDiff = 0.f;
+ tmpLineLayout.wsLengthEndOfLine = 0.f;
+ tmpLineLayout.ascender = 0.f;
+ tmpLineLayout.descender = MAX_FLOAT;
+
+ FontId lastFontId = 0u;
+ for( GlyphIndex glyphIndex = lineLayout.glyphIndex;
+ glyphIndex < parameters.totalNumberOfGlyphs;
+ ++glyphIndex )
+ {
+ // Get the glyph info.
+ const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + glyphIndex );
+
+ // Get the character indices for the current glyph. The last character index is needed
+ // because there are glyphs formed by more than one character but their break info is
+ // given only for the last character.
+ const Length charactersPerGlyph = *( parameters.charactersPerGlyphBuffer + glyphIndex );
+ const CharacterIndex characterFirstIndex = *( parameters.glyphsToCharactersBuffer + glyphIndex );
+ const CharacterIndex characterLastIndex = characterFirstIndex + ( ( 1u > charactersPerGlyph ) ? 0u : charactersPerGlyph - 1u );
+
+ // Get the line break info for the current character.
+ const LineBreakInfo lineBreakInfo = *( parameters.lineBreakInfoBuffer + characterLastIndex );
+
+ // Get the word break info for the current character.
+ const WordBreakInfo wordBreakInfo = *( parameters.wordBreakInfoBuffer + characterLastIndex );
+
+ // Increase the number of characters.
+ tmpLineLayout.numberOfCharacters += charactersPerGlyph;
+
+ // Increase the number of glyphs.
+ tmpLineLayout.numberOfGlyphs++;
+
+ // Check whether is a white space.
+ const Character character = *( parameters.textBuffer + characterFirstIndex );
+ const bool isWhiteSpace = TextAbstraction::IsWhiteSpace( character );
+
+ // Increase the accumulated length.
+ if( isWhiteSpace )
+ {
+ // Add the length to the length of white spaces at the end of the line.
+ tmpLineLayout.wsLengthEndOfLine += glyphInfo.advance; // I use the advance as the width is always zero for the white spaces.
+ tmpLineLayout.widthAdvanceDiff = 0.f;
+ }
+ else
+ {
+ // Add as well any previous white space length.
+ tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine + glyphInfo.advance;
+ tmpLineLayout.widthAdvanceDiff = glyphInfo.width - glyphInfo.advance;
+
+ // Clear the white space length at the end of the line.
+ tmpLineLayout.wsLengthEndOfLine = 0.f;
+ }
+
+ // Check if the accumulated length fits in the width of the box.
+ if( lineLayout.length + tmpLineLayout.length + tmpLineLayout.widthAdvanceDiff + ( ( 0.f < tmpLineLayout.length ) ? lineLayout.wsLengthEndOfLine : 0.f ) > parameters.boundingBox.width )
+ {
+ // Current word does not fit in the box's width.
+ return;
+ }
+
+ if( TextAbstraction::LINE_MUST_BREAK == lineBreakInfo )
+ {
+ // Must break the line. Update the line layout and return.
+ lineLayout.numberOfCharacters += tmpLineLayout.numberOfCharacters;
+ lineLayout.numberOfGlyphs += tmpLineLayout.numberOfGlyphs;
+ lineLayout.length += tmpLineLayout.length;
+ lineLayout.widthAdvanceDiff = tmpLineLayout.widthAdvanceDiff;
+
+ if( 0.f < tmpLineLayout.length )
+ {
+ lineLayout.length += lineLayout.wsLengthEndOfLine;
+
+ lineLayout.wsLengthEndOfLine = tmpLineLayout.wsLengthEndOfLine;
+ }
+ else
+ {
+ lineLayout.wsLengthEndOfLine += tmpLineLayout.wsLengthEndOfLine;
+ }
+
+ if( tmpLineLayout.ascender > lineLayout.ascender )
+ {
+ lineLayout.ascender = tmpLineLayout.ascender;
+ }
+
+ if( tmpLineLayout.descender < lineLayout.descender )
+ {
+ lineLayout.descender = tmpLineLayout.descender;
+ }
+
+ tmpLineLayout.numberOfCharacters = 0u;
+ tmpLineLayout.numberOfGlyphs = 0u;
+ tmpLineLayout.length = 0u;
+ tmpLineLayout.widthAdvanceDiff = 0u;
+ tmpLineLayout.wsLengthEndOfLine = 0u;
+ tmpLineLayout.ascender = 0.f;
+ tmpLineLayout.descender = MAX_FLOAT;
+ return;
+ }
+
+ if( TextAbstraction::WORD_BREAK == wordBreakInfo )
+ {
+ // Current glyph is the last one of the current word.
+ // Add the temporal layout to the current one.
+ lineLayout.numberOfCharacters += tmpLineLayout.numberOfCharacters;
+ lineLayout.numberOfGlyphs += tmpLineLayout.numberOfGlyphs;
+ lineLayout.length += tmpLineLayout.length;
+ lineLayout.widthAdvanceDiff = tmpLineLayout.widthAdvanceDiff;
+
+ if( 0.f < tmpLineLayout.length )
+ {
+ lineLayout.length += lineLayout.wsLengthEndOfLine;
+
+ lineLayout.wsLengthEndOfLine = tmpLineLayout.wsLengthEndOfLine;
+ }
+ else
+ {
+ lineLayout.wsLengthEndOfLine += tmpLineLayout.wsLengthEndOfLine;
+ }
+
+ if( tmpLineLayout.ascender > lineLayout.ascender )
+ {
+ lineLayout.ascender = tmpLineLayout.ascender;
+ }
+
+ if( tmpLineLayout.descender < lineLayout.descender )
+ {
+ lineLayout.descender = tmpLineLayout.descender;
+ }
+
+ tmpLineLayout.numberOfCharacters = 0u;
+ tmpLineLayout.numberOfGlyphs = 0u;
+ tmpLineLayout.length = 0u;
+ tmpLineLayout.widthAdvanceDiff = 0u;
+ tmpLineLayout.wsLengthEndOfLine = 0u;
+ tmpLineLayout.ascender = 0.f;
+ tmpLineLayout.descender = MAX_FLOAT;
+ }
+
+ if( lastFontId != glyphInfo.fontId )
+ {
+ Text::FontMetrics fontMetrics;
+ mFontClient.GetFontMetrics( glyphInfo.fontId, fontMetrics );
+
+ // Sets the maximum ascender.
+ if( fontMetrics.ascender > tmpLineLayout.ascender )
+ {
+ tmpLineLayout.ascender = fontMetrics.ascender;
+ }
+
+ // Sets the minimum descender.
+ if( -fontMetrics.descender < tmpLineLayout.descender )
+ {
+ tmpLineLayout.descender = fontMetrics.descender;
+ }
+
+ lastFontId = glyphInfo.fontId;
+ }
+ }
+ }
+
+ bool LayoutText( const LayoutParameters& layoutParameters,
+ Vector<Vector2>& glyphPositions,
+ Vector<LineRun>& lines,
+ Size& actualSize )
+ {
+ // TODO Switch between different layouts
+ bool update = false;
+
+ switch( mLayout )
+ {
+ case LayoutEngine::SINGLE_LINE_BOX:
+ {
+ update = SingleLineLayout( layoutParameters,
+ glyphPositions,
+ lines,
+ actualSize );
+ break;
+ }
+ case LayoutEngine::MULTI_LINE_BOX:
+ {
+ update = MultiLineLayout( layoutParameters,
+ glyphPositions,
+ lines,
+ actualSize );
+ break;
+ }
+ default:
+ break;
+ }
+
+ return update;
+ }
+
+ void ReLayoutRightToLeftLines( const LayoutParameters& layoutParameters,
+ Vector<Vector2>& glyphPositions )
+ {
+ // Traverses the paragraphs with right to left characters.
+ for( LineIndex lineIndex = 0u; lineIndex < layoutParameters.numberOfBidirectionalInfoRuns; ++lineIndex )
+ {
+ const BidirectionalLineInfoRun& bidiLine = *( layoutParameters.lineBidirectionalInfoRunsBuffer + lineIndex );
+
+ float penX = 0.f;
+
+ Vector2* glyphPositionsBuffer = glyphPositions.Begin();
+
+ // Traverses the characters of the right to left paragraph.
+ for( CharacterIndex characterLogicalIndex = 0u;
+ characterLogicalIndex < bidiLine.characterRun.numberOfCharacters;
+ ++characterLogicalIndex )
+ {
+ // Convert the character in the logical order into the character in the visual order.
+ const CharacterIndex characterVisualIndex = bidiLine.characterRun.characterIndex + *( bidiLine.visualToLogicalMap + characterLogicalIndex );
+
+ // Get the number of glyphs of the character.
+ const Length numberOfGlyphs = *( layoutParameters.glyphsPerCharacterBuffer + characterVisualIndex );
+
+ for( GlyphIndex index = 0u; index < numberOfGlyphs; ++index )
+ {
+ // Convert the character in the visual order into the glyph in the visual order.
+ const GlyphIndex glyphIndex = *( layoutParameters.charactersToGlyphsBuffer + characterVisualIndex ) + index;
+
+ DALI_ASSERT_DEBUG( 0u <= glyphIndex && glyphIndex < layoutParameters.totalNumberOfGlyphs );
+
+ const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + glyphIndex );
+ Vector2& position = *( glyphPositionsBuffer + glyphIndex );
+
+ position.x = penX + glyph.xBearing;
+ penX += glyph.advance;
+ }
+ }
+ }
+ }
+
+ void Align( const LayoutParameters& layoutParameters,
+ const Size& layoutSize,
+ const Vector<LineRun>& lines,
+ Vector<Vector2>& glyphPositions )
+ {
+ Vector2* glyphPositionsBuffer = glyphPositions.Begin();
+
+ // Traverse all lines and align the glyphs.
+ // LayoutParameters contains bidirectional info for those lines with
+ // right to left text, this info includes the paragraph's direction.
+
+ LineIndex bidiLineIndex = 0u;
+ for( Vector<LineRun>::ConstIterator it = lines.Begin(), endIt = lines.End();
+ it != endIt;
+ ++it )
+ {
+ const LineRun& line = *it;
+
+ // 1) Get the paragrap's direction.
+ bool paragraphDirection = false;
+
+ // Check if there is any right to left line.
+ if( ( NULL != layoutParameters.lineBidirectionalInfoRunsBuffer ) &&
+ ( bidiLineIndex < layoutParameters.numberOfBidirectionalInfoRuns ) )
+ {
+ const BidirectionalLineInfoRun* bidiLine = layoutParameters.lineBidirectionalInfoRunsBuffer + bidiLineIndex;
+
+ // Get the right to left line that match with current line.
+ while( ( line.characterRun.characterIndex > bidiLine->characterRun.characterIndex ) &&
+ ( bidiLineIndex < layoutParameters.numberOfBidirectionalInfoRuns ) )
+ {
+ ++bidiLineIndex;
+ bidiLine = layoutParameters.lineBidirectionalInfoRunsBuffer + bidiLineIndex;
+ }
+
+ if( line.characterRun.characterIndex == bidiLine->characterRun.characterIndex )
+ {
+ paragraphDirection = bidiLine->direction;
+ }
+ }
+
+ // 2) Calculate the alignment offset accordingly with the align option,
+ // the box width, line length, and the paragraphs direction.
+ float alignOffset = CalculateHorizontalAlignment( layoutSize.width,
+ line.width,
+ line.extraLength,
+ paragraphDirection );
+
+ // 3) Traverse all glyphs and update the 'x' position.
+ for( GlyphIndex index = line.glyphIndex,
+ endIndex = line.glyphIndex + line.numberOfGlyphs;
+ index < endIndex;
+ ++index )
+ {
+ Vector2& position = *( glyphPositionsBuffer + index );
+
+ position.x += alignOffset;
+ }
+ }
+ }
+
+ bool SingleLineLayout( const LayoutParameters& layoutParameters,
+ Vector<Vector2>& glyphPositions,
+ Vector<LineRun>& lines,
+ Size& actualSize )
+ {
+ LineLayout layout;
+ layout.glyphIndex = 0u;
+ GetLineLayoutForBox( layoutParameters,
+ layout );
+
+ // Create a line run and add it to the lines.
+ const GlyphIndex lastGlyphIndex = layoutParameters.totalNumberOfGlyphs - 1u;
+
+ LineRun lineRun;
+ lineRun.glyphIndex = 0u;
+ lineRun.numberOfGlyphs = layoutParameters.totalNumberOfGlyphs;
+ lineRun.characterRun.characterIndex = 0u;
+ lineRun.characterRun.numberOfCharacters = *( layoutParameters.glyphsToCharactersBuffer + lastGlyphIndex ) + *( layoutParameters.charactersPerGlyphBuffer + lastGlyphIndex );
+ lineRun.width = layout.length;
+ lineRun.ascender = layout.ascender;
+ lineRun.descender = layout.descender;
+ lineRun.extraLength = layout.wsLengthEndOfLine;
+ lineRun.direction = false;
+
+ lines.PushBack( lineRun );
+
+ // Update the actual size.
+ actualSize.width = layout.length;
+ actualSize.height = lineRun.ascender + -lineRun.descender;
+
+ float penX = 0.f;
+ float penY = layout.ascender;
+
+ Vector2* glyphPositionsBuffer = glyphPositions.Begin();
+ for( GlyphIndex glyphIndex = 0u; glyphIndex < layout.numberOfGlyphs; ++glyphIndex )
+ {
+ const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + glyphIndex );
+ Vector2& position = *( glyphPositionsBuffer + glyphIndex );
+
+ position.x = penX + glyph.xBearing;
+ position.y = penY - glyph.yBearing;
+
+ penX += glyph.advance;
+ }
+
+ return true;
+ }
+
+ bool MultiLineLayout( const LayoutParameters& layoutParameters,
+ Vector<Vector2>& glyphPositions,
+ Vector<LineRun>& lines,
+ Size& actualSize )
+ {
+ float penY = 0.f;
+ for( GlyphIndex index = 0u; index < layoutParameters.totalNumberOfGlyphs; )
+ {
+ float penX = 0.f;
+
+ // Get the layout for the line.
+ LineLayout layout;
+ layout.glyphIndex = index;
+ GetMultiLineLayoutForBox( layoutParameters,
+ layout );
+
+ if( 0u == layout.numberOfGlyphs )
+ {
+ // The width is too small and no characters are laid-out.
+ return false;
+ }
+
+ // Create a line run and add it to the lines.
+ const GlyphIndex lastGlyphIndex = index + layout.numberOfGlyphs - 1u;
+
+ LineRun lineRun;
+ lineRun.glyphIndex = index;
+ lineRun.numberOfGlyphs = layout.numberOfGlyphs;
+ lineRun.characterRun.characterIndex = *( layoutParameters.glyphsToCharactersBuffer + index );
+ lineRun.characterRun.numberOfCharacters = ( *( layoutParameters.glyphsToCharactersBuffer + lastGlyphIndex ) + *( layoutParameters.charactersPerGlyphBuffer + lastGlyphIndex ) ) - lineRun.characterRun.characterIndex;
+ lineRun.width = layout.length + ( ( layout.widthAdvanceDiff > 0.f ) ? layout.widthAdvanceDiff : 0.f );
+ lineRun.ascender = layout.ascender;
+ lineRun.descender = layout.descender;
+ lineRun.extraLength = layout.wsLengthEndOfLine;
+ lineRun.direction = false;
+
+ lines.PushBack( lineRun );
+
+ // Update the actual size.
+ if( layout.length + layout.widthAdvanceDiff > actualSize.width )
+ {
+ actualSize.width = layout.length;
+ }
+
+ actualSize.height += ( lineRun.ascender + -lineRun.descender );
+
+ // Traverse the glyphs and set the positions.
+
+ penY += layout.ascender;
+
+ Vector2* glyphPositionsBuffer = glyphPositions.Begin();
+ for( GlyphIndex i = index; i < index + layout.numberOfGlyphs; ++i )
+ {
+ const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + i );
+ Vector2& position = *( glyphPositionsBuffer + i );
+
+ position.x = penX + glyph.xBearing;
+ position.y = penY - glyph.yBearing;
+
+ penX += glyph.advance;
+ }
+
+ penY += -layout.descender;
+
+ // Increase the glyph index.
+ index += layout.numberOfGlyphs;
+ }
+
+ return true;
+ }
+
+ float CalculateHorizontalAlignment( float boxWidth,
+ float lineLength,
+ float extraLength,
+ bool paragraphDirection )
+ {
+ float offset = 0.f;
+
+ HorizontalAlignment alignment = mHorizontalAlignment;
+ if( paragraphDirection &&
+ ( HORIZONTAL_ALIGN_CENTER != alignment ) )
+ {
+ if( HORIZONTAL_ALIGN_BEGIN == alignment )
+ {
+ alignment = HORIZONTAL_ALIGN_END;
+ }
+ else
+ {
+ alignment = HORIZONTAL_ALIGN_BEGIN;
+ }
+ }
+
+ switch( alignment )
+ {
+ case HORIZONTAL_ALIGN_BEGIN:
+ {
+ offset = 0.f;
+ break;
+ }
+ case HORIZONTAL_ALIGN_CENTER:
+ {
+ offset = 0.5f * ( boxWidth - lineLength );
+ const int intOffset = static_cast<int>( offset ); // try to avoid pixel alignment.
+ offset = static_cast<float>( intOffset );
+ break;
+ }
+ case HORIZONTAL_ALIGN_END:
+ {
+ offset = boxWidth - lineLength;
+ break;
+ }
+ }
+
+ if( paragraphDirection )
+ {
+ offset -= extraLength;
+ }
+
+ return offset;
+ }
+
+ LayoutEngine::Layout mLayout;
+ LayoutEngine::HorizontalAlignment mHorizontalAlignment;
+ LayoutEngine::VerticalAlignment mVerticalAlignment;
+
+ 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::SetHorizontalAlignment( HorizontalAlignment alignment )
+{
+ mImpl->mHorizontalAlignment = alignment;
+}
+
+LayoutEngine::HorizontalAlignment LayoutEngine::GetHorizontalAlignment() const
+{
+ return mImpl->mHorizontalAlignment;
+}
+
+void LayoutEngine::SetVerticalAlignment( VerticalAlignment alignment )
+{
+ mImpl->mVerticalAlignment = alignment;
+}
+
+LayoutEngine::VerticalAlignment LayoutEngine::GetVerticalAlignment() const
+{
+ return mImpl->mVerticalAlignment;
+}
+
+bool LayoutEngine::LayoutText( const LayoutParameters& layoutParameters,
+ Vector<Vector2>& glyphPositions,
+ Vector<LineRun>& lines,
+ Size& actualSize )
+{
+ return mImpl->LayoutText( layoutParameters,
+ glyphPositions,
+ lines,
+ actualSize );
+}
+
+void LayoutEngine::ReLayoutRightToLeftLines( const LayoutParameters& layoutParameters,
+ Vector<Vector2>& glyphPositions )
+{
+ mImpl->ReLayoutRightToLeftLines( layoutParameters,
+ glyphPositions );
+}
+
+void LayoutEngine::Align( const LayoutParameters& layoutParameters,
+ const Size& layoutSize,
+ const Vector<LineRun>& lines,
+ Vector<Vector2>& glyphPositions )
+{
+ mImpl->Align( layoutParameters,
+ layoutSize,
+ lines,
+ glyphPositions );
+}
+
+} // 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.
+ *
+ */
+
+// EXTERNAL INCLUDE
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/math/vector2.h>
+
+// INTERNAL INCLUDE
+#include <dali-toolkit/internal/text/line-run.h>
+
+namespace Dali
+{
+
+struct Vector2;
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct LayoutParameters;
+
+/**
+ * @brief LayoutEngine is responsible for calculating the visual position of glyphs in layout.
+ */
+class LayoutEngine
+{
+public:
+
+ enum Layout
+ {
+ SINGLE_LINE_BOX,
+ MULTI_LINE_BOX
+ };
+
+ enum HorizontalAlignment
+ {
+ HORIZONTAL_ALIGN_BEGIN,
+ HORIZONTAL_ALIGN_CENTER,
+ HORIZONTAL_ALIGN_END
+ };
+
+ enum VerticalAlignment
+ {
+ VERTICAL_ALIGN_TOP,
+ VERTICAL_ALIGN_CENTER,
+ VERTICAL_ALIGN_BOTTOM
+ };
+
+ /**
+ * @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 Choose the required text horizontal alignment.
+ *
+ * @param[in] alignment The required alignment.
+ */
+ void SetHorizontalAlignment( HorizontalAlignment alignment );
+
+ /**
+ * @brief Query the required text horizontal alignment.
+ *
+ * @return The required alignment.
+ */
+ HorizontalAlignment GetHorizontalAlignment() const;
+
+ /**
+ * @brief Choose the required text vertical alignment.
+ *
+ * @param[in] alignment The required alignment.
+ */
+ void SetVerticalAlignment( VerticalAlignment alignment );
+
+ /**
+ * @brief Query the required text vertical alignment.
+ *
+ * @return The required alignment.
+ */
+ VerticalAlignment GetVerticalAlignment() const;
+
+ /**
+ * @brief Store the visual position of glyphs in the VisualModel.
+ *
+ * @param[in] layoutParameters The parameters needed to layout the text.
+ * @param[out] glyphPositions The positions of all the glyphs.
+ * @param[out] lines The laid-out lines.
+ * @param[out] actualSize The size of the text after it has been laid-out.
+ *
+ * @return \e true if the text has been re-laid-out. \e false means the given width is too small to layout even a single character.
+ */
+ bool LayoutText( const LayoutParameters& layoutParameters,
+ Vector<Vector2>& glyphPositions,
+ Vector<LineRun>& lines,
+ Size& actualSize );
+
+ /**
+ * @brief Re-lays out those lines with right to left characters.
+ *
+ * It doesn't change the phisical position of the glyphs in the model but sets their new position.
+ *
+ * @param[in] layoutParameters The parameters needed to layout the text.
+ * @param[in,out] glyphPositions The positions of all the glyphs.
+ */
+ void ReLayoutRightToLeftLines( const LayoutParameters& layoutParameters,
+ Vector<Vector2>& glyphPositions );
+
+ /**
+ * @brief Aligns the laid out lines.
+ *
+ * @param[in] layoutParameters The parameters needed to layout the text.
+ * @param[in] layoutSize The size of the laid out the text.
+ * @param[in] lines The laid-out lines.
+ * @param[in,out] glyphPositions The positions of all the glyphs.
+ */
+ void Align( const LayoutParameters& layoutParameters,
+ const Size& layoutSize,
+ const Vector<LineRun>& lines,
+ Vector<Vector2>& glyphPositions );
+
+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_LAYOUT_PARAMETERS_H__
+#define __DALI_TOOLKIT_TEXT_LAYOUT_PARAMETERS_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/math/vector2.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct BidirectionalLineInfoRun;
+
+/**
+ * @brief Struct used to pass parameters.
+ */
+struct LayoutParameters
+{
+ /**
+ * Constructor with the needed parameters to layout the text.
+ *
+ * @param[in] boundingBox The size of the box containing the text.
+ * @param[in] textBuffer The text buffer.
+ * @param[in] lineBreakInfoBuffer The line break info.
+ * @param[in] wordBreakInfoBuffer The word break info.
+ * @param[in] totalNumberOfGlyphs The number of glyphs.
+ * @param[in] glyphsBuffer A vector with glyphs.
+ * @param[in] glyphsToCharactersBuffer Vector with indices pointing the first character of each glyph.
+ * @param[in] charactersPerGlyphBuffer Vector with the number of characters that forms each glyph.
+ */
+ LayoutParameters( const Vector2& boundingBox,
+ const Character* const textBuffer,
+ const LineBreakInfo* const lineBreakInfoBuffer,
+ const WordBreakInfo* const wordBreakInfoBuffer,
+ Length totalNumberOfGlyphs,
+ const GlyphInfo* const glyphsBuffer,
+ const CharacterIndex* const glyphsToCharactersBuffer,
+ const Length* const charactersPerGlyphBuffer )
+ : boundingBox( boundingBox ),
+ textBuffer( textBuffer ),
+ lineBreakInfoBuffer( lineBreakInfoBuffer ),
+ wordBreakInfoBuffer( wordBreakInfoBuffer ),
+ totalNumberOfGlyphs( totalNumberOfGlyphs ),
+ glyphsBuffer( glyphsBuffer ),
+ glyphsToCharactersBuffer( glyphsToCharactersBuffer ),
+ charactersPerGlyphBuffer( charactersPerGlyphBuffer ),
+ charactersToGlyphsBuffer( NULL ),
+ glyphsPerCharacterBuffer( NULL ),
+ lineBidirectionalInfoRunsBuffer( NULL ),
+ numberOfBidirectionalInfoRuns( 0u )
+ {}
+
+ Vector2 boundingBox;
+ const Character* const textBuffer;
+ const LineBreakInfo* const lineBreakInfoBuffer;
+ const WordBreakInfo* const wordBreakInfoBuffer;
+ Length totalNumberOfGlyphs;
+ const GlyphInfo* const glyphsBuffer;
+ const CharacterIndex* const glyphsToCharactersBuffer;
+ const Length* const charactersPerGlyphBuffer;
+ GlyphIndex* charactersToGlyphsBuffer; ///< The character to glyph conversion table.
+ Length* glyphsPerCharacterBuffer; ///< The number of glyphs per character.
+ BidirectionalLineInfoRun* lineBidirectionalInfoRunsBuffer; ///< Bidirectional conversion tables per line.
+ Length numberOfBidirectionalInfoRuns; ///< The number of lines with bidirectional info.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_LAYOUT_PARAMETERS_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/vector2.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief LineRun
+ */
+struct LineRun
+{
+ GlyphIndex glyphIndex; ///< The initial glyph index.
+ Length numberOfGlyphs; ///< The number of glyphs of the run.
+ CharacterRun characterRun; ///< The initial character and the number of characters.
+ float width; ///< The line's width.
+ float ascender; ///< The line's ascender.
+ float descender; ///< The line's descender.
+ float extraLength; ///< The length of the white spaces at the end of the line.
+ CharacterDirection direction; ///< Direction of the first character of the paragraph.
+};
+
+} // 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/internal/text/logical-model-impl.h>
+
+// EXTERNAL INCLUDES
+#include <memory.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+LogicalModelPtr LogicalModel::New()
+{
+ return LogicalModelPtr( new LogicalModel() );
+}
+
+void LogicalModel::SetText( const Character* const text,
+ Length numberOfCharacters )
+{
+ if( 0u == numberOfCharacters )
+ {
+ mText.Clear();
+ }
+ else
+ {
+ mText.Resize( numberOfCharacters );
+ memcpy( mText.Begin(), text, numberOfCharacters * sizeof( Character ) );
+ }
+}
+
+Length LogicalModel::GetNumberOfCharacters() const
+{
+ return mText.Count();
+}
+
+void LogicalModel::GetText( Character* text,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ memcpy( text, mText.Begin() + characterIndex, numberOfCharacters * sizeof( Character ) );
+}
+
+Character LogicalModel::GetCharacter( CharacterIndex characterIndex ) const
+{
+ return mText[characterIndex];
+}
+
+void LogicalModel::ReplaceText( CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ const Character* const text,
+ Length numberOfCharactersToInsert )
+{
+}
+
+void LogicalModel::SetScripts( const ScriptRun* const scripts,
+ Length numberOfRuns )
+{
+ if( 0u == numberOfRuns )
+ {
+ mScriptRuns.Clear();
+ }
+ else
+ {
+ mScriptRuns.Resize( numberOfRuns );
+ memcpy( mScriptRuns.Begin(), scripts, numberOfRuns * sizeof( ScriptRun ) );
+ }
+}
+
+void LogicalModel::GetNumberOfScriptRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters,
+ ScriptRunIndex& firstScriptRun,
+ Length& numberOfScriptRuns ) const
+{
+ // Initialize the number of scripts and the index to the first script.
+ firstScriptRun = 0u;
+ numberOfScriptRuns = 0;
+ bool firstScriptFound = false;
+
+ const CharacterIndex lastCharacterIndex = characterIndex + numberOfCharacters;
+
+ // Traverse the scripts and count those scripts within the range of characters.
+ for( Vector<ScriptRun>::ConstIterator it = mScriptRuns.Begin(),
+ endIt = mScriptRuns.End();
+ it != endIt;
+ ++it )
+ {
+ const ScriptRun& script = *it;
+
+ if( ( script.characterRun.characterIndex + script.characterRun.numberOfCharacters > characterIndex ) &&
+ ( lastCharacterIndex > script.characterRun.characterIndex ) )
+ {
+ firstScriptFound = true;
+ ++numberOfScriptRuns;
+ }
+ else if( lastCharacterIndex <= script.characterRun.characterIndex )
+ {
+ // nothing else to do.
+ break;
+ }
+
+ if( !firstScriptFound )
+ {
+ ++firstScriptRun;
+ }
+ }
+}
+
+void LogicalModel::GetScriptRuns( ScriptRun* scriptRuns,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ ScriptRunIndex firstScriptRun = 0u;
+ Length numberOfScriptRuns = 0u;
+
+ GetNumberOfScriptRuns( characterIndex,
+ numberOfCharacters,
+ firstScriptRun,
+ numberOfScriptRuns );
+
+ memcpy( scriptRuns, mScriptRuns.Begin() + firstScriptRun, numberOfScriptRuns * sizeof( ScriptRun ) );
+}
+
+Script LogicalModel::GetScript( CharacterIndex characterIndex ) const
+{
+ // If this operation is too slow, consider a binary search.
+
+ for( Length index = 0u, length = mScriptRuns.Count(); index < length; ++index )
+ {
+ const ScriptRun* const scriptRun = mScriptRuns.Begin() + index;
+
+ if( ( scriptRun->characterRun.characterIndex <= characterIndex ) &&
+ ( characterIndex < scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters ) )
+ {
+ return scriptRun->script;
+ }
+ }
+
+ return TextAbstraction::UNKNOWN;
+}
+
+void LogicalModel::ReplaceScripts( CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ const ScriptRun* const scriptRuns,
+ Length numberOfCharactersToInsert )
+{
+}
+
+void LogicalModel::SetFonts( const FontRun* const fonts,
+ Length numberOfRuns )
+{
+ if( 0u == numberOfRuns )
+ {
+ mFontRuns.Clear();
+ }
+ else
+ {
+ mFontRuns.Resize( numberOfRuns );
+ memcpy( mFontRuns.Begin(), fonts, numberOfRuns * sizeof( FontRun ) );
+ }
+}
+
+void LogicalModel::GetNumberOfFontRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters,
+ FontRunIndex& firstFontRun,
+ Length& numberOfFontRuns ) const
+{
+ // Initialize the number of fonts and the index to the first font.
+ firstFontRun = 0u;
+ numberOfFontRuns = 0;
+ bool firstFontFound = false;
+
+ const CharacterIndex lastCharacterIndex = characterIndex + numberOfCharacters;
+
+ // Traverse the fonts and count those fonts within the range of characters.
+ for( Vector<FontRun>::ConstIterator it = mFontRuns.Begin(),
+ endIt = mFontRuns.End();
+ it != endIt;
+ ++it )
+ {
+ const FontRun& font = *it;
+
+ if( ( font.characterRun.characterIndex + font.characterRun.numberOfCharacters > characterIndex ) &&
+ ( characterIndex + numberOfCharacters > font.characterRun.characterIndex ) )
+ {
+ firstFontFound = true;
+ ++numberOfFontRuns;
+ }
+ else if( lastCharacterIndex <= font.characterRun.characterIndex )
+ {
+ // nothing else to do.
+ break;
+ }
+
+ if( !firstFontFound )
+ {
+ ++firstFontRun;
+ }
+ }
+}
+
+void LogicalModel::GetFontRuns( FontRun* fontRuns,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ FontRunIndex firstFontRun = 0u;
+ Length numberOfFontRuns = 0u;
+
+ GetNumberOfFontRuns( characterIndex,
+ numberOfCharacters,
+ firstFontRun,
+ numberOfFontRuns );
+
+ memcpy( fontRuns, mFontRuns.Begin() + firstFontRun, numberOfFontRuns * sizeof( FontRun ) );
+}
+
+FontId LogicalModel::GetFont( CharacterIndex characterIndex ) const
+{
+ for( Length index = 0u, length = mFontRuns.Count(); index < length; ++index )
+ {
+ const FontRun* const fontRun = mFontRuns.Begin() + index;
+
+ if( ( fontRun->characterRun.characterIndex <= characterIndex ) &&
+ ( characterIndex < fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters ) )
+ {
+ return fontRun->fontId;
+ }
+ }
+
+ return 0u;
+}
+
+void LogicalModel::ReplaceFonts( CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ const FontRun* const fontRuns,
+ Length numberOfCharactersToInsert )
+{
+}
+
+void LogicalModel::SetLineBreakInfo( const LineBreakInfo* const lineBreakInfo,
+ Length length )
+{
+ if( 0u == length )
+ {
+ mLineBreakInfo.Clear();
+ }
+ else
+ {
+ mLineBreakInfo.Resize( length );
+ memcpy( mLineBreakInfo.Begin(), lineBreakInfo, length * sizeof( LineBreakInfo ) );
+ }
+}
+
+void LogicalModel::GetLineBreakInfo( LineBreakInfo* lineBreakInfo,
+ CharacterIndex characterIndex,
+ Length numberOfItems ) const
+{
+ memcpy( lineBreakInfo, mLineBreakInfo.Begin() + characterIndex, numberOfItems * sizeof( LineBreakInfo ) );
+}
+
+LineBreakInfo LogicalModel::GetLineBreakInfo( CharacterIndex characterIndex ) const
+{
+ return *( mLineBreakInfo.Begin() + characterIndex );
+}
+
+void LogicalModel::ReplaceLineBreakInfo( CharacterIndex characterIndex,
+ Length numberOfItemsToRemove,
+ const LineBreakInfo* const lineBreakInfo,
+ Length numberOfItemsToInsert )
+{
+}
+
+void LogicalModel::SetWordBreakInfo( const WordBreakInfo* const wordBreakInfo,
+ Length length )
+{
+ if( 0u == length )
+ {
+ mWordBreakInfo.Clear();
+ }
+ else
+ {
+ mWordBreakInfo.Resize( length );
+ memcpy( mWordBreakInfo.Begin(), wordBreakInfo, length * sizeof( WordBreakInfo ) );
+ }
+}
+
+void LogicalModel::GetWordBreakInfo( WordBreakInfo* wordBreakInfo,
+ CharacterIndex characterIndex,
+ Length numberOfItems ) const
+{
+ memcpy( wordBreakInfo, mWordBreakInfo.Begin() + characterIndex, numberOfItems * sizeof( WordBreakInfo ) );
+}
+
+WordBreakInfo LogicalModel::GetWordBreakInfo( CharacterIndex characterIndex ) const
+{
+ return *( mWordBreakInfo.Begin() + characterIndex );
+}
+
+void LogicalModel::ReplaceWordBreakInfo( CharacterIndex characterIndex,
+ Length numberOfItemsToRemove,
+ const WordBreakInfo* const wordBreakInfo,
+ Length numberOfItemsToInsert )
+{
+}
+
+void LogicalModel::SetBidirectionalInfo( const BidirectionalParagraphInfoRun* const bidirectionalInfo,
+ Length numberOfRuns )
+{
+ if( 0u == numberOfRuns )
+ {
+ mBidirectionalParagraphInfo.Clear();
+ }
+ else
+ {
+ mBidirectionalParagraphInfo.Resize( numberOfRuns );
+ memcpy( mBidirectionalParagraphInfo.Begin(), bidirectionalInfo, numberOfRuns * sizeof( BidirectionalParagraphInfoRun ) );
+ }
+}
+
+void LogicalModel::GetNumberOfBidirectionalInfoRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters,
+ BidirectionalRunIndex& firstBidirectionalRun,
+ Length& numberOfFontRuns ) const
+{
+ // Initialize the number of bidi paragraphs and the index to the first paragraph.
+ firstBidirectionalRun = 0u;
+ numberOfFontRuns = 0;
+ bool firstParagraphFound = false;
+
+ // Traverse the bidirectional paragraph info and count those bidi paragraphs within the range of characters.
+ for( Vector<BidirectionalParagraphInfoRun>::ConstIterator it = mBidirectionalParagraphInfo.Begin(),
+ endIt = mBidirectionalParagraphInfo.End();
+ it != endIt;
+ ++it )
+ {
+ const BidirectionalParagraphInfoRun& bidi = *it;
+
+ if( ( bidi.characterRun.characterIndex + bidi.characterRun.numberOfCharacters > characterIndex ) &&
+ ( characterIndex + numberOfCharacters > bidi.characterRun.characterIndex ) )
+ {
+ firstParagraphFound = true;
+ ++numberOfFontRuns;
+ }
+
+ if( !firstParagraphFound )
+ {
+ ++firstBidirectionalRun;
+ }
+ }
+}
+
+void LogicalModel::GetBidirectionalInfo( BidirectionalParagraphInfoRun* bidirectionalInfo,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ BidirectionalRunIndex firstBidirectionalRun = 0u;
+ Length numberOfFontRuns = 0u;
+
+ GetNumberOfBidirectionalInfoRuns( characterIndex,
+ numberOfCharacters,
+ firstBidirectionalRun,
+ numberOfFontRuns );
+
+ memcpy( bidirectionalInfo, mBidirectionalParagraphInfo.Begin() + firstBidirectionalRun, numberOfFontRuns * sizeof( BidirectionalParagraphInfoRun ) );
+}
+
+void ReplaceBidirectionalInfo( CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ const BidirectionalParagraphInfoRun* const bidirectionalInfo,
+ Length numberOfCharactersToInsert )
+{
+}
+
+void LogicalModel::SetCharacterDirections( const CharacterDirection* const directions,
+ Length numberOfCharacters )
+{
+ if( 0u == numberOfCharacters )
+ {
+ mCharacterDirections.Clear();
+ }
+ else
+ {
+ mCharacterDirections.Resize( numberOfCharacters );
+ memcpy( mCharacterDirections.Begin(), directions, numberOfCharacters * sizeof( CharacterDirection ) );
+ }
+}
+
+void LogicalModel::GetCharacterDirections( CharacterDirection* directions,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ if( 0u == mCharacterDirections.Count() )
+ {
+ // Nothing to retrieve if the model has no right to left characters.
+ return;
+ }
+
+ memcpy( directions, mCharacterDirections.Begin() + characterIndex, numberOfCharacters * sizeof( CharacterDirection ) );
+}
+
+CharacterDirection LogicalModel::GetCharacterDirection( CharacterIndex characterIndex ) const
+{
+ if( characterIndex >= mCharacterDirections.Count() )
+ {
+ // The model has no right to left characters, so the vector of directions is void.
+ return false;
+ }
+
+ return *( mCharacterDirections.Begin() + characterIndex );
+}
+
+void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const bidirectionalInfo,
+ Length numberOfRuns )
+{
+ if( 0u == numberOfRuns )
+ {
+ mVisualToLogicalMap.Clear();
+ mLogicalToVisualMap.Clear();
+ mVisualToLogicalCursorMap.Clear();
+ }
+ else
+ {
+ const Length numberOfCharacters = mText.Count();
+ mVisualToLogicalMap.Resize( numberOfCharacters );
+ mLogicalToVisualMap.Resize( numberOfCharacters );
+
+ const Length numberOfCharactersPlus = numberOfCharacters + 1u;
+ mVisualToLogicalCursorMap.Resize( numberOfCharactersPlus );
+
+ CharacterIndex* modelVisualToLogicalMapBuffer = mVisualToLogicalMap.Begin();
+ CharacterIndex* modelLogicalToVisualMapBuffer = mLogicalToVisualMap.Begin();
+
+ CharacterIndex* modelVisualToLogicalCursorMap = mVisualToLogicalCursorMap.Begin();
+
+ CharacterIndex lastIndex = 0u;
+ for( unsigned int bidiIndex = 0u; bidiIndex < numberOfRuns; ++bidiIndex )
+ {
+ const BidirectionalLineInfoRun& bidiLineInfo = *( bidirectionalInfo + bidiIndex );
+
+ if( lastIndex < bidiLineInfo.characterRun.characterIndex )
+ {
+ // Fill with the identity.
+ for( ; lastIndex < bidiLineInfo.characterRun.characterIndex; ++lastIndex )
+ {
+ *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex;
+ }
+ }
+
+ // Fill the conversion table of the run.
+ for( CharacterIndex index = 0u;
+ index < bidiLineInfo.characterRun.numberOfCharacters;
+ ++index, ++lastIndex )
+ {
+ *( modelVisualToLogicalMapBuffer + lastIndex ) = bidiLineInfo.characterRun.characterIndex + *( bidiLineInfo.visualToLogicalMap + index );
+ }
+ }
+
+ // Complete with the identity if there are some left to right characters after the last right to left.
+ for( ; lastIndex < numberOfCharacters; ++lastIndex )
+ {
+ *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex;
+ }
+
+ // Sets the logical to visual conversion map.
+ for( CharacterIndex index = 0u; index < numberOfCharacters; ++index )
+ {
+ *( modelLogicalToVisualMapBuffer + *( modelVisualToLogicalMapBuffer + index ) ) = index;
+ }
+
+ // Sets the visual to logical conversion map for cursor positions.
+
+ const Length numberOfBidirectionalParagraphs = mBidirectionalParagraphInfo.Count();
+ BidirectionalParagraphInfoRun* bidirectionalParagraphInfoBuffer = mBidirectionalParagraphInfo.Begin();
+ BidirectionalParagraphInfoRun* bidirectionalParagraph = bidirectionalParagraphInfoBuffer;
+
+ const CharacterDirection* const modelCharacterDirections = mCharacterDirections.Begin();
+
+ Length bidirectionalParagraphIndex = 0u;
+ bool isRightToLeftParagraph = false;
+ for( CharacterIndex index = 0u; index < numberOfCharactersPlus; ++index )
+ {
+ if( bidirectionalParagraph &&
+ ( bidirectionalParagraph->characterRun.characterIndex == index ) )
+ {
+ isRightToLeftParagraph = true;
+ }
+
+ if( 0u == index )
+ {
+ if( isRightToLeftParagraph )
+ {
+ *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters;
+ }
+ else // else logical position is zero.
+ {
+ *( modelVisualToLogicalCursorMap + index ) = 0u;
+ }
+ }
+ else if( numberOfCharacters == index )
+ {
+ if( isRightToLeftParagraph )
+ {
+ *( modelVisualToLogicalCursorMap + index ) = 0u;
+ }
+ else // else logical position is the number of characters.
+ {
+ *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters;
+ }
+ }
+ else
+ {
+ // Get the character indexed by index - 1 and index
+ // and calculate the logical position according the directions of
+ // both characters and the direction of the paragraph.
+
+ const CharacterIndex previousIndex = index - 1u;
+ const CharacterIndex logicalPosition0 = *( modelVisualToLogicalMapBuffer + previousIndex );
+ const CharacterIndex logicalPosition1 = *( modelVisualToLogicalMapBuffer + index );
+
+ const CharacterDirection direction0 = *( modelCharacterDirections + logicalPosition0 );
+ const CharacterDirection direction1 = *( modelCharacterDirections + logicalPosition1 );
+
+ if( direction0 == direction1 )
+ {
+ // Both glyphs have the same direction.
+ if( direction0 )
+ {
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition0;
+ }
+ else
+ {
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition1;
+ }
+ }
+ else
+ {
+ if( isRightToLeftParagraph )
+ {
+ if( direction1 )
+ {
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition1 + 1u;
+ }
+ else
+ {
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition0;
+ }
+ }
+ else
+ {
+ if( direction0 )
+ {
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition1;
+ }
+ else
+ {
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition0 + 1u;
+ }
+ }
+ }
+ }
+
+ if( bidirectionalParagraph &&
+ ( bidirectionalParagraph->characterRun.characterIndex + bidirectionalParagraph->characterRun.numberOfCharacters == index ) )
+ {
+ isRightToLeftParagraph = false;
+ ++bidirectionalParagraphIndex;
+ if( bidirectionalParagraphIndex < numberOfBidirectionalParagraphs )
+ {
+ bidirectionalParagraph = bidirectionalParagraphInfoBuffer + bidirectionalParagraphIndex;
+ }
+ else
+ {
+ bidirectionalParagraph = NULL;
+ }
+ }
+ }
+ }
+}
+
+void LogicalModel::ReplaceVisualToLogicalMap( CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ const BidirectionalLineInfoRun* const bidirectionalInfo,
+ Length numberOfCharactersToInsert )
+{
+}
+
+CharacterIndex LogicalModel::GetVisualCharacterIndex( CharacterIndex logicalCharacterIndex ) const
+{
+ if( 0u == mLogicalToVisualMap.Count() )
+ {
+ // If there is no logical to visual info is because the whole text is left to right.
+ // Return the identity.
+ return logicalCharacterIndex;
+ }
+
+ return *( mLogicalToVisualMap.Begin() + logicalCharacterIndex );
+}
+
+CharacterIndex LogicalModel::GetLogicalCharacterIndex( CharacterIndex visualCharacterIndex ) const
+{
+ if( 0u == mVisualToLogicalMap.Count() )
+ {
+ // If there is no visual to logical info is because the whole text is left to right.
+ // Return the identity.
+ return visualCharacterIndex;
+ }
+
+ return *( mVisualToLogicalMap.Begin() + visualCharacterIndex );
+}
+
+void LogicalModel::GetLogicalToVisualMap( CharacterIndex* logicalToVisualMap,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ memcpy( logicalToVisualMap, mLogicalToVisualMap.Begin() + characterIndex, numberOfCharacters * sizeof( CharacterIndex ) );
+}
+
+void LogicalModel::GetVisualToLogicalMap( CharacterIndex* visualToLogicalMap,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ memcpy( visualToLogicalMap, mVisualToLogicalMap.Begin() + characterIndex, numberOfCharacters * sizeof( CharacterIndex ) );
+}
+
+LogicalModel::~LogicalModel()
+{
+}
+
+LogicalModel::LogicalModel()
+{
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_LOGICAL_MODEL_IMPL_H__
+#define __DALI_TOOLKIT_TEXT_LOGICAL_MODEL_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.
+ *
+ */
+
+// EXTERNAL 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>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/bidirectional-line-info-run.h>
+#include <dali-toolkit/internal/text/bidirectional-paragraph-info-run.h>
+#include <dali-toolkit/internal/text/font-run.h>
+#include <dali-toolkit/internal/text/script-run.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.
+ *
+ * @note If the number of characters is zero the text buffer is cleared.
+ *
+ * @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[out] text Pointer to a buffer where the text is copied.
+ * @param[in] characterIndex The index to the first character to copy.
+ * @param[in] numberOfCharacters The number of characters to be copied.
+ */
+ void GetText( Character* text,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ /**
+ * @brief Retrieves a character.
+ *
+ * @param[in] characterIndex Index to a character.
+ *
+ * @return A character.
+ */
+ Character GetCharacter( CharacterIndex characterIndex ) const;
+
+ /**
+ * @brief Replaces characters from the text.
+ *
+ * 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] characterIndex Where to replace the text.
+ * @param[in] numberOfCharactersToRemove The number of characters to be removed.
+ * @param[in] text Pointer to a buffer with the text encoded in utf32.
+ * @param[in] numberOfCharactersToInsert The number of characters in the buffer.
+ */
+ void ReplaceText( CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ const Character* const text,
+ Length numberOfCharactersToInsert );
+
+ // Language support interface.
+
+ /**
+ * @brief 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.
+ *
+ * @note If the number of runs is zero the script buffer is cleared.
+ *
+ * @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 );
+
+ /**
+ * @brief Retrieves the number of script runs and the index to the first one 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.
+ * @param[out] firstScriptRun Index to the script run containing the character index.
+ * @param[out] numberOfScriptRuns The number of script runs.
+ */
+ void GetNumberOfScriptRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters,
+ ScriptRunIndex& firstScriptRun,
+ Length& numberOfScriptRuns ) const;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief Replaces script runs for the given range of characters.
+ *
+ * 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] characterIndex Index of the first character where to replace the scripts.
+ * @param[in] numberOfCharactersToRemove The number of characters to be the script removed.
+ * @param[in] scriptRuns Pointer to a buffer with the script runs.
+ * @param[in] numberOfCharactersToInsert The number of characters to be the script inserted.
+ */
+ void ReplaceScripts( CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ const ScriptRun* const scriptRuns,
+ Length numberOfCharactersToInsert );
+
+ /**
+ * @brief 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.
+ *
+ * @note If the number of runs is zero the font buffer is cleared.
+ *
+ * @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 );
+
+ /**
+ * @brief Retrieves the number of font runs and the index of the first one 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.
+ * @param[out] firstFontRun Index to the font run containing the character index.
+ * @param[out] numberOfFontRuns The number of font runs.
+ */
+ void GetNumberOfFontRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters,
+ FontRunIndex& firstFontRun,
+ Length& numberOfFontRuns ) const;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief Replaces font runs for the given range of characters.
+ *
+ * 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] characterIndex Index of the first character where to replace the fonts.
+ * @param[in] numberOfCharactersToRemove The number of characters to be the font removed.
+ * @param[in] fontRuns Pointer to a buffer with the font runs.
+ * @param[in] numberOfCharactersToInsert The number of characters to be the font inserted.
+ */
+ void ReplaceFonts( CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ const FontRun* const fontRuns,
+ Length numberOfCharactersToInsert );
+
+ // Break info interface.
+
+ /**
+ * @brief Sets the line break info.
+ *
+ * See GetLineBreakInfo() to get how the line break info is encoded.
+ *
+ * Replaces any line break info previously set.
+ *
+ * @note If the @length is zero the break info buffer is cleared.
+ *
+ * @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 );
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief Replaces line break info.
+ *
+ * See GetLineBreakInfo() to get how the line break info is encoded.
+ *
+ * If the @p numberOfItemsToRemove is zero, this operation is like an insert.
+ * If the @p numberOfItemsToInsert is zero, this operation is like a remove.
+ *
+ * @param[in] characterIndex Where to replace the line break info.
+ * @param[in] numberOfItemsToRemove The number of items to be removed.
+ * @param[in] lineBreakInfo Pointer to a buffer with the line break info.
+ * @param[in] numberOfItemsToInsert The number of items in the buffer.
+ */
+ void ReplaceLineBreakInfo( CharacterIndex characterIndex,
+ Length numberOfItemsToRemove,
+ const LineBreakInfo* const lineBreakInfo,
+ Length numberOfItemsToInsert );
+
+ /**
+ * @brief Sets the word break info.
+ *
+ * See GetWordBreakInfo() to get how the word break info is encoded.
+ *
+ * Replaces any word break info previously set.
+ *
+ * @note If the @length is zero the break info buffer is cleared.
+ *
+ * @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 );
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief Replaces word break info.
+ *
+ * See GetWordBreakInfo() to get how the word break info is encoded.
+ *
+ * If the @p numberOfItemsToRemove is zero, this operation is like an insert.
+ * If the @p numberOfItemsToInsert is zero, this operation is like a remove.
+ *
+ * @param[in] characterIndex Where to replace the word break info.
+ * @param[in] numberOfItemsToRemove The number of items to be removed.
+ * @param[in] wordBreakInfo Pointer to a buffer with the word break info.
+ * @param[in] numberOfItemsToInsert The number of items in the buffer.
+ */
+ void ReplaceWordBreakInfo( CharacterIndex characterIndex,
+ Length numberOfItemsToRemove,
+ const WordBreakInfo* const wordBreakInfo,
+ Length numberOfItemsToInsert );
+
+ // Bidirectional support interface.
+
+ /**
+ * @brief 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.
+ *
+ * @note If the number of runs is zero the bidirectional info buffer is cleared.
+ *
+ * @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 );
+
+ /**
+ * @brief Retrieves the number of bidirectional info runs and the index to the first one 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.
+ */
+ void GetNumberOfBidirectionalInfoRuns( CharacterIndex characterIndex,
+ Length numberOfCharacters,
+ BidirectionalRunIndex& firstBidirectionalRun,
+ Length& numberOfFontRuns ) const;
+
+ /**
+ * @brief Retrieves the bidirectional paragraph info runs for the given range of characters.
+ *
+ * The @p bidirectionalInfo buffer needs to be big enough to copy the number of bidirectional
+ * paragraph info runs.
+ * Call GetNumberOfBidirectionalInfoRuns() to retrieve the number of bidirectional runs.
+ *
+ * @param[out] bidirectionalInfo Pointer to a buffer where the bidirectional info runs are copied.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void GetBidirectionalInfo( BidirectionalParagraphInfoRun* bidirectionalInfo,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ /**
+ * @brief Replaces bidirectional info runs for the given range of characters.
+ *
+ * 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] characterIndex Index of the first character where to replace the bidirectional info.
+ * @param[in] numberOfCharactersToRemove The number of characters to be the bidirectional info removed.
+ * @param[in] bidirectionalInfo Pointer to a buffer with the bidirectional info runs.
+ * @param[in] numberOfCharactersToInsert The number of characters to be the bidirectional info inserted.
+ */
+ void ReplaceBidirectionalInfo( CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ const BidirectionalParagraphInfoRun* const bidirectionalInfo,
+ Length numberOfCharactersToInsert );
+
+ /**
+ * @brief Replaces the direction of the characters.
+ *
+ * @note If the number of characters is zero the directions buffer is cleared.
+ *
+ * @param[in] directions The directions of the characters.
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void SetCharacterDirections( const CharacterDirection* const directions,
+ Length numberOfCharacters );
+
+ /**
+ * @brief Retrieves the direction of the characters.
+ *
+ * It sets @e true for right to left characters and @e 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.
+ *
+ * @pre the @p directions vector should be initialized to @e false (left to right) as this method is not going
+ * to update it if there is no right to left characters.
+ *
+ * @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;
+
+ /**
+ * @brief 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.
+
+ /**
+ * @brief Sets the visual to logical and the logical to visual map tables.
+ *
+ * Replaces any map tables previously set.
+ *
+ * @note If the number of runs is zero the bidirectional info buffer is cleared.
+ *
+ * @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 );
+
+ /**
+ * @brief Replaces the visual to logical and logical to visual map tables for the given range of characters.
+ *
+ * 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] characterIndex Index of the first character where to replace the map tables.
+ * @param[in] numberOfCharactersToRemove The number of characters to be removed.
+ * @param[in] bidirectionalInfo Pointer to a buffer with the bidirectional info runs.
+ * @param[in] numberOfCharactersToInsert The number of characters to be inserted.
+ */
+ void ReplaceVisualToLogicalMap( CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ const BidirectionalLineInfoRun* const bidirectionalInfo,
+ Length numberOfCharactersToInsert );
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief 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 );
+
+public:
+
+ Vector<Character> mText;
+ Vector<ScriptRun> mScriptRuns;
+ Vector<FontRun> mFontRuns;
+ Vector<LineBreakInfo> mLineBreakInfo;
+ Vector<WordBreakInfo> mWordBreakInfo;
+ Vector<BidirectionalParagraphInfoRun> mBidirectionalParagraphInfo;
+ Vector<CharacterDirection> mCharacterDirections; ///< For each character, whether is right to left. ( @e flase is left to right, @e true right to left ).
+ Vector<BidirectionalLineInfoRun> mBidirectionalLineInfo;
+ Vector<CharacterIndex> mLogicalToVisualMap; ///< Bidirectional logical to visual conversion table.
+ Vector<CharacterIndex> mVisualToLogicalMap; ///< Bidirectional visual to logical conversion table.
+ Vector<CharacterIndex> mVisualToLogicalCursorMap; ///< Bidirectional visual to logical cursor conversion table.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_LOGICAL_MODEL_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/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>
+#include <dali/public-api/text-abstraction/script.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/logical-model-impl.h>
+#include <dali-toolkit/internal/text/font-run.h>
+#include <dali-toolkit/internal/text/script-run.h>
+#include <dali-toolkit/internal/text/text-io.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_MULTI_LANGUAGE_SUPPORT");
+#endif
+
+const Dali::Toolkit::Text::Character UTF32_A = 0x0041;
+}
+
+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 ( TextAbstraction::IsWhiteSpace( character ) ||
+ TextAbstraction::IsZeroWidthNonJoiner( character ) ||
+ TextAbstraction::IsZeroWidthJoiner( character ) ||
+ TextAbstraction::IsZeroWidthSpace( character ) ||
+ TextAbstraction::IsLeftToRightMark( character ) ||
+ TextAbstraction::IsRightToLeftMark( character ) ||
+ TextAbstraction::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 = TextAbstraction::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::IsRightToLeftScript( script );
+ firstValidScript = false;
+ }
+
+ if( script != currentScriptRun.script )
+ {
+ // Current run needs to be stored and a new one initialized.
+
+ if( isParagraphRTL != TextAbstraction::IsRightToLeftScript( 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 )
+ {
+ validateFontsPerScript = new ValidateFontsPerScript();
+ }
+
+ if( NULL != validateFontsPerScript )
+ {
+ if( !validateFontsPerScript->FindValidFont( fontId ) )
+ {
+ // Use the font client to validate the font.
+ GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character );
+
+ // Emojis are present in many monochrome fonts; prefer color by default.
+ if( TextAbstraction::EMOJI == script &&
+ 0u != glyphIndex )
+ {
+ BufferImage bitmap = fontClient.CreateBitmap( fontId, glyphIndex );
+ if( bitmap &&
+ Pixel::BGRA8888 != bitmap.GetPixelFormat() )
+ {
+ glyphIndex = 0;
+ }
+ }
+
+ 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 );
+ }
+ }
+ }
+ }
+ } // !isDefault
+
+ // 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 )
+ {
+ // Emojis are present in many monochrome fonts; prefer color by default.
+ bool preferColor = ( TextAbstraction::EMOJI == script );
+
+ // Find a default font.
+ fontId = fontClient.FindDefaultFont( character, pointSize, preferColor );
+
+ // If the system does not support a suitable font, fallback to Latin
+ if( 0u == fontId )
+ {
+ fontId = *( defaultFontPerScriptCacheBuffer + TextAbstraction::LATIN );
+ }
+ if( 0u == fontId )
+ {
+ fontId = fontClient.FindDefaultFont( UTF32_A, 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/multi-language-support.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.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/object/base-handle.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/font-run.h>
+#include <dali-toolkit/internal/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/internal/text/rendering/atlas/atlas-glyph-manager-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/actors/image-actor.h>
+#include <dali/public-api/common/stage.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+//#define DISPLAY_ATLAS
+
+AtlasGlyphManager::AtlasGlyphManager()
+: mCount( 0 )
+{
+ mAtlasManager = Dali::Toolkit::AtlasManager::New();
+}
+
+AtlasGlyphManager::~AtlasGlyphManager()
+{
+}
+
+AtlasGlyphManagerPtr AtlasGlyphManager::New()
+{
+ AtlasGlyphManagerPtr internal = new AtlasGlyphManager();
+ return internal;
+}
+
+void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
+ const BufferImage& bitmap,
+ Dali::Toolkit::AtlasManager::AtlasSlot& slot )
+{
+ GlyphRecord record;
+ record.mFontId = glyph.fontId;
+ record.mIndex = glyph.index;
+
+ mAtlasManager.Add( bitmap, slot );
+ record.mImageId = slot.mImageId;
+ mGlyphRecords.PushBack( record );
+
+#ifdef DISPLAY_ATLAS
+ {
+ uint32_t atlasCount = mAtlasManager.GetAtlasCount();
+ if ( atlasCount > mCount )
+ {
+ for ( uint32_t i = 0; i < atlasCount; ++i )
+ {
+ ImageActor actor = ImageActor::New( mAtlasManager.GetAtlasContainer( i + 1u ) );
+ actor.SetParentOrigin( Vector3( 0.5f, 0.25f + ( static_cast< float >( i ) * 0.25f ), 0.5f ) );
+ actor.SetAnchorPoint( AnchorPoint::CENTER );
+ actor.SetSize( 256.0f, 256.0f );
+ Stage::GetCurrent().Add( actor );
+ }
+ }
+ mCount = atlasCount;
+ }
+#endif
+}
+
+void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
+ const Vector2& position,
+ MeshData& meshData )
+{
+ mAtlasManager.GenerateMeshData( imageId, position, meshData );
+}
+
+void AtlasGlyphManager::StitchMesh( MeshData& first,
+ const MeshData& second )
+{
+ mAtlasManager.StitchMesh( first, second );
+}
+
+void AtlasGlyphManager::Cached( Text::FontId fontId,
+ uint32_t index,
+ Dali::Toolkit::AtlasManager::AtlasSlot& slot )
+{
+ for ( uint32_t i = 0; i < mGlyphRecords.Size(); ++i )
+ {
+ if ( fontId == mGlyphRecords[ i ].mFontId && index == mGlyphRecords[ i ].mIndex )
+ {
+ slot.mImageId = mGlyphRecords[ i ].mImageId;
+ slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
+ return;
+ }
+ }
+ slot.mImageId = 0;
+}
+
+Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
+{
+ return mAtlasManager.GetAtlasSize( atlasId );
+}
+
+void AtlasGlyphManager::SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize )
+{
+ mAtlasManager.SetNewAtlasSize( size, blockSize );
+}
+
+void AtlasGlyphManager::Remove( uint32_t imageId )
+{
+ if ( mAtlasManager.Remove( imageId ) )
+ {
+ for ( uint32_t i = 0; i < mGlyphRecords.Size(); ++i )
+ {
+ if ( mGlyphRecords[ i ].mImageId == imageId )
+ {
+ mGlyphRecords.Remove( mGlyphRecords.Begin() + i );
+ return;
+ }
+ }
+ }
+}
+
+Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
+{
+ return mAtlasManager.GetPixelFormat( atlasId );
+}
+
+const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
+{
+ mMetrics.mGlyphCount = mGlyphRecords.Size();
+ mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
+ return mMetrics;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+
+#ifndef __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
+#define __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_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.
+ */
+
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+class AtlasGlyphManager;
+
+} // namespace Toolkit
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class AtlasGlyphManager;
+typedef IntrusivePtr<AtlasGlyphManager> AtlasGlyphManagerPtr;
+
+class AtlasGlyphManager : public Dali::BaseObject
+{
+public:
+
+ struct GlyphRecord
+ {
+ Text::FontId mFontId;
+ Text::GlyphIndex mIndex;
+ uint32_t mImageId;
+ };
+
+ AtlasGlyphManager();
+
+ virtual ~AtlasGlyphManager();
+
+/**
+ * Create a new AtlasGlyphManager
+ */
+ static AtlasGlyphManagerPtr New();
+
+ /**
+ * @copydoc Toolkit::AtlasGlyphManager::Add
+ */
+ void Add( const Text::GlyphInfo& glyph,
+ const BufferImage& bitmap,
+ Dali::Toolkit::AtlasManager::AtlasSlot& slot );
+
+ /**
+ * @copydoc Toolkit::AtlasGlyphManager::GenerateMeshData
+ */
+ void GenerateMeshData( uint32_t imageId,
+ const Vector2& position,
+ MeshData& meshData );
+
+ /**
+ * @copydoc Toolkit::AtlasGlyphManager::StitchMesh
+ */
+ void StitchMesh( MeshData& first,
+ const MeshData& second );
+
+ /**
+ * @copydoc Toolkit::AtlasGlyphManager::Cached
+ */
+ void Cached( Text::FontId fontId,
+ Text::GlyphIndex index,
+ Dali::Toolkit::AtlasManager::AtlasSlot& slot );
+
+ /**
+ * @copydoc Toolkit::AtlasGlyphManager::GetAtlasSize
+ */
+ Vector2 GetAtlasSize( uint32_t atlasId );
+
+ /**
+ * @copydoc Toolkit::AtlasGlyphManager::SetNewAtlasSize
+ */
+ void SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize );
+
+ /**
+ * @copydoc Toolkit::AtlasGlyphManager::Remove
+ */
+ void Remove( uint32_t imageId );
+
+ /**
+ * @copydoc toolkit::AtlasGlyphManager::GetPixelFormat
+ */
+ Pixel::Format GetPixelFormat( uint32_t atlasId );
+
+ /**
+ * @copydoc toolkit::AtlasGlyphManager::GetMetrics
+ */
+ const Toolkit::AtlasGlyphManager::Metrics& GetMetrics();
+
+private:
+
+ Dali::Toolkit::AtlasManager mAtlasManager;
+ Vector< GlyphRecord > mGlyphRecords;
+ uint32_t mCount;
+ Toolkit::AtlasGlyphManager::Metrics mMetrics;
+};
+
+} // namespace Internal
+
+inline const Internal::AtlasGlyphManager& GetImplementation(const Toolkit::AtlasGlyphManager& manager)
+{
+ DALI_ASSERT_ALWAYS( manager && "AtlasGlyphManager handle is empty" );
+
+ const BaseObject& handle = manager.GetBaseObject();
+
+ return static_cast<const Internal::AtlasGlyphManager&>(handle);
+}
+
+inline Internal::AtlasGlyphManager& GetImplementation(Toolkit::AtlasGlyphManager& manager)
+{
+ DALI_ASSERT_ALWAYS( manager && "AtlasGlyphManager handle is empty" );
+
+ BaseObject& handle = manager.GetBaseObject();
+
+ return static_cast<Internal::AtlasGlyphManager&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+
+ #endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
\ No newline at end of file
--- /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/atlas/atlas-glyph-manager.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/singleton-service.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/atlas-manager/atlas-manager-impl.h>
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+AtlasGlyphManager::AtlasGlyphManager()
+{
+}
+
+AtlasGlyphManager::~AtlasGlyphManager()
+{
+}
+
+AtlasGlyphManager AtlasGlyphManager::Get()
+{
+ AtlasGlyphManager manager;
+
+ // Check whether the AtlasGlyphManager is already created
+ SingletonService singletonService( SingletonService::Get() );
+ if ( singletonService )
+ {
+ Dali::BaseHandle handle = singletonService.GetSingleton(typeid(AtlasGlyphManager));
+ if(handle)
+ {
+ // If so, downcast the handle of singleton to AtlasGlyphManager
+ manager = AtlasGlyphManager(dynamic_cast<Internal::AtlasGlyphManager*>(handle.GetObjectPtr()));
+ }
+
+ if(!manager)
+ {
+ // If not, create the AtlasGlyphManager and register it as a singleton
+ manager = AtlasGlyphManager(new Internal::AtlasGlyphManager());
+ singletonService.Register(typeid(manager), manager);
+ }
+ }
+ return manager;
+}
+
+AtlasGlyphManager::AtlasGlyphManager(Internal::AtlasGlyphManager *impl)
+ : BaseHandle(impl)
+{
+}
+
+void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
+ const BufferImage& bitmap,
+ AtlasManager::AtlasSlot& slot )
+{
+ GetImplementation(*this).Add( glyph, bitmap, slot );
+}
+
+void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
+ const Vector2& position,
+ MeshData& meshData )
+{
+ GetImplementation(*this).GenerateMeshData( imageId,
+ position,
+ meshData );
+}
+
+void AtlasGlyphManager::StitchMesh( MeshData& first,
+ const MeshData& second )
+{
+ GetImplementation(*this).StitchMesh( first, second );
+}
+
+void AtlasGlyphManager::Cached( Text::FontId fontId,
+ Text::GlyphIndex index,
+ AtlasManager::AtlasSlot& slot )
+{
+ GetImplementation(*this).Cached( fontId, index, slot );
+}
+
+void AtlasGlyphManager::SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize )
+{
+ GetImplementation(*this).SetNewAtlasSize( size, blockSize );
+}
+
+Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
+{
+ return GetImplementation(*this).GetAtlasSize( atlasId );
+}
+
+void AtlasGlyphManager::Remove( uint32_t imageId )
+{
+ GetImplementation(*this).Remove( imageId );
+}
+
+Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
+{
+ return GetImplementation(*this).GetPixelFormat( atlasId );
+}
+
+const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
+{
+ return GetImplementation(*this).GetMetrics();
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_H__
+#define __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_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/internal/atlas-manager/atlas-manager.h>
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class AtlasGlyphManager;
+}
+
+
+class DALI_IMPORT_API AtlasGlyphManager : public BaseHandle
+{
+public:
+
+ /**
+ * Description of GlyphManager state
+ */
+ struct Metrics
+ {
+ uint32_t mGlyphCount; // number of glyphs being managed
+ AtlasManager::Metrics mAtlasMetrics; // metrics from the Atlas Manager
+ };
+
+ /**
+ * @brief Create a AtlasGlyphManager handle.
+ *
+ * Calling member functions with an uninitialised handle is not allowed.
+ */
+ AtlasGlyphManager();
+
+ /**
+ * @brief Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~AtlasGlyphManager();
+
+ /**
+ * @brief Create or retrieve AtlasGlyphManager singleton.
+ *
+ * @return A handle to the AtlasGlyphManager control.
+ */
+ static AtlasGlyphManager Get();
+
+ /**
+ * @brief Ask Atlas Manager to add a glyph
+ *
+ * @param[in] glyph glyph to add to an atlas
+ * @param[in] bitmap bitmap to use for glyph addition
+ * @param[out] slot information returned by atlas manager for addition
+ */
+ void Add( const Text::GlyphInfo& glyph,
+ const BufferImage& bitmap,
+ AtlasManager::AtlasSlot& slot );
+
+ /**
+ * @brief Generate mesh data for an image contained in an atlas
+ *
+ * @param[in] imageId ID of image to generate geometry for
+ * @param[in] position top left of image
+ * @param[out] meshData generated MeshData
+ */
+ void GenerateMeshData( uint32_t imageId,
+ const Vector2& position,
+ MeshData& meshData );
+
+ /**
+ * @brief Stitch Two Meshes together
+ *
+ * @param[in] first first mesh
+ * @param[in] second second mesh
+ */
+ void StitchMesh( MeshData& first,
+ const MeshData& second );
+
+ /**
+ * @brief Check to see if a glyph is being cached
+ *
+ * @param[in] fontId The font that this glyph comes from
+ * @param[in] index The GlyphIndex of this glyph
+ * @param[out] slot container holding information about the glyph( mImage = 0 indicates not being cached )
+ */
+ void Cached( Text::FontId fontId,
+ Text::GlyphIndex index,
+ AtlasManager::AtlasSlot& slot );
+
+ /**
+ * @brief Retrieve the size of an atlas
+ *
+ * @param[in] atlasId Id of the atlas to interrogate
+ *
+ * @return The pixel size of the atlas
+ */
+ Vector2 GetAtlasSize( uint32_t atlasId );
+
+ /**
+ * @brief Set the Atlas size and block size for subsequent atlas generation
+ *
+ * @param[in] size size of the atlas in pixels
+ * @param[in] blockSize size of a block in this atlas in pixels
+ */
+ void SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize );
+
+ /**
+ * @brief Unreference an image from the atlas and remove from cache if no longer needed
+ *
+ * @param[in] imageId ID of the image
+ */
+ void Remove( uint32_t imageId );
+
+ /**
+ * @brief Get the Pixel Format used by an atlas
+ *
+ * @param[in] atlasId Id of atlas to check
+ *
+ * @return The pixel format of the atlas
+ */
+ Pixel::Format GetPixelFormat( uint32_t atlasId );
+
+ /**
+ * @brief Get Glyph Manager metrics
+ *
+ * @return const reference to glyph manager metrics
+ */
+ const Metrics& GetMetrics();
+
+private:
+
+ explicit DALI_INTERNAL AtlasGlyphManager(Internal::AtlasGlyphManager *impl);
+
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_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/atlas/text-atlas-renderer.h>
+
+// EXTERNAL INCLUDES
+#include <dali/dali.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/atlas-manager/atlas-manager.h>
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
+#include <dali-toolkit/internal/text/rendering/shaders/text-basic-shader.h>
+#include <dali-toolkit/internal/text/rendering/shaders/text-bgra-shader.h>
+#include <dali-toolkit/internal/text/rendering/shaders/text-basic-shadow-shader.h>
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_ATLAS_RENDERER");
+#endif
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+using namespace Dali::Toolkit::Text;
+
+namespace
+{
+ const Vector2 DEFAULT_ATLAS_SIZE( 512.0f, 512.0f );
+ const Vector2 DEFAULT_BLOCK_SIZE( 16.0f, 16.0f );
+ const Vector2 PADDING( 4.0f, 4.0f ); // Allow for variation in font glyphs
+}
+
+struct AtlasRenderer::Impl : public ConnectionTracker
+{
+
+ enum Style
+ {
+ STYLE_NORMAL,
+ STYLE_DROP_SHADOW
+ };
+
+ struct MeshRecord
+ {
+ Vector4 mColor;
+ uint32_t mAtlasId;
+ MeshData mMeshData;
+ FrameBufferImage mBuffer;
+ bool mIsUnderline;
+ };
+
+ struct Extent
+ {
+ float mBaseLine;
+ float mLeft;
+ float mRight;
+ float mUnderlinePosition;
+ float mUnderlineThickness;
+ uint32_t mMeshRecordIndex;
+ };
+
+ struct AtlasRecord
+ {
+ uint32_t mImageId;
+ Text::GlyphIndex mIndex;
+ };
+
+ struct MaxBlockSize
+ {
+ FontId mFontId;
+ Vector2 mNeededBlockSize;
+ };
+
+ Impl()
+ {
+ mGlyphManager = AtlasGlyphManager::Get();
+ mFontClient = TextAbstraction::FontClient::Get();
+ mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_SIZE, DEFAULT_BLOCK_SIZE );
+ mBasicShader = BasicShader::New();
+ mBgraShader = BgraShader::New();
+ mBasicShadowShader = BasicShadowShader::New();
+
+ mFace.reserve( 6u );
+ mFace.push_back( 0 ); mFace.push_back( 2u ); mFace.push_back( 1u );
+ mFace.push_back( 1u ); mFace.push_back( 2u ); mFace.push_back( 3u );
+ }
+
+ void AddGlyphs( const std::vector<Vector2>& positions,
+ const Vector<GlyphInfo>& glyphs,
+ const Vector4& textColor,
+ const Vector2& shadowOffset,
+ const Vector4& shadowColor,
+ float underlineEnabled,
+ const Vector4& underlineColor )
+ {
+ AtlasManager::AtlasSlot slot;
+ std::vector< MeshRecord > meshContainer;
+ Vector< Extent > extents;
+
+ float currentUnderlinePosition = 0.0f;
+ float currentUnderlineThickness = 0.0f;
+ FontId lastFontId = 0;
+ Style style = STYLE_NORMAL;
+
+ if ( shadowOffset.x != 0.0f || shadowOffset.y != 0.0f )
+ {
+ style = STYLE_DROP_SHADOW;
+ }
+
+ if ( mImageIds.Size() )
+ {
+ // Unreference any currently used glyphs
+ RemoveText();
+ }
+
+ CalculateBlocksSize( glyphs );
+
+ for ( uint32_t i = 0; i < glyphs.Size(); ++i )
+ {
+ GlyphInfo glyph = glyphs[ i ];
+
+ // No operation for white space
+ if ( glyph.width && glyph.height )
+ {
+ // Are we still using the same fontId as previous
+ if ( glyph.fontId != lastFontId )
+ {
+ // We need to fetch fresh font underline metrics
+ FontMetrics fontMetrics;
+ mFontClient.GetFontMetrics( glyph.fontId, fontMetrics );
+ currentUnderlinePosition = fontMetrics.underlinePosition;
+ currentUnderlineThickness = fontMetrics.underlineThickness;
+
+ // Ensure that an underline is at least 1 pixel high
+ if ( currentUnderlineThickness < 1.0f )
+ {
+ currentUnderlineThickness = 1.0f;
+ }
+ }
+
+ Vector2 position = positions[ i ];
+ MeshData newMeshData;
+ mGlyphManager.Cached( glyph.fontId, glyph.index, slot );
+
+ if ( slot.mImageId )
+ {
+ // This glyph already exists so generate mesh data plugging in our supplied position
+ mGlyphManager.GenerateMeshData( slot.mImageId, position, newMeshData );
+ mImageIds.PushBack( slot.mImageId );
+ }
+ else
+ {
+
+ // Select correct size for new atlas if needed....?
+ if ( lastFontId != glyph.fontId )
+ {
+ for ( uint32_t j = 0; j < mBlockSizes.size(); ++j )
+ {
+ if ( mBlockSizes[ j ].mFontId == glyph.fontId )
+ {
+ mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_SIZE, mBlockSizes[ j ].mNeededBlockSize );
+ }
+ }
+ lastFontId = glyph.fontId;
+ }
+
+ // Glyph doesn't currently exist in atlas so upload
+ BufferImage bitmap = mFontClient.CreateBitmap( glyph.fontId, glyph.index );
+
+ // Locate a new slot for our glyph
+ mGlyphManager.Add( glyph, bitmap, slot );
+
+ // Generate mesh data for this quad, plugging in our supplied position
+ if ( slot.mImageId )
+ {
+ mGlyphManager.GenerateMeshData( slot.mImageId, position, newMeshData );
+ mImageIds.PushBack( slot.mImageId );
+ }
+ }
+ // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
+ StitchTextMesh( meshContainer,
+ newMeshData,
+ extents,
+ textColor,
+ position.y + glyph.yBearing,
+ currentUnderlinePosition,
+ currentUnderlineThickness,
+ slot );
+ }
+ }
+
+ if ( underlineEnabled )
+ {
+ // Check to see if any of the text needs an underline
+ GenerateUnderlines( meshContainer, extents, underlineColor, textColor );
+ }
+
+ // For each MeshData object, create a mesh actor and add to the renderable actor
+ if ( meshContainer.size() )
+ {
+ for ( std::vector< MeshRecord >::iterator mIt = meshContainer.begin(); mIt != meshContainer.end(); ++mIt )
+ {
+ MeshActor actor = MeshActor::New( Mesh::New( mIt->mMeshData ) );
+ actor.SetColor( mIt->mColor );
+ if ( mIt->mIsUnderline )
+ {
+ actor.SetColorMode( USE_OWN_COLOR );
+ }
+ else
+ {
+ actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+ }
+
+ // Check to see what pixel format the shader should be
+ if ( mGlyphManager.GetPixelFormat( mIt->mAtlasId ) == Pixel::L8 )
+ {
+ // Create an effect if necessary
+ if ( style == STYLE_DROP_SHADOW )
+ {
+ actor.Add( GenerateShadow( *mIt, shadowOffset, shadowColor ) );
+ }
+ actor.SetShaderEffect( mBasicShader );
+ }
+ else
+ {
+ actor.SetShaderEffect( mBgraShader );
+ }
+
+ if ( mActor )
+ {
+ mActor.Add( actor );
+ }
+ else
+ {
+ mActor = actor;
+ }
+ }
+ mActor.OffStageSignal().Connect( this, &AtlasRenderer::Impl::OffStageDisconnect );
+ }
+#if defined(DEBUG_ENABLED)
+ Toolkit::AtlasGlyphManager::Metrics metrics = mGlyphManager.GetMetrics();
+ DALI_LOG_INFO( gLogFilter, Debug::Concise, "TextAtlasRenderer::GlyphManager::GlyphCount: %i, AtlasCount: %i, TextureMemoryUse: %iK\n",
+ metrics.mGlyphCount,
+ metrics.mAtlasMetrics.mAtlasCount,
+ metrics.mAtlasMetrics.mTextureMemoryUsed / 1024 );
+ for ( uint32_t i = 0; i < metrics.mAtlasMetrics.mAtlasCount; ++i )
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Atlas [%i] %sPixels: %s Size: %ix%i, BlockSize: %ix%i, BlocksUsed: %i/%i\n",
+ i + 1, i > 8 ? "" : " ",
+ metrics.mAtlasMetrics.mAtlasMetrics[ i ].mPixelFormat == Pixel::L8 ? "L8 " : "BGRA",
+ metrics.mAtlasMetrics.mAtlasMetrics[ i ].mWidth,
+ metrics.mAtlasMetrics.mAtlasMetrics[ i ].mHeight,
+ metrics.mAtlasMetrics.mAtlasMetrics[ i ].mBlockWidth,
+ metrics.mAtlasMetrics.mAtlasMetrics[ i ].mBlockHeight,
+ metrics.mAtlasMetrics.mAtlasMetrics[ i ].mBlocksUsed,
+ metrics.mAtlasMetrics.mAtlasMetrics[ i ].mTotalBlocks );
+ }
+#endif
+ }
+
+ void StitchTextMesh( std::vector< MeshRecord >& meshContainer,
+ MeshData& newMeshData,
+ Vector< Extent >& extents,
+ const Vector4& color,
+ float baseLine,
+ float underlinePosition,
+ float underlineThickness,
+ AtlasManager::AtlasSlot& slot )
+ {
+ if ( slot.mImageId )
+ {
+ MeshData::VertexContainer verts = newMeshData.GetVertices();
+ float left = verts[ 0 ].x;
+ float right = verts[ 1 ].x;
+
+ // Check to see if there's a mesh data object that references the same atlas ?
+ uint32_t index = 0;
+ for ( std::vector< MeshRecord >::iterator mIt = meshContainer.begin(); mIt != meshContainer.end(); ++mIt, ++index )
+ {
+ if ( slot.mAtlasId == mIt->mAtlasId )
+ {
+ // Stitch the mesh to the existing mesh and adjust any extents
+ mGlyphManager.StitchMesh( mIt->mMeshData, newMeshData );
+ AdjustExtents( extents,
+ meshContainer,
+ index,
+ color,
+ left,
+ right,
+ baseLine,
+ underlinePosition,
+ underlineThickness );
+ return;
+ }
+ }
+
+ // No mesh data object currently exists that references this atlas, so create a new one
+ MeshRecord meshRecord;
+ meshRecord.mAtlasId = slot.mAtlasId;
+ meshRecord.mMeshData = newMeshData;
+ meshRecord.mColor = color;
+ meshRecord.mIsUnderline = false;
+ meshContainer.push_back( meshRecord );
+
+ // Adjust extents for this new meshrecord
+ AdjustExtents( extents,
+ meshContainer,
+ meshContainer.size() - 1u,
+ color,
+ left,
+ right,
+ baseLine,
+ underlinePosition,
+ underlineThickness );
+
+ }
+ }
+
+ void AdjustExtents( Vector< Extent >& extents,
+ std::vector< MeshRecord>& meshRecords,
+ uint32_t index,
+ const Vector4& color,
+ float left,
+ float right,
+ float baseLine,
+ float underlinePosition,
+ float underlineThickness )
+ {
+ bool foundExtent = false;
+ for ( Vector< Extent >::Iterator eIt = extents.Begin(); eIt != extents.End(); ++eIt )
+ {
+ if ( Equals( baseLine, eIt->mBaseLine ) )
+ {
+ // If we've found an extent with the same color then we don't need to create a new extent
+ if ( color == meshRecords[ index ].mColor )
+ {
+ foundExtent = true;
+ if ( left < eIt->mLeft )
+ {
+ eIt->mLeft = left;
+ }
+ if ( right > eIt->mRight )
+ {
+ eIt->mRight = right;
+ }
+ }
+ // Font metrics use negative values for lower underline positions
+ if ( underlinePosition < eIt->mUnderlinePosition )
+ {
+ eIt->mUnderlinePosition = underlinePosition;
+ }
+ if ( underlineThickness > eIt->mUnderlineThickness )
+ {
+ eIt->mUnderlineThickness = underlineThickness;
+ }
+ }
+ }
+ if ( !foundExtent )
+ {
+ Extent extent;
+ extent.mLeft = left;
+ extent.mRight = right;
+ extent.mBaseLine = baseLine;
+ extent.mUnderlinePosition = underlinePosition;
+ extent.mUnderlineThickness = underlineThickness;
+ extent.mMeshRecordIndex = index;
+ extents.PushBack( extent );
+ }
+ }
+
+ // Unreference any glyphs that were used with this actor
+ void OffStageDisconnect( Dali::Actor actor )
+ {
+ RemoveText();
+ }
+
+ void RemoveText()
+ {
+ for ( uint32_t i = 0; i < mImageIds.Size(); ++i )
+ {
+ mGlyphManager.Remove( mImageIds[ i ] );
+ }
+ mImageIds.Resize( 0 );
+ }
+
+ void CalculateBlocksSize( const Vector<GlyphInfo>& glyphs )
+ {
+ MaxBlockSize maxBlockSize;
+ for ( uint32_t i = 0; i < glyphs.Size(); ++i )
+ {
+ // Get the fontId of this glyph and check to see if a max size exists?
+ FontId fontId = glyphs[ i ].fontId;
+ float paddedWidth = glyphs[ i ].width + PADDING.x;
+ float paddedHeight = glyphs[ i ].height + PADDING.y;
+ bool foundFont = false;
+
+ for ( uint32_t j = 0; j < mBlockSizes.size(); ++j )
+ {
+ if ( mBlockSizes[ j ].mFontId == fontId )
+ {
+ foundFont = true;
+ if ( mBlockSizes[ j ].mNeededBlockSize.x < paddedWidth )
+ {
+ mBlockSizes[ j ].mNeededBlockSize.x = paddedWidth;
+ }
+ if ( mBlockSizes[ j ].mNeededBlockSize.y < paddedHeight )
+ {
+ mBlockSizes[ j ].mNeededBlockSize.y = paddedHeight;
+ }
+ }
+ }
+
+ if ( !foundFont )
+ {
+ maxBlockSize.mNeededBlockSize = Vector2( paddedWidth, paddedHeight );
+ maxBlockSize.mFontId = fontId;
+ mBlockSizes.push_back( maxBlockSize );
+ }
+ }
+ }
+
+ void GenerateUnderlines( std::vector< MeshRecord>& meshRecords,
+ Vector< Extent >& extents,
+ const Vector4& underlineColor,
+ const Vector4& textColor )
+ {
+ MeshData newMeshData;
+ const float zero = 0.0f;
+ const float half = 0.5f;
+
+ for ( Vector< Extent >::ConstIterator eIt = extents.Begin(); eIt != extents.End(); ++eIt )
+ {
+ MeshData::VertexContainer newVerts;
+ newVerts.reserve( 4u );
+ uint32_t index = eIt->mMeshRecordIndex;
+ Vector2 uv = mGlyphManager.GetAtlasSize( meshRecords[ index ].mAtlasId );
+
+ // Make sure we don't hit texture edge for single pixel texture ( filled pixel is in top left of every atlas )
+ float u = half / uv.x;
+ float v = half / uv.y;
+ float thickness = eIt->mUnderlineThickness;
+ float baseLine = eIt->mBaseLine - eIt->mUnderlinePosition - ( thickness * 0.5f );
+ float tlx = eIt->mLeft;
+ float brx = eIt->mRight;
+
+ newVerts.push_back( MeshData::Vertex( Vector3( tlx, baseLine, zero ),
+ Vector2( zero, zero ),
+ Vector3( zero, zero, zero ) ) );
+
+ newVerts.push_back( MeshData::Vertex( Vector3( brx, baseLine, zero ),
+ Vector2( u, zero ),
+ Vector3( zero, zero, zero ) ) );
+
+ newVerts.push_back( MeshData::Vertex( Vector3( tlx, baseLine + thickness, zero ),
+ Vector2( zero, v ),
+ Vector3( zero, zero, zero ) ) );
+
+ newVerts.push_back( MeshData::Vertex( Vector3( brx, baseLine + thickness, zero ),
+ Vector2( u, v ),
+ Vector3( zero, zero, zero ) ) );
+
+ newMeshData.SetVertices( newVerts );
+ newMeshData.SetFaceIndices( mFace );
+
+ if ( underlineColor == textColor )
+ {
+ mGlyphManager.StitchMesh( meshRecords[ index ].mMeshData, newMeshData );
+ }
+ else
+ {
+ MeshRecord record;
+ newMeshData.SetMaterial( meshRecords[ index ].mMeshData.GetMaterial() );
+ newMeshData.SetHasNormals( true );
+ newMeshData.SetHasColor( false );
+ newMeshData.SetHasTextureCoords( true );
+ record.mMeshData = newMeshData;
+ record.mAtlasId = meshRecords[ index ].mAtlasId;
+ record.mColor = underlineColor;
+ record.mIsUnderline = true;
+ meshRecords.push_back( record );
+ }
+ }
+ }
+
+ MeshActor GenerateShadow( MeshRecord& meshRecord,
+ const Vector2& shadowOffset,
+ const Vector4& shadowColor )
+ {
+ // Scan vertex buffer to determine width and height of effect buffer needed
+ MeshData::VertexContainer verts = meshRecord.mMeshData.GetVertices();
+ const float one = 1.0f;
+ const float zero = 0.0f;
+ float tlx = verts[ 0 ].x;
+ float tly = verts[ 0 ].y;
+ float brx = zero;
+ float bry = zero;
+
+ for ( uint32_t i = 0; i < verts.size(); ++i )
+ {
+ if ( verts[ i ].x < tlx )
+ {
+ tlx = verts[ i ].x;
+ }
+ if ( verts[ i ].y < tly )
+ {
+ tly = verts[ i ].y;
+ }
+ if ( verts[ i ].x > brx )
+ {
+ brx = verts[ i ].x;
+ }
+ if ( verts[ i ].y > bry )
+ {
+ bry = verts[ i ].y;
+ }
+ }
+
+ float width = brx - tlx;
+ float height = bry - tly;
+ float divWidth = 2.0f / width;
+ float divHeight = 2.0f / height;
+
+ // Create a buffer to render to
+ meshRecord.mBuffer = FrameBufferImage::New( width, height );
+
+ // Create a mesh actor to contain the post-effect render
+ MeshData::VertexContainer vertices;
+ MeshData::FaceIndices face;
+
+ vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, tly + shadowOffset.y, zero ),
+ Vector2( zero, zero ),
+ Vector3( zero, zero, zero ) ) );
+
+ vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, tly + shadowOffset.y, zero ),
+ Vector2( one, zero ),
+ Vector3( zero, zero, zero ) ) );
+
+ vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, bry + shadowOffset.y, zero ),
+ Vector2( zero, one ),
+ Vector3( zero, zero, zero ) ) );
+
+ vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, bry + shadowOffset.y, zero ),
+ Vector2( one, one ),
+ Vector3( zero, zero, zero ) ) );
+
+ MeshData meshData;
+ Material newMaterial = Material::New("effect buffer");
+ newMaterial.SetDiffuseTexture( meshRecord.mBuffer );
+ meshData.SetMaterial( newMaterial );
+ meshData.SetVertices( vertices );
+ meshData.SetFaceIndices( mFace );
+ meshData.SetHasNormals( true );
+ meshData.SetHasColor( false );
+ meshData.SetHasTextureCoords( true );
+ MeshActor actor = MeshActor::New( Mesh::New( meshData ) );
+ actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+ actor.SetShaderEffect( mBgraShader );
+ actor.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR );
+ actor.SetSortModifier( 0.1f ); // force behind main text
+
+ // Create a sub actor to render once with normalized vertex positions
+ MeshData newMeshData;
+ MeshData::VertexContainer newVerts;
+ MeshData::FaceIndices newFaces;
+ MeshData::FaceIndices faces = meshRecord.mMeshData.GetFaces();
+ for ( uint32_t i = 0; i < verts.size(); ++i )
+ {
+ MeshData::Vertex vertex = verts[ i ];
+ vertex.x = ( ( vertex.x - tlx ) * divWidth ) - one;
+ vertex.y = ( ( vertex.y - tly ) * divHeight ) - one;
+ newVerts.push_back( vertex );
+ }
+
+ // Reverse triangle winding order
+ uint32_t faceCount = faces.size() / 3;
+ for ( uint32_t i = 0; i < faceCount; ++i )
+ {
+ uint32_t index = i * 3;
+ newFaces.push_back( faces[ index + 2 ] );
+ newFaces.push_back( faces[ index + 1 ] );
+ newFaces.push_back( faces[ index ] );
+ }
+
+ newMeshData.SetMaterial( meshRecord.mMeshData.GetMaterial() );
+ newMeshData.SetVertices( newVerts );
+ newMeshData.SetFaceIndices( newFaces );
+ newMeshData.SetHasNormals( true );
+ newMeshData.SetHasColor( false );
+ newMeshData.SetHasTextureCoords( true );
+
+ MeshActor subActor = MeshActor::New( Mesh::New( newMeshData ) );
+ subActor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+ subActor.SetColor( shadowColor );
+ subActor.SetShaderEffect( mBasicShadowShader );
+ subActor.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST );
+
+ // Create a render task to render the effect
+ RenderTask task = Stage::GetCurrent().GetRenderTaskList().CreateTask();
+ task.SetTargetFrameBuffer( meshRecord.mBuffer );
+ task.SetSourceActor( subActor );
+ task.SetClearEnabled( true );
+ task.SetClearColor( Vector4::ZERO );
+ task.SetExclusive( true );
+ task.SetRefreshRate( RenderTask::REFRESH_ONCE );
+ task.FinishedSignal().Connect( this, &AtlasRenderer::Impl::RenderComplete );
+ actor.Add( subActor );
+ return actor;
+ }
+
+ void RenderComplete( RenderTask& renderTask )
+ {
+ // Disconnect and remove this single shot render task
+ renderTask.FinishedSignal().Disconnect( this, &AtlasRenderer::Impl::RenderComplete );
+ Stage::GetCurrent().GetRenderTaskList().RemoveTask( renderTask );
+
+ // Get the actor used for render to buffer and remove it from the parent
+ Actor renderActor = renderTask.GetSourceActor();
+ if ( renderActor )
+ {
+ Actor parent = renderActor.GetParent();
+ if ( parent )
+ {
+ parent.Remove( renderActor );
+ }
+ }
+ }
+
+ RenderableActor mActor; ///< The actor parent which renders the text
+ AtlasGlyphManager mGlyphManager; ///< Glyph Manager to handle upload and caching
+ Vector< uint32_t > mImageIds; ///< A list of imageIDs used by the renderer
+ TextAbstraction::FontClient mFontClient; ///> The font client used to supply glyph information
+ ShaderEffect mBasicShader; ///> Shader used to render L8 glyphs
+ ShaderEffect mBgraShader; ///> Shader used to render BGRA glyphs
+ ShaderEffect mBasicShadowShader; ///> Shader used to render drop shadow into buffer
+ std::vector< MaxBlockSize > mBlockSizes; ///> Maximum size needed to contain a glyph in a block within a new atlas
+ std::vector< MeshData::FaceIndex > mFace; ///> Face indices for a quad
+};
+
+Text::RendererPtr AtlasRenderer::New()
+{
+ return Text::RendererPtr( new AtlasRenderer() );
+}
+
+RenderableActor AtlasRenderer::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 );
+ mImpl->AddGlyphs( positions,
+ glyphs,
+ view.GetTextColor(),
+ view.GetShadowOffset(),
+ view.GetShadowColor(),
+ view.IsUnderlineEnabled(),
+ view.GetUnderlineColor() );
+ }
+ return mImpl->mActor;
+}
+
+AtlasRenderer::AtlasRenderer()
+{
+ mImpl = new Impl();
+
+}
+
+AtlasRenderer::~AtlasRenderer()
+{
+ delete mImpl;
+}
\ No newline at end of file
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_ATLAS_RENDERER_H__
+#define __DALI_TOOLKIT_TEXT_ATLAS_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/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Implementation of a text renderer based on dynamic atlases.
+ *
+ */
+class AtlasRenderer : 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.
+ */
+ AtlasRenderer();
+
+ /**
+ * @brief A reference counted object may only be deleted by calling Unreference().
+ */
+ virtual ~AtlasRenderer();
+
+private:
+
+ // Undefined
+ AtlasRenderer( const AtlasRenderer& handle );
+
+ // Undefined
+ AtlasRenderer& operator=( const AtlasRenderer& handle );
+
+private:
+
+ struct Impl;
+ Impl* mImpl;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_ATLAS_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/internal/text/rendering/basic/text-basic-renderer.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/text-abstraction/font-client.h>
+#include <dali/public-api/actors/image-actor.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/internal/text/rendering/shaders/text-basic-shader.h>
+#include <dali-toolkit/internal/text/rendering/shaders/text-bgra-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 AtlasGlyph
+{
+ AtlasGlyph()
+ : fontId( 0 ),
+ index( 0 ),
+ xOffset( 0 ),
+ width( 0 ),
+ height( 0 )
+ {
+ }
+
+ AtlasGlyph( FontId id,
+ GlyphIndex glyphIndex,
+ std::size_t offset,
+ std::size_t widthPixels,
+ std::size_t heightPixels,
+ BufferImage bitmap )
+ : fontId( id ),
+ index( glyphIndex ),
+ xOffset( offset ),
+ width( widthPixels ),
+ height( heightPixels ),
+ mBitmap( bitmap )
+ {
+ }
+
+ FontId fontId;
+ GlyphIndex index;
+ std::size_t xOffset;
+ std::size_t width;
+ std::size_t height;
+ BufferImage mBitmap;
+ TextureCoordinates coords;
+};
+
+} // unnamed namespace
+
+struct BasicRenderer::Impl
+{
+ /**
+ * @brief Create the renderer implementation.
+ */
+ Impl()
+ : mWidthL8( 0.0f ),
+ mHeightL8( 0.0f ),
+ mWidthBGRA8888( 0.0f ),
+ mHeightBGRA8888( 0.0f )
+ {
+ mFontClient = TextAbstraction::FontClient::Get();
+ }
+
+ /**
+ * @brief Reset the previous glyph calculations.
+ *
+ * @param[in] size The glyph space to reserve.
+ */
+ void Reset( std::size_t size )
+ {
+ mWidthL8 = 0.0f;
+ mHeightL8 = 0.0f;
+ mWidthBGRA8888 = 0.0f;
+ mHeightBGRA8888 = 0.0f;
+ mGlyphs.clear();
+ mGlyphs.reserve( size );
+ mAtlasL8.Reset();
+ mAtlasBGRA8888.Reset();
+ }
+
+ /**
+ * @brief Ccreate an Atlas, uploading the necessary glyph bitmaps
+ *
+ * @param[in] glyphs The glyphs to upload.
+ */
+ void CreateAtlases( const Vector<GlyphInfo>& glyphs )
+ {
+ // Clear previous atlas
+ Reset( 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( !GlyphFound( glyphs[i].fontId, glyphs[i].index ) )
+ {
+ AddGlyph( glyphs[i] );
+ }
+ }
+ }
+
+ mAtlasL8 = CreateAtlas( mWidthL8, mHeightL8, Pixel::L8 );
+ mAtlasBGRA8888 = CreateAtlas( mWidthBGRA8888, mHeightBGRA8888, Pixel::BGRA8888 );
+ }
+
+ Atlas CreateAtlas( unsigned int width, unsigned int height, Pixel::Format format )
+ {
+ Atlas atlas;
+
+ if( width > 0 && height > 0 )
+ {
+ atlas = Atlas::New( width, height, format );
+
+ for( unsigned int i=0; i<mGlyphs.size(); ++i )
+ {
+ AtlasGlyph& glyph = mGlyphs[i];
+
+ const Pixel::Format glyphFormat = glyph.mBitmap.GetPixelFormat();
+
+ if( format == glyphFormat )
+ {
+ atlas.Upload( glyph.mBitmap, glyph.xOffset, 0 );
+
+ TextureCoordinates& coords = glyph.coords;
+ coords.topLeft.x = static_cast<float>(glyph.xOffset) / static_cast<float>(width);
+ coords.topLeft.y = 0.0f;
+ coords.topRight.x = static_cast<float>(glyph.xOffset + glyph.width) / static_cast<float>(width);
+ coords.topRight.y = 0.0f;
+ coords.bottomLeft.x = static_cast<float>(glyph.xOffset) / static_cast<float>(width);
+ coords.bottomLeft.y = static_cast<float>(glyph.height) / static_cast<float>(height);
+ coords.bottomRight.x = static_cast<float>(glyph.xOffset + glyph.width) / static_cast<float>(width);
+ coords.bottomRight.y = static_cast<float>(glyph.height) / static_cast<float>(height);
+ }
+ }
+ }
+
+ return atlas;
+ }
+
+ /**
+ * @brief Check whether we already have the glyph.
+ */
+ bool GlyphFound( FontId fontId, GlyphIndex index ) const
+ {
+ for( unsigned int i=0; i<mGlyphs.size(); ++i )
+ {
+ const AtlasGlyph& glyph = mGlyphs[i];
+
+ if( fontId == glyph.fontId &&
+ index == glyph.index )
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @brief Add the glyph.
+ */
+ void AddGlyph( const GlyphInfo& glyphInfo )
+ {
+ BufferImage bitmap = mFontClient.CreateBitmap( glyphInfo.fontId, glyphInfo.index );
+
+ const Pixel::Format format = bitmap.GetPixelFormat();
+
+ if( Pixel::L8 == format )
+ {
+ mGlyphs.push_back( AtlasGlyph( glyphInfo.fontId, glyphInfo.index, mWidthL8, glyphInfo.width, glyphInfo.height, bitmap ) );
+
+ // Increase the Atlas width/height
+ mWidthL8 += glyphInfo.width + PADDING;
+ if( mHeightL8 < glyphInfo.height + PADDING )
+ {
+ mHeightL8 = glyphInfo.height + PADDING;
+ }
+ }
+ else if ( Pixel::BGRA8888 == format )
+ {
+ mGlyphs.push_back( AtlasGlyph( glyphInfo.fontId, glyphInfo.index, mWidthBGRA8888, glyphInfo.width, glyphInfo.height, bitmap ) );
+
+ // A separate Atlas is used for color Emojis
+ mWidthBGRA8888 += glyphInfo.width + PADDING;
+ if( mHeightBGRA8888 < glyphInfo.height + PADDING )
+ {
+ mHeightBGRA8888 = glyphInfo.height + PADDING;
+ }
+ }
+ }
+
+ /**
+ * @brief Get the texture coordinates for a glyph.
+ */
+ bool GetTextureCoordinates( Pixel::Format format, FontId fontId, GlyphIndex index, TextureCoordinates& coords )
+ {
+ for( unsigned int i=0; i<mGlyphs.size(); ++i )
+ {
+ const AtlasGlyph& glyph = mGlyphs[i];
+
+ const Pixel::Format glyphFormat = glyph.mBitmap.GetPixelFormat();
+
+ if( format == glyphFormat &&
+ fontId == glyph.fontId &&
+ index == glyph.index )
+ {
+ coords = glyph.coords;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @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, Pixel::Format format, 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;
+ if( GetTextureCoordinates( format, 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
+
+ Atlas mAtlasL8;
+ unsigned int mWidthL8;
+ unsigned int mHeightL8;
+
+ // A separate Atlas is used for color Emojis
+ Atlas mAtlasBGRA8888;
+ unsigned int mWidthBGRA8888;
+ unsigned int mHeightBGRA8888;
+
+ std::vector<AtlasGlyph> mGlyphs;
+
+ TextAbstraction::FontClient mFontClient;
+};
+
+Text::RendererPtr BasicRenderer::New()
+{
+ return Text::RendererPtr( new BasicRenderer() );
+}
+
+RenderableActor BasicRenderer::Render( Text::ViewInterface& view )
+{
+ // Remove the previous text
+ 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 );
+
+ mImpl->CreateAtlases( glyphs );
+
+ MeshActor actorL8;
+ if( mImpl->mAtlasL8 )
+ {
+ actorL8 = MeshActor::New( mImpl->CreateMesh( glyphs, positions, Pixel::L8, mImpl->mAtlasL8 ) );
+ actorL8.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+
+ ShaderEffect shader = BasicShader::New();
+ actorL8.SetShaderEffect( shader );
+ }
+
+ MeshActor actorBGRA8888;
+ if( mImpl->mAtlasBGRA8888 )
+ {
+ actorBGRA8888 = MeshActor::New( mImpl->CreateMesh( glyphs, positions, Pixel::BGRA8888, mImpl->mAtlasBGRA8888 ) );
+ actorBGRA8888.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+
+ ShaderEffect shader = BgraShader::New();
+ actorBGRA8888.SetShaderEffect( shader );
+ }
+
+ // If we have both monochrome & color glyphs, two mesh actors are returned in a container
+ if( actorL8 && actorBGRA8888 )
+ {
+ mImpl->mActor = ImageActor::New();
+ mImpl->mActor.Add( actorL8 );
+ mImpl->mActor.Add( actorBGRA8888 );
+ }
+ else
+ {
+ if( actorL8 )
+ {
+ mImpl->mActor = actorL8;
+ }
+ else if( actorBGRA8888 )
+ {
+ mImpl->mActor = actorBGRA8888;
+ }
+ }
+ }
+
+ 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/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/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/internal/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/internal/text/rendering/text-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace BasicShadowShader
+{
+
+Dali::ShaderEffect New()
+{
+ std::string vertexShader = DALI_COMPOSE_SHADER(
+ void main()\n
+ {\n
+ gl_Position = 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 BasicShadowShader
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_BASIC_SHADOW_SHADER_H__
+#define __DALI_TOOLKIT_TEXT_BASIC_SHADOW_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 BasicShadowShader
+{
+
+/**
+ * Create a basic text shadow shader.
+ * @return A handle to a newly allocated ShaderEffect
+ */
+Dali::ShaderEffect New();
+
+} // namespace BasicShadowShader
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_BASIC_SHADOW_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.
+ *
+ */
+
+// INTERNAL HEADERS
+#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace BgraShader
+{
+
+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
+ gl_FragColor = texture2D( sTexture, vTexCoord );
+ }\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 BGRAShader
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
--- /dev/null
+
+#ifndef __DALI_TOOLKIT_TEXT_BGRA_SHADER_H__
+#define __DALI_TOOLKIT_TEXT_BGRA_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 BGRA shader for rendering glyphs.
+ */
+namespace BgraShader
+{
+
+/**
+ * Create a basic text shader.
+ * @return A handle to a newly allocated ShaderEffect
+ */
+Dali::ShaderEffect New();
+
+} // namespace BGRAShader
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_BGRA_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/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-backend.h>
+#include <dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.h>
+#include <dali-toolkit/internal/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:
+ {
+ renderer = Dali::Toolkit::Text::AtlasRenderer::New();
+ }
+ 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/internal/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__
--- /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.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/internal/text/rendering/text-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace Internal DALI_INTERNAL
+{
+class Backend;
+}
+
+/**
+ * @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__
-#ifndef __DALI_V8PLUGIN_TEXT_ACTOR_API_H__
-#define __DALI_V8PLUGIN_TEXT_ACTOR_API_H__
-
/*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
*
*
*/
-
-// EXTERNAL INCLUDES
-#include <v8.h>
-#include <dali/public-api/actors/text-actor.h>
+// CLASS HEADER
+#include <dali-toolkit/internal/text/rendering/text-renderer.h>
namespace Dali
{
-namespace V8Plugin
+namespace Toolkit
{
-namespace TextActorApi
+namespace Text
{
- Actor New( const v8::FunctionCallbackInfo< v8::Value >& args );
- void SetToNaturalSize( const v8::FunctionCallbackInfo< v8::Value >& args );
-}; // namespace TextActorApi
+Renderer::Renderer()
+{
+}
-} // namespace V8Plugin
+Renderer::~Renderer()
+{
+}
-} // namespace Dali
+} // namespace Text
+
+} // namespace Toolkit
-#endif // header __DALI_V8PLUGIN_TEXT_ACTOR_API_H__
+} // 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/internal/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/internal/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
+/*
+ * 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/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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/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/internal/text/shaper.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/text-abstraction/script.h>
+#include <dali/public-api/text-abstraction/shaping.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/font-run.h>
+#include <dali-toolkit/internal/text/logical-model-impl.h>
+#include <dali-toolkit/internal/text/script-run.h>
+#include <dali-toolkit/internal/text/visual-model-impl.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>& glyphToCharacterMap,
+ 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 );
+ glyphToCharacterMap.Resize( numberOfGlyphsReserved );
+
+ // The actual number of glyphs.
+ Length totalNumberOfGlyphs = 0u;
+
+ const Character* textBuffer = text.Begin();
+ const LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
+ GlyphInfo* glyphsBuffer = glyphs.Begin();
+ CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.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 new paragraph character.
+ // A \n is going to be shaped in order to not to mess the conversion tables.
+ // After the \n character is shaped, the glyph is going to be reset to its
+ // default in order to not to get any metric or font index for it.
+ const bool isNewParagraph = TextAbstraction::IsNewParagraph( *( textBuffer + currentIndex ) );
+
+ // The last character is always a must-break even if it's not a \n.
+ Length numberOfCharactersToShape = currentIndex - previousIndex;
+ if( mustBreak )
+ {
+ // Add one more character to shape.
+ ++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 );
+ glyphToCharacterMap.Resize( numberOfGlyphsReserved );
+
+ // Iterators are not valid anymore, set them again.
+ glyphsBuffer = glyphs.Begin();
+ glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
+ }
+
+ // Retrieve the glyphs and the glyph to character conversion map.
+ shaping.GetGlyphs( glyphsBuffer + glyphIndex,
+ glyphToCharacterMapBuffer + glyphIndex );
+
+ if( isNewParagraph )
+ {
+ // TODO : This is a work around to avoid drawing a square in the
+ // place of a new line character.
+
+ // If the last character is a \n, it resets the glyph to the default
+ // to avoid getting any metric for it.
+ GlyphInfo& glyph = *( glyphsBuffer + glyphIndex + ( numberOfGlyphs - 1u ) );
+
+ glyph = GlyphInfo();
+ }
+
+ // Update indices.
+ if( 0u != glyphIndex )
+ {
+ for( Length index = glyphIndex; index < glyphIndex + numberOfGlyphs; ++index )
+ {
+ CharacterIndex& characterIndex = *( glyphToCharacterMapBuffer + index );
+ characterIndex += previousIndex;
+ }
+ }
+
+ // 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;
+ }
+
+ // Add the number of characters per glyph.
+ charactersPerGlyph.Reserve( totalNumberOfGlyphs );
+ previousIndex = 0u;
+ for( Length index = 1u; index < totalNumberOfGlyphs; ++index )
+ {
+ const CharacterIndex characterIndex = *( glyphToCharacterMapBuffer + index );
+
+ charactersPerGlyph.PushBack( characterIndex - previousIndex );
+
+ previousIndex = characterIndex;
+ }
+
+ charactersPerGlyph.PushBack( numberOfCharacters - previousIndex );
+
+ // Resize the vectors to set the right number of items.
+ glyphs.Resize( totalNumberOfGlyphs );
+ glyphToCharacterMap.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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/font-run.h>
+#include <dali-toolkit/internal/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] glyphToCharacterMap 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>& glyphToCharacterMap,
+ 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/internal/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/internal/text/text-controller.h>
+
+// EXTERNAL INCLUDES
+#include <limits>
+#include <vector>
+#include <dali/public-api/adaptor-framework/key.h>
+#include <dali/public-api/text-abstraction/font-client.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/bidirectional-support.h>
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/layouts/layout-engine.h>
+#include <dali-toolkit/internal/text/layouts/layout-parameters.h>
+#include <dali-toolkit/internal/text/logical-model-impl.h>
+#include <dali-toolkit/internal/text/multi-language-support.h>
+#include <dali-toolkit/internal/text/script-run.h>
+#include <dali-toolkit/internal/text/segmentation.h>
+#include <dali-toolkit/internal/text/shaper.h>
+#include <dali-toolkit/internal/text/text-io.h>
+#include <dali-toolkit/internal/text/text-view.h>
+#include <dali-toolkit/internal/text/visual-model-impl.h>
+
+using std::vector;
+
+namespace
+{
+
+const float MAX_FLOAT = std::numeric_limits<float>::max();
+
+enum ModifyType
+{
+ REPLACE_TEXT, ///< Replace the entire text
+ INSERT_TEXT, ///< Insert characters at the current cursor position
+ DELETE_TEXT ///< Delete a character at the current cursor position
+};
+
+struct ModifyEvent
+{
+ ModifyType type;
+ std::string text;
+};
+
+const std::string EMPTY_STRING("");
+
+} // namespace
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct Controller::FontDefaults
+{
+ FontDefaults()
+ : mDefaultPointSize(0.0f),
+ mFontId(0u)
+ {
+ }
+
+ FontId GetFontId( TextAbstraction::FontClient& fontClient )
+ {
+ if( !mFontId )
+ {
+ Dali::TextAbstraction::PointSize26Dot6 pointSize = mDefaultPointSize*64;
+ mFontId = fontClient.GetFontId( mDefaultFontFamily, mDefaultFontStyle, pointSize );
+ }
+
+ return mFontId;
+ }
+
+ std::string mDefaultFontFamily;
+ std::string mDefaultFontStyle;
+ float mDefaultPointSize;
+ FontId mFontId;
+};
+
+struct Controller::TextInput
+{
+ // Used to queue input events until DoRelayout()
+ enum EventType
+ {
+ KEYBOARD_FOCUS_GAIN_EVENT,
+ KEYBOARD_FOCUS_LOST_EVENT,
+ CURSOR_KEY_EVENT,
+ TAP_EVENT,
+ PAN_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;
+ };
+
+ struct CursorInfo
+ {
+ CursorInfo()
+ : primaryPosition(),
+ secondaryPosition(),
+ lineHeight( 0.f ),
+ primaryCursorHeight( 0.f ),
+ secondaryCursorHeight( 0.f ),
+ isSecondaryCursor( false )
+ {}
+
+ ~CursorInfo()
+ {}
+
+ Vector2 primaryPosition; ///< The primary cursor's position.
+ Vector2 secondaryPosition; ///< The secondary cursor's position.
+ float lineHeight; ///< The height of the line where the cursor is placed.
+ float primaryCursorHeight; ///< The primary cursor's height.
+ float secondaryCursorHeight; ///< The secondary cursor's height.
+ bool isSecondaryCursor; ///< Whether the secondary cursor is valid.
+ };
+
+ /**
+ * @brief Some characters can be shaped in more than one glyph.
+ * This struct is used to retrieve metrics from these group of glyphs.
+ */
+ struct GlyphMetrics
+ {
+ GlyphMetrics()
+ : fontHeight( 0.f ),
+ advance( 0.f ),
+ ascender( 0.f ),
+ xBearing( 0.f )
+ {}
+
+ ~GlyphMetrics()
+ {}
+
+ float fontHeight; ///< The font's height of that glyphs.
+ float advance; ///< The sum of all the advances of all the glyphs.
+ float ascender; ///< The font's ascender.
+ float xBearing; ///< The x bearing of the first glyph.
+ };
+
+ enum State
+ {
+ INACTIVE,
+ SELECTING,
+ EDITING,
+ EDITING_WITH_POPUP
+ };
+
+ TextInput( LogicalModelPtr logicalModel,
+ VisualModelPtr visualModel,
+ DecoratorPtr decorator,
+ FontDefaults* fontDefaults,
+ TextAbstraction::FontClient& fontClient )
+ : mLogicalModel( logicalModel ),
+ mVisualModel( visualModel ),
+ mDecorator( decorator ),
+ mFontDefaults( fontDefaults ),
+ mFontClient( fontClient ),
+ mState( INACTIVE ),
+ mPrimaryCursorPosition( 0u ),
+ mSecondaryCursorPosition( 0u ),
+ mDecoratorUpdated( false ),
+ mCursorBlinkEnabled( true ),
+ mGrabHandleEnabled( true ),
+ mGrabHandlePopupEnabled( true ),
+ mSelectionEnabled( true ),
+ mHorizontalScrollingEnabled( true ),
+ mVerticalScrollingEnabled( false ),
+ mUpdateCursorPosition( false )
+ {}
+
+ /**
+ * @brief Helper to move the cursor, grab handle etc.
+ */
+ bool ProcessInputEvents( const Vector2& controlSize,
+ const Vector2& alignmentOffset )
+ {
+ 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 CURSOR_KEY_EVENT:
+ {
+ OnCursorKeyEvent( *iter );
+ break;
+ }
+ case TAP_EVENT:
+ {
+ OnTapEvent( *iter, alignmentOffset );
+ break;
+ }
+ case PAN_EVENT:
+ {
+ OnPanEvent( *iter, controlSize, alignmentOffset );
+ break;
+ }
+ case GRAB_HANDLE_EVENT:
+ {
+ OnGrabHandleEvent( *iter );
+ break;
+ }
+ }
+ }
+ }
+
+ // The cursor must also be repositioned after inserts into the model
+ if( mUpdateCursorPosition )
+ {
+ UpdateCursorPosition();
+ mUpdateCursorPosition = false;
+ }
+
+ mEventQueue.clear();
+
+ return mDecoratorUpdated;
+ }
+
+ void OnKeyboardFocus( bool hasFocus )
+ {
+ if( !hasFocus )
+ {
+ ChangeState( INACTIVE );
+ }
+ else
+ {
+ ChangeState( EDITING );
+ }
+ }
+
+ void OnCursorKeyEvent( const Event& event )
+ {
+ int keyCode = event.p1.mInt;
+
+ if( Dali::DALI_KEY_CURSOR_LEFT == keyCode )
+ {
+ if( mPrimaryCursorPosition > 0u )
+ {
+ mPrimaryCursorPosition = CalculateNewCursorIndex( mPrimaryCursorPosition - 1u );
+ }
+ }
+ else if( Dali::DALI_KEY_CURSOR_RIGHT == keyCode )
+ {
+ if( mLogicalModel->GetNumberOfCharacters() > mPrimaryCursorPosition )
+ {
+ mPrimaryCursorPosition = CalculateNewCursorIndex( mPrimaryCursorPosition );
+ }
+ }
+ else if( Dali::DALI_KEY_CURSOR_UP == keyCode )
+ {
+ // TODO
+ }
+ else if( Dali::DALI_KEY_CURSOR_DOWN == keyCode )
+ {
+ // TODO
+ }
+
+ UpdateCursorPosition();
+ }
+
+ void HandleCursorKey( int keyCode )
+ {
+ // TODO
+ }
+
+ void OnTapEvent( const Event& event,
+ const Vector2& alignmentOffset )
+ {
+ unsigned int tapCount = event.p1.mUint;
+
+ if( 1u == tapCount )
+ {
+ ChangeState( EDITING );
+
+ float xPosition = event.p2.mFloat - alignmentOffset.x;
+ float yPosition = event.p3.mFloat - alignmentOffset.y;
+
+ mPrimaryCursorPosition = GetClosestCursorIndex( xPosition,
+ yPosition );
+
+ UpdateCursorPosition();
+ }
+ else if( mSelectionEnabled &&
+ 2u == tapCount )
+ {
+ ChangeState( SELECTING );
+
+ RepositionSelectionHandles( event.p2.mFloat, event.p3.mFloat );
+ }
+ }
+
+ void OnPanEvent( const Event& event,
+ const Vector2& controlSize,
+ const Vector2& alignmentOffset )
+ {
+ int state = event.p1.mInt;
+
+ if( Gesture::Started == state ||
+ Gesture::Continuing == state )
+ {
+ const Vector2& actualSize = mVisualModel->GetActualSize();
+
+ if( mHorizontalScrollingEnabled )
+ {
+ const float displacementX = event.p2.mFloat;
+ mScrollPosition.x += displacementX;
+
+ // Clamp between -space & 0 (and the text alignment).
+ const float contentWidth = actualSize.width;
+ if( contentWidth > controlSize.width )
+ {
+ const float space = ( contentWidth - controlSize.width ) + alignmentOffset.x;
+ mScrollPosition.x = ( mScrollPosition.x < -space ) ? -space : mScrollPosition.x;
+ mScrollPosition.x = ( mScrollPosition.x > -alignmentOffset.x ) ? -alignmentOffset.x : mScrollPosition.x;
+
+ mDecoratorUpdated = true;
+ }
+ else
+ {
+ mScrollPosition.x = 0.f;
+ }
+ }
+
+ if( mVerticalScrollingEnabled )
+ {
+ const float displacementY = event.p3.mFloat;
+ mScrollPosition.y += displacementY;
+
+ // Clamp between -space & 0 (and the text alignment).
+ if( actualSize.height > controlSize.height )
+ {
+ const float space = ( actualSize.height - controlSize.height ) + alignmentOffset.y;
+ mScrollPosition.y = ( mScrollPosition.y < -space ) ? -space : mScrollPosition.y;
+ mScrollPosition.y = ( mScrollPosition.y > -alignmentOffset.y ) ? -alignmentOffset.y : mScrollPosition.y;
+
+ mDecoratorUpdated = true;
+ }
+ else
+ {
+ mScrollPosition.y = 0.f;
+ }
+ }
+ }
+ }
+
+ void OnGrabHandleEvent( const Event& event )
+ {
+ unsigned int state = event.p1.mUint;
+
+ if( GRAB_HANDLE_PRESSED == state )
+ {
+ float xPosition = event.p2.mFloat + mScrollPosition.x;
+ float yPosition = event.p3.mFloat + mScrollPosition.y;
+
+ mPrimaryCursorPosition = GetClosestCursorIndex( xPosition,
+ yPosition );
+
+ UpdateCursorPosition();
+
+ //mDecorator->HidePopup();
+ ChangeState ( EDITING );
+ }
+ else if ( mGrabHandlePopupEnabled &&
+ GRAB_HANDLE_RELEASED == state )
+ {
+ //mDecorator->ShowPopup();
+ ChangeState ( EDITING_WITH_POPUP );
+ mDecoratorUpdated = true;
+ }
+ }
+
+ void RepositionSelectionHandles( float visualX, float visualY )
+ {
+ // TODO - Find which word was selected
+
+ const Vector<GlyphInfo>& glyphs = mVisualModel->mGlyphs;
+ const Vector<Vector2>::SizeType glyphCount = glyphs.Count();
+
+ const Vector<Vector2>& positions = mVisualModel->mGlyphPositions;
+ const Vector<Vector2>::SizeType positionCount = positions.Count();
+
+ // Guard against glyphs which did not fit inside the layout
+ const Vector<Vector2>::SizeType count = (positionCount < glyphCount) ? positionCount : glyphCount;
+
+ if( count )
+ {
+ float primaryX = positions[0].x;
+ float secondaryX = positions[count-1].x + glyphs[count-1].width;
+
+ // TODO - multi-line selection
+ const Vector<LineRun>& lines = mVisualModel->mLines;
+ float height = lines.Count() ? lines[0].ascender + -lines[0].descender : 0.0f;
+
+ mDecorator->SetPosition( PRIMARY_SELECTION_HANDLE, primaryX, 0.0f, height );
+ mDecorator->SetPosition( SECONDARY_SELECTION_HANDLE, secondaryX, 0.0f, height );
+
+ mDecorator->ClearHighlights();
+ mDecorator->AddHighlight( primaryX, 0.0f, secondaryX, height );
+ }
+ }
+
+ void ChangeState( State newState )
+ {
+ if( mState != newState )
+ {
+ mState = newState;
+
+ if( INACTIVE == mState )
+ {
+ mDecorator->SetActiveCursor( ACTIVE_CURSOR_NONE );
+ mDecorator->StopCursorBlink();
+ mDecorator->SetGrabHandleActive( false );
+ mDecorator->SetSelectionActive( false );
+ mDecorator->SetPopupActive( false );
+ mDecoratorUpdated = true;
+ }
+ else if ( SELECTING == mState )
+ {
+ mDecorator->SetActiveCursor( ACTIVE_CURSOR_NONE );
+ mDecorator->StopCursorBlink();
+ mDecorator->SetGrabHandleActive( false );
+ mDecorator->SetSelectionActive( true );
+ mDecoratorUpdated = true;
+ }
+ else if( EDITING == mState )
+ {
+ mDecorator->SetActiveCursor( ACTIVE_CURSOR_PRIMARY );
+ if( mCursorBlinkEnabled )
+ {
+ mDecorator->StartCursorBlink();
+ }
+ if( mGrabHandleEnabled )
+ {
+ mDecorator->SetGrabHandleActive( true );
+ }
+ if( mGrabHandlePopupEnabled )
+ {
+ mDecorator->SetPopupActive( false );
+ }
+ mDecorator->SetSelectionActive( false );
+ mDecoratorUpdated = true;
+ }
+ else if( EDITING_WITH_POPUP == mState )
+ {
+ mDecorator->SetActiveCursor( ACTIVE_CURSOR_PRIMARY );
+ if( mCursorBlinkEnabled )
+ {
+ mDecorator->StartCursorBlink();
+ }
+ if( mGrabHandleEnabled )
+ {
+ mDecorator->SetGrabHandleActive( true );
+ }
+ if( mGrabHandlePopupEnabled )
+ {
+ mDecorator->SetPopupActive( true );
+ }
+ mDecorator->SetSelectionActive( false );
+ mDecoratorUpdated = true;
+ }
+ }
+ }
+
+ LineIndex GetClosestLine( float y ) const
+ {
+ float totalHeight = 0.f;
+ LineIndex lineIndex = 0u;
+
+ const Vector<LineRun>& lines = mVisualModel->mLines;
+ for( LineIndex endLine = lines.Count();
+ lineIndex < endLine;
+ ++lineIndex )
+ {
+ const LineRun& lineRun = lines[lineIndex];
+ totalHeight += lineRun.ascender + -lineRun.descender;
+ if( y < totalHeight )
+ {
+ return lineIndex;
+ }
+ }
+
+ return lineIndex-1;
+ }
+
+ /**
+ * @brief Retrieves the cursor's logical position for a given touch point x,y
+ *
+ * @param[in] visualX The touch point x.
+ * @param[in] visualY The touch point y.
+ *
+ * @return The logical cursor position (in characters). 0 is just before the first character, a value equal to the number of characters is just after the last character.
+ */
+ CharacterIndex GetClosestCursorIndex( float visualX,
+ float visualY ) const
+ {
+ CharacterIndex logicalIndex = 0u;
+
+ const Length numberOfGlyphs = mVisualModel->mGlyphs.Count();
+ const Length numberOfLines = mVisualModel->mLines.Count();
+ if( 0 == numberOfGlyphs ||
+ 0 == numberOfLines )
+ {
+ return logicalIndex;
+ }
+
+ // Transform to visual model coords
+ visualX -= mScrollPosition.x;
+ visualY -= mScrollPosition.y;
+
+ // Find which line is closest
+ const LineIndex lineIndex = GetClosestLine( visualY );
+ const LineRun& line = mVisualModel->mLines[lineIndex];
+
+ // Get the positions of the glyphs.
+ const Vector<Vector2>& positions = mVisualModel->mGlyphPositions;
+ const Vector2* const positionsBuffer = positions.Begin();
+
+ // Get the visual to logical conversion tables.
+ const CharacterIndex* const visualToLogicalBuffer = ( 0u != mLogicalModel->mVisualToLogicalMap.Count() ) ? mLogicalModel->mVisualToLogicalMap.Begin() : NULL;
+ const CharacterIndex* const visualToLogicalCursorBuffer = mLogicalModel->mVisualToLogicalCursorMap.Begin();
+
+ // Get the character to glyph conversion table.
+ const GlyphIndex* const charactersToGlyphBuffer = mVisualModel->mCharactersToGlyph.Begin();
+
+ // Get the glyphs per character table.
+ const Length* const glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin();
+
+ // If the vector is void, there is no right to left characters.
+ const bool hasRightToLeftCharacters = NULL != visualToLogicalBuffer;
+
+ const CharacterIndex startCharacter = line.characterRun.characterIndex;
+ const CharacterIndex endCharacter = line.characterRun.characterIndex + line.characterRun.numberOfCharacters;
+ DALI_ASSERT_DEBUG( endCharacter <= mLogicalModel->mText.Count() && "Invalid line info" );
+
+ // Whether there is a hit on a glyph.
+ bool matched = false;
+
+ // Traverses glyphs in visual order. To do that use the visual to logical conversion table.
+ CharacterIndex visualIndex = startCharacter;
+ for( ; !matched && ( visualIndex < endCharacter ); ++visualIndex )
+ {
+ // The character in logical order.
+ const CharacterIndex characterLogicalOrderIndex = hasRightToLeftCharacters ? *( visualToLogicalBuffer + visualIndex ) : visualIndex;
+
+ // The first glyph for that character in logical order.
+ const GlyphIndex glyphLogicalOrderIndex = *( charactersToGlyphBuffer + characterLogicalOrderIndex );
+
+ // The number of glyphs for that character
+ const Length numberOfGlyphs = *( glyphsPerCharacterBuffer + characterLogicalOrderIndex );
+
+ // Get the metrics for the group of glyphs.
+ GlyphMetrics glyphMetrics;
+ GetGlyphsMetrics( glyphLogicalOrderIndex,
+ numberOfGlyphs,
+ glyphMetrics );
+
+ const Vector2& position = *( positionsBuffer + glyphLogicalOrderIndex );
+
+ const float glyphX = -glyphMetrics.xBearing + position.x + 0.5f * glyphMetrics.advance;
+
+ if( visualX < glyphX )
+ {
+ matched = true;
+ break;
+ }
+ }
+
+ // Return the logical position of the cursor in characters.
+
+ if( !matched )
+ {
+ visualIndex = endCharacter;
+ }
+
+ return hasRightToLeftCharacters ? *( visualToLogicalCursorBuffer + visualIndex ) : visualIndex;
+ }
+
+ /**
+ * @brief Calculates the cursor's position for a given character index in the logical order.
+ *
+ * It retrieves as well the line's height and the cursor's height and
+ * if there is a valid alternative cursor, its position and height.
+ *
+ * @param[in] logical The logical cursor position (in characters). 0 is just before the first character, a value equal to the number of characters is just after the last character.
+ * @param[out] cursorInfo The line's height, the cursor's height, the cursor's position and whether there is an alternative cursor.
+ */
+ void GetCursorPosition( CharacterIndex logical,
+ CursorInfo& cursorInfo ) const
+ {
+ // TODO: Check for multiline with \n, etc...
+
+ // Check if the logical position is the first or the last one of the text.
+ const bool isFirstPosition = 0u == logical;
+ const bool isLastPosition = mLogicalModel->GetNumberOfCharacters() == logical;
+
+ if( isFirstPosition && isLastPosition )
+ {
+ // There is zero characters. Get the default font.
+
+ FontId defaultFontId = 0u;
+ if( NULL == mFontDefaults )
+ {
+ defaultFontId = mFontClient.GetFontId( EMPTY_STRING,
+ EMPTY_STRING );
+ }
+ else
+ {
+ defaultFontId = mFontDefaults->GetFontId( mFontClient );
+ }
+
+ Text::FontMetrics fontMetrics;
+ mFontClient.GetFontMetrics( defaultFontId, fontMetrics );
+
+ cursorInfo.lineHeight = fontMetrics.ascender - fontMetrics.descender;
+ cursorInfo.primaryCursorHeight = cursorInfo.lineHeight;
+
+ cursorInfo.primaryPosition.x = 0.f;
+ cursorInfo.primaryPosition.y = 0.f;
+
+ // Nothing else to do.
+ return;
+ }
+
+ // Get the previous logical index.
+ const CharacterIndex previousLogical = isFirstPosition ? 0u : logical - 1u;
+
+ // Decrease the logical index if it's the last one.
+ if( isLastPosition )
+ {
+ --logical;
+ }
+
+ // Get the direction of the character and the previous one.
+ const CharacterDirection* const modelCharacterDirectionsBuffer = ( 0u != mLogicalModel->mCharacterDirections.Count() ) ? mLogicalModel->mCharacterDirections.Begin() : NULL;
+
+ CharacterDirection isCurrentRightToLeft = false;
+ CharacterDirection isPreviousRightToLeft = false;
+ if( NULL != modelCharacterDirectionsBuffer ) // If modelCharacterDirectionsBuffer is NULL, it means the whole text is left to right.
+ {
+ isCurrentRightToLeft = *( modelCharacterDirectionsBuffer + logical );
+ isPreviousRightToLeft = *( modelCharacterDirectionsBuffer + previousLogical );
+ }
+
+ // Get the line where the character is laid-out.
+ const LineRun* modelLines = mVisualModel->mLines.Begin();
+
+ const LineIndex lineIndex = mVisualModel->GetLineOfCharacter( logical );
+ const LineRun& line = *( modelLines + lineIndex );
+
+ // Get the paragraph's direction.
+ const CharacterDirection isRightToLeftParagraph = line.direction;
+
+ // Check whether there is an alternative position:
+
+ cursorInfo.isSecondaryCursor = ( isCurrentRightToLeft != isPreviousRightToLeft ) ||
+ ( isLastPosition && ( isRightToLeftParagraph != isCurrentRightToLeft ) );
+
+ // Set the line height.
+ cursorInfo.lineHeight = line.ascender + -line.descender;
+
+ // Convert the cursor position into the glyph position.
+ CharacterIndex characterIndex = logical;
+ if( cursorInfo.isSecondaryCursor &&
+ ( isRightToLeftParagraph != isCurrentRightToLeft ) )
+ {
+ characterIndex = previousLogical;
+ }
+
+ const GlyphIndex currentGlyphIndex = *( mVisualModel->mCharactersToGlyph.Begin() + characterIndex );
+ const Length numberOfGlyphs = *( mVisualModel->mGlyphsPerCharacter.Begin() + characterIndex );
+ const Length numberOfCharacters = *( mVisualModel->mCharactersPerGlyph.Begin() +currentGlyphIndex );
+
+ // Get the metrics for the group of glyphs.
+ GlyphMetrics glyphMetrics;
+ GetGlyphsMetrics( currentGlyphIndex,
+ numberOfGlyphs,
+ glyphMetrics );
+
+ float interGlyphAdvance = 0.f;
+ if( !isLastPosition &&
+ ( numberOfCharacters > 1u ) )
+ {
+ const CharacterIndex firstIndex = *( mVisualModel->mGlyphsToCharacters.Begin() + currentGlyphIndex );
+ interGlyphAdvance = static_cast<float>( characterIndex - firstIndex ) * glyphMetrics.advance / static_cast<float>( numberOfCharacters );
+ }
+
+ // Get the glyph position and x bearing.
+ const Vector2& currentPosition = *( mVisualModel->mGlyphPositions.Begin() + currentGlyphIndex );
+
+ // Set the cursor's height.
+ cursorInfo.primaryCursorHeight = glyphMetrics.fontHeight;
+
+ // Set the position.
+ cursorInfo.primaryPosition.x = -glyphMetrics.xBearing + currentPosition.x + ( isCurrentRightToLeft ? glyphMetrics.advance : interGlyphAdvance );
+ cursorInfo.primaryPosition.y = line.ascender - glyphMetrics.ascender;
+
+ if( isLastPosition )
+ {
+ // The position of the cursor after the last character needs special
+ // care depending on its direction and the direction of the paragraph.
+
+ if( cursorInfo.isSecondaryCursor )
+ {
+ // Need to find the first character after the last character with the paragraph's direction.
+ // i.e l0 l1 l2 r0 r1 should find r0.
+
+ // TODO: check for more than one line!
+ characterIndex = isRightToLeftParagraph ? line.characterRun.characterIndex : line.characterRun.characterIndex + line.characterRun.numberOfCharacters - 1u;
+ characterIndex = mLogicalModel->GetLogicalCharacterIndex( characterIndex );
+
+ const GlyphIndex glyphIndex = *( mVisualModel->mCharactersToGlyph.Begin() + characterIndex );
+ const Length numberOfGlyphs = *( mVisualModel->mGlyphsPerCharacter.Begin() + characterIndex );
+
+ const Vector2& position = *( mVisualModel->mGlyphPositions.Begin() + glyphIndex );
+
+ // Get the metrics for the group of glyphs.
+ GlyphMetrics glyphMetrics;
+ GetGlyphsMetrics( glyphIndex,
+ numberOfGlyphs,
+ glyphMetrics );
+
+ cursorInfo.primaryPosition.x = -glyphMetrics.xBearing + position.x + ( isRightToLeftParagraph ? 0.f : glyphMetrics.advance );
+
+ cursorInfo.primaryPosition.y = line.ascender - glyphMetrics.ascender;
+ }
+ else
+ {
+ if( !isCurrentRightToLeft )
+ {
+ cursorInfo.primaryPosition.x += glyphMetrics.advance;
+ }
+ else
+ {
+ cursorInfo.primaryPosition.x -= glyphMetrics.advance;
+ }
+ }
+ }
+
+ // Set the alternative cursor position.
+ if( cursorInfo.isSecondaryCursor )
+ {
+ // Convert the cursor position into the glyph position.
+ const CharacterIndex previousCharacterIndex = ( ( isRightToLeftParagraph != isCurrentRightToLeft ) ? logical : previousLogical );
+ const GlyphIndex previousGlyphIndex = *( mVisualModel->mCharactersToGlyph.Begin() + previousCharacterIndex );
+ const Length numberOfGlyphs = *( mVisualModel->mGlyphsPerCharacter.Begin() + previousCharacterIndex );
+
+ // Get the glyph position.
+ const Vector2& previousPosition = *( mVisualModel->mGlyphPositions.Begin() + previousGlyphIndex );
+
+ // Get the metrics for the group of glyphs.
+ GlyphMetrics glyphMetrics;
+ GetGlyphsMetrics( previousGlyphIndex,
+ numberOfGlyphs,
+ glyphMetrics );
+
+ // Set the cursor position and height.
+ cursorInfo.secondaryPosition.x = -glyphMetrics.xBearing + previousPosition.x + ( ( ( isLastPosition && !isCurrentRightToLeft ) ||
+ ( !isLastPosition && isCurrentRightToLeft ) ) ? glyphMetrics.advance : 0.f );
+
+ cursorInfo.secondaryCursorHeight = 0.5f * glyphMetrics.fontHeight;
+
+ cursorInfo.secondaryPosition.y = cursorInfo.lineHeight - cursorInfo.secondaryCursorHeight - line.descender - ( glyphMetrics.fontHeight - glyphMetrics.ascender );
+
+ // Update the primary cursor height as well.
+ cursorInfo.primaryCursorHeight *= 0.5f;
+ }
+ }
+
+ /**
+ * @brief Get some glyph's metrics of a group of glyphs formed as a result of shaping one character.
+ *
+ * @param[in] glyphIndex The index to the first glyph.
+ * @param[in] numberOfGlyphs The number of glyphs.
+ * @param[out] glyphMetrics Some glyph metrics (font height, advance, ascender and x bearing).
+ */
+ void GetGlyphsMetrics( GlyphIndex glyphIndex,
+ Length numberOfGlyphs,
+ GlyphMetrics& glyphMetrics ) const
+ {
+ const GlyphInfo* glyphsBuffer = mVisualModel->mGlyphs.Begin();
+
+ const GlyphInfo& firstGlyph = *( glyphsBuffer + glyphIndex );
+
+ Text::FontMetrics fontMetrics;
+ mFontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics );
+
+ glyphMetrics.fontHeight = fontMetrics.height;
+ glyphMetrics.advance = firstGlyph.advance;
+ glyphMetrics.ascender = fontMetrics.ascender;
+ glyphMetrics.xBearing = firstGlyph.xBearing;
+
+ for( unsigned int i = 1u; i < numberOfGlyphs; ++i )
+ {
+ const GlyphInfo& glyphInfo = *( glyphsBuffer + glyphIndex + i );
+
+ glyphMetrics.advance += glyphInfo.advance;
+ }
+ }
+
+ /**
+ * @brief Calculates the new cursor index.
+ *
+ * It takes into account that in some scripts multiple characters can form a glyph and all of them
+ * need to be jumped with one key event.
+ *
+ * @param[in] index The initial new index.
+ *
+ * @return The new cursor index.
+ */
+ CharacterIndex CalculateNewCursorIndex( CharacterIndex index ) const
+ {
+ CharacterIndex cursorIndex = mPrimaryCursorPosition;
+
+ const Script script = mLogicalModel->GetScript( index );
+ const GlyphIndex* charactersToGlyphBuffer = mVisualModel->mCharactersToGlyph.Begin();
+ const Length* charactersPerGlyphBuffer = mVisualModel->mCharactersPerGlyph.Begin();
+
+ Length numberOfCharacters = 0u;
+ if( TextAbstraction::LATIN == script )
+ {
+ // Prevents to jump the whole Latin ligatures like fi, ff, ...
+ numberOfCharacters = 1u;
+ }
+ else
+ {
+ GlyphIndex glyphIndex = *( charactersToGlyphBuffer + index );
+ numberOfCharacters = *( charactersPerGlyphBuffer + glyphIndex );
+
+ while( 0u == numberOfCharacters )
+ {
+ numberOfCharacters = *( charactersPerGlyphBuffer + glyphIndex );
+ ++glyphIndex;
+ }
+ }
+
+ if( index < mPrimaryCursorPosition )
+ {
+ cursorIndex -= numberOfCharacters;
+ }
+ else
+ {
+ cursorIndex += numberOfCharacters;
+ }
+
+ return cursorIndex;
+ }
+
+ void UpdateCursorPosition()
+ {
+ CursorInfo cursorInfo;
+
+ GetCursorPosition( mPrimaryCursorPosition,
+ cursorInfo );
+
+ mDecorator->SetPosition( PRIMARY_CURSOR,
+ cursorInfo.primaryPosition.x,
+ cursorInfo.primaryPosition.y,
+ cursorInfo.primaryCursorHeight,
+ cursorInfo.lineHeight );
+
+ if( cursorInfo.isSecondaryCursor )
+ {
+ mDecorator->SetActiveCursor( ACTIVE_CURSOR_BOTH );
+ mDecorator->SetPosition( SECONDARY_CURSOR,
+ cursorInfo.secondaryPosition.x,
+ cursorInfo.secondaryPosition.y,
+ cursorInfo.secondaryCursorHeight,
+ cursorInfo.lineHeight );
+ }
+ else
+ {
+ mDecorator->SetActiveCursor( ACTIVE_CURSOR_PRIMARY );
+ }
+
+ mUpdateCursorPosition = false;
+ mDecoratorUpdated = true;
+ }
+
+ LogicalModelPtr mLogicalModel;
+ VisualModelPtr mVisualModel;
+ DecoratorPtr mDecorator;
+ FontDefaults* mFontDefaults;
+ TextAbstraction::FontClient& mFontClient;
+ std::string mPlaceholderText;
+
+ /**
+ * 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.
+
+ State mState; ///< Selection mode, edit mode etc.
+
+ CharacterIndex mPrimaryCursorPosition; ///< Index into logical model for primary cursor
+ CharacterIndex mSecondaryCursorPosition; ///< Index into logical model for secondary cursor
+
+ /**
+ * 0,0 means that the top-left corner of the layout matches the top-left corner of the UI control.
+ * Typically this will have a negative value with scrolling occurs.
+ */
+ Vector2 mScrollPosition; ///< The text is offset by this position when scrolling.
+
+ bool mDecoratorUpdated : 1; ///< True if the decorator was updated during event processing
+ bool mCursorBlinkEnabled : 1; ///< True if cursor should blink when active
+ bool mGrabHandleEnabled : 1; ///< True if grab handle is enabled
+ bool mGrabHandlePopupEnabled : 1; ///< True if the grab handle popu-up should be shown
+ bool mSelectionEnabled : 1; ///< True if selection handles, highlight etc. are enabled
+ bool mHorizontalScrollingEnabled : 1; ///< True if horizontal scrolling is enabled
+ bool mVerticalScrollingEnabled : 1; ///< True if vertical scrolling is enabled
+ bool mUpdateCursorPosition : 1; ///< True if the visual position of the cursor must be recalculated
+};
+
+struct Controller::Impl
+{
+ Impl( ControlInterface& controlInterface )
+ : mControlInterface( controlInterface ),
+ mLogicalModel(),
+ mVisualModel(),
+ mFontDefaults( NULL ),
+ mTextInput( NULL ),
+ mFontClient(),
+ mView(),
+ mLayoutEngine(),
+ mModifyEvents(),
+ mControlSize(),
+ mAlignmentOffset(),
+ mOperationsPending( NO_OPERATION ),
+ mRecalculateNaturalSize( true )
+ {
+ mLogicalModel = LogicalModel::New();
+ mVisualModel = VisualModel::New();
+
+ mFontClient = TextAbstraction::FontClient::Get();
+
+ mView.SetVisualModel( mVisualModel );
+
+ // Set the text properties to default
+ mVisualModel->SetTextColor( Color::WHITE );
+ mVisualModel->SetShadowOffset( Vector2::ZERO );
+ mVisualModel->SetShadowColor( Vector4::ZERO );
+ mVisualModel->SetUnderlineEnabled( false );
+ }
+
+ ~Impl()
+ {
+ delete mTextInput;
+ }
+
+ ControlInterface& mControlInterface; ///< Reference to the text controller.
+ LogicalModelPtr mLogicalModel; ///< Pointer to the logical model.
+ VisualModelPtr mVisualModel; ///< Pointer to the visual model.
+ FontDefaults* mFontDefaults; ///< Avoid allocating this when the user does not specify a font.
+ Controller::TextInput* mTextInput; ///< Avoid allocating everything for text input until EnableTextInput().
+ TextAbstraction::FontClient mFontClient; ///< Handle to the font client.
+ View mView; ///< The view interface to the rendering back-end.
+ LayoutEngine mLayoutEngine; ///< The layout engine.
+ std::vector<ModifyEvent> mModifyEvents; ///< Temporary stores the text set until the next relayout.
+ Size mControlSize; ///< The size of the control.
+ Vector2 mAlignmentOffset; ///< Vertical and horizontal offset of the whole text inside the control due to alignment.
+ OperationsMask mOperationsPending; ///< Operations pending to be done to layout the text.
+ bool mRecalculateNaturalSize:1; ///< Whether the natural size needs to be recalculated.
+};
+
+ControllerPtr Controller::New( ControlInterface& controlInterface )
+{
+ return ControllerPtr( new Controller( controlInterface ) );
+}
+
+void Controller::SetText( const std::string& text )
+{
+ // Cancel previously queued inserts etc.
+ mImpl->mModifyEvents.clear();
+
+ // Keep until size negotiation
+ ModifyEvent event;
+ event.type = REPLACE_TEXT;
+ event.text = text;
+ mImpl->mModifyEvents.push_back( event );
+
+ if( mImpl->mTextInput )
+ {
+ // Cancel previously queued events
+ mImpl->mTextInput->mEventQueue.clear();
+
+ // TODO - Hide selection decorations
+ }
+}
+
+void Controller::GetText( std::string& text ) const
+{
+ if( !mImpl->mModifyEvents.empty() &&
+ REPLACE_TEXT == mImpl->mModifyEvents[0].type )
+ {
+ text = mImpl->mModifyEvents[0].text;
+ }
+ else
+ {
+ // TODO - Convert from UTF-32
+ }
+}
+
+void Controller::SetPlaceholderText( const std::string& text )
+{
+ if( !mImpl->mTextInput )
+ {
+ mImpl->mTextInput->mPlaceholderText = text;
+ }
+}
+
+void Controller::GetPlaceholderText( std::string& text ) const
+{
+ if( !mImpl->mTextInput )
+ {
+ text = mImpl->mTextInput->mPlaceholderText;
+ }
+}
+
+void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily )
+{
+ if( !mImpl->mFontDefaults )
+ {
+ mImpl->mFontDefaults = new Controller::FontDefaults();
+ }
+
+ mImpl->mFontDefaults->mDefaultFontFamily = defaultFontFamily;
+ mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
+ mImpl->mOperationsPending = ALL_OPERATIONS;
+ mImpl->mRecalculateNaturalSize = true;
+
+ // Clear the font-specific data
+ mImpl->mLogicalModel->mFontRuns.Clear();
+ mImpl->mVisualModel->mGlyphs.Clear();
+ mImpl->mVisualModel->mGlyphsToCharacters.Clear();
+ mImpl->mVisualModel->mCharactersToGlyph.Clear();
+ mImpl->mVisualModel->mCharactersPerGlyph.Clear();
+ mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
+ mImpl->mVisualModel->mGlyphPositions.Clear();
+ mImpl->mVisualModel->mLines.Clear();
+ mImpl->mVisualModel->ClearCaches();
+
+ RequestRelayout();
+}
+
+const std::string& Controller::GetDefaultFontFamily() const
+{
+ if( mImpl->mFontDefaults )
+ {
+ return mImpl->mFontDefaults->mDefaultFontFamily;
+ }
+
+ return EMPTY_STRING;
+}
+
+void Controller::SetDefaultFontStyle( const std::string& defaultFontStyle )
+{
+ if( !mImpl->mFontDefaults )
+ {
+ mImpl->mFontDefaults = new Controller::FontDefaults();
+ }
+
+ mImpl->mFontDefaults->mDefaultFontStyle = defaultFontStyle;
+ mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
+ mImpl->mOperationsPending = ALL_OPERATIONS;
+ mImpl->mRecalculateNaturalSize = true;
+
+ // Clear the font-specific data
+ mImpl->mLogicalModel->mFontRuns.Clear();
+ mImpl->mVisualModel->mGlyphs.Clear();
+ mImpl->mVisualModel->mGlyphsToCharacters.Clear();
+ mImpl->mVisualModel->mCharactersToGlyph.Clear();
+ mImpl->mVisualModel->mCharactersPerGlyph.Clear();
+ mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
+ mImpl->mVisualModel->mGlyphPositions.Clear();
+ mImpl->mVisualModel->mLines.Clear();
+ mImpl->mVisualModel->ClearCaches();
+
+ RequestRelayout();
+}
+
+const std::string& Controller::GetDefaultFontStyle() const
+{
+ if( mImpl->mFontDefaults )
+ {
+ return mImpl->mFontDefaults->mDefaultFontStyle;
+ }
+
+ return EMPTY_STRING;
+}
+
+void Controller::SetDefaultPointSize( float pointSize )
+{
+ if( !mImpl->mFontDefaults )
+ {
+ mImpl->mFontDefaults = new Controller::FontDefaults();
+ }
+
+ mImpl->mFontDefaults->mDefaultPointSize = pointSize;
+ mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
+ mImpl->mOperationsPending = ALL_OPERATIONS;
+ mImpl->mRecalculateNaturalSize = true;
+
+ // Clear the font-specific data
+ mImpl->mLogicalModel->mFontRuns.Clear();
+ mImpl->mVisualModel->mGlyphs.Clear();
+ mImpl->mVisualModel->mGlyphsToCharacters.Clear();
+ mImpl->mVisualModel->mCharactersToGlyph.Clear();
+ mImpl->mVisualModel->mCharactersPerGlyph.Clear();
+ mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
+ mImpl->mVisualModel->mGlyphPositions.Clear();
+ mImpl->mVisualModel->mLines.Clear();
+ mImpl->mVisualModel->ClearCaches();
+
+ RequestRelayout();
+}
+
+float Controller::GetDefaultPointSize() const
+{
+ if( mImpl->mFontDefaults )
+ {
+ return mImpl->mFontDefaults->mDefaultPointSize;
+ }
+
+ return 0.0f;
+}
+
+void Controller::GetDefaultFonts( Vector<FontRun>& fonts, Length numberOfCharacters ) const
+{
+ if( mImpl->mFontDefaults )
+ {
+ FontRun fontRun;
+ fontRun.characterRun.characterIndex = 0;
+ fontRun.characterRun.numberOfCharacters = numberOfCharacters;
+ fontRun.fontId = mImpl->mFontDefaults->GetFontId( mImpl->mFontClient );
+ fontRun.isDefault = true;
+
+ fonts.PushBack( fontRun );
+ }
+}
+
+const Vector4& Controller::GetTextColor() const
+{
+ return mImpl->mVisualModel->GetTextColor();
+}
+
+const Vector2& Controller::GetShadowOffset() const
+{
+ return mImpl->mVisualModel->GetShadowOffset();
+}
+
+const Vector4& Controller::GetShadowColor() const
+{
+ return mImpl->mVisualModel->GetShadowColor();
+}
+
+const Vector4& Controller::GetUnderlineColor() const
+{
+ return mImpl->mVisualModel->GetUnderlineColor();
+}
+
+bool Controller::IsUnderlineEnabled() const
+{
+ return mImpl->mVisualModel->IsUnderlineEnabled();
+}
+
+void Controller::SetTextColor( const Vector4& textColor )
+{
+ mImpl->mVisualModel->SetTextColor( textColor );
+}
+
+void Controller::SetShadowOffset( const Vector2& shadowOffset )
+{
+ mImpl->mVisualModel->SetShadowOffset( shadowOffset );
+}
+
+void Controller::SetShadowColor( const Vector4& shadowColor )
+{
+ mImpl->mVisualModel->SetShadowColor( shadowColor );
+}
+
+void Controller::SetUnderlineColor( const Vector4& color )
+{
+ mImpl->mVisualModel->SetUnderlineColor( color );
+}
+
+void Controller::SetUnderlineEnabled( bool enabled )
+{
+ mImpl->mVisualModel->SetUnderlineEnabled( enabled );
+}
+
+void Controller::EnableTextInput( DecoratorPtr decorator )
+{
+ if( !mImpl->mTextInput )
+ {
+ mImpl->mTextInput = new TextInput( mImpl->mLogicalModel,
+ mImpl->mVisualModel,
+ decorator,
+ mImpl->mFontDefaults,
+ mImpl->mFontClient );
+ }
+}
+
+void Controller::SetEnableCursorBlink( bool enable )
+{
+ DALI_ASSERT_DEBUG( NULL != mImpl->mTextInput && "TextInput disabled" );
+
+ if( mImpl->mTextInput )
+ {
+ mImpl->mTextInput->mCursorBlinkEnabled = enable;
+
+ if( !enable &&
+ mImpl->mTextInput->mDecorator )
+ {
+ mImpl->mTextInput->mDecorator->StopCursorBlink();
+ }
+ }
+}
+
+bool Controller::GetEnableCursorBlink() const
+{
+ if( mImpl->mTextInput )
+ {
+ return mImpl->mTextInput->mCursorBlinkEnabled;
+ }
+
+ return false;
+}
+
+const Vector2& Controller::GetScrollPosition() const
+{
+ if( mImpl->mTextInput )
+ {
+ return mImpl->mTextInput->mScrollPosition;
+ }
+
+ return Vector2::ZERO;
+}
+
+const Vector2& Controller::GetAlignmentOffset() const
+{
+ return mImpl->mAlignmentOffset;
+}
+
+Vector3 Controller::GetNaturalSize()
+{
+ Vector3 naturalSize;
+
+ // Make sure the model is up-to-date before layouting
+ ProcessModifyEvents();
+
+ if( mImpl->mRecalculateNaturalSize )
+ {
+ // 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 |
+ BIDI_INFO |
+ SHAPE_TEXT |
+ GET_GLYPH_METRICS );
+ // Make sure the model is up-to-date before layouting
+ UpdateModel( onlyOnceOperations );
+
+ // Operations that need to be done if the size changes.
+ const OperationsMask sizeOperations = static_cast<OperationsMask>( LAYOUT |
+ ALIGN |
+ REORDER );
+
+ DoRelayout( Size( MAX_FLOAT, MAX_FLOAT ),
+ static_cast<OperationsMask>( onlyOnceOperations |
+ sizeOperations ),
+ naturalSize.GetVectorXY() );
+
+ // Do not do again the only once operations.
+ mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending & ~onlyOnceOperations );
+
+ // Do the size related operations again.
+ mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | sizeOperations );
+
+ // Stores the natural size to avoid recalculate it again
+ // unless the text/style changes.
+ mImpl->mVisualModel->SetNaturalSize( naturalSize.GetVectorXY() );
+
+ mImpl->mRecalculateNaturalSize = false;
+ }
+ else
+ {
+ naturalSize = mImpl->mVisualModel->GetNaturalSize();
+ }
+
+ return naturalSize;
+}
+
+float Controller::GetHeightForWidth( float width )
+{
+ // Make sure the model is up-to-date before layouting
+ ProcessModifyEvents();
+
+ Size layoutSize;
+ if( width != mImpl->mControlSize.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 |
+ BIDI_INFO |
+ SHAPE_TEXT |
+ GET_GLYPH_METRICS );
+ // Make sure the model is up-to-date before layouting
+ UpdateModel( onlyOnceOperations );
+
+ // Operations that need to be done if the size changes.
+ const OperationsMask sizeOperations = static_cast<OperationsMask>( LAYOUT |
+ ALIGN |
+ REORDER );
+
+ DoRelayout( Size( width, MAX_FLOAT ),
+ static_cast<OperationsMask>( onlyOnceOperations |
+ sizeOperations ),
+ layoutSize );
+
+ // Do not do again the only once operations.
+ mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending & ~onlyOnceOperations );
+
+ // Do the size related operations again.
+ mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | sizeOperations );
+ }
+ else
+ {
+ layoutSize = mImpl->mVisualModel->GetActualSize();
+ }
+
+ return layoutSize.height;
+}
+
+bool Controller::Relayout( const Size& size )
+{
+ if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
+ {
+ bool glyphsRemoved( false );
+ if( 0u != mImpl->mVisualModel->GetNumberOfGlyphPositions() )
+ {
+ mImpl->mVisualModel->SetGlyphPositions( NULL, 0u );
+ glyphsRemoved = true;
+ }
+
+ // Not worth to relayout if width or height is equal to zero.
+ return glyphsRemoved;
+ }
+
+ if( size != mImpl->mControlSize )
+ {
+ // Operations that need to be done if the size changes.
+ mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
+ LAYOUT |
+ ALIGN |
+ UPDATE_ACTUAL_SIZE |
+ REORDER );
+
+ mImpl->mControlSize = size;
+ }
+
+ // Make sure the model is up-to-date before layouting
+ ProcessModifyEvents();
+ UpdateModel( mImpl->mOperationsPending );
+
+ Size layoutSize;
+ bool updated = DoRelayout( mImpl->mControlSize,
+ mImpl->mOperationsPending,
+ layoutSize );
+
+ // Do not re-do any operation until something changes.
+ mImpl->mOperationsPending = NO_OPERATION;
+
+ // After doing the text layout, the alignment offset to place the actor in the desired position can be calculated.
+ CalculateTextAlignment( size );
+
+ if( mImpl->mTextInput )
+ {
+ // Move the cursor, grab handle etc.
+ updated = mImpl->mTextInput->ProcessInputEvents( mImpl->mControlSize, mImpl->mAlignmentOffset ) || updated;
+ }
+
+ return updated;
+}
+
+void Controller::ProcessModifyEvents()
+{
+ std::vector<ModifyEvent>& events = mImpl->mModifyEvents;
+
+ for( unsigned int i=0; i<events.size(); ++i )
+ {
+ if( REPLACE_TEXT == events[0].type )
+ {
+ // A (single) replace event should come first, otherwise we wasted time processing NOOP events
+ DALI_ASSERT_DEBUG( 0 == i && "Unexpected REPLACE event" );
+
+ ReplaceTextEvent( events[0].text );
+ }
+ else if( INSERT_TEXT == events[0].type )
+ {
+ InsertTextEvent( events[0].text );
+ }
+ else if( DELETE_TEXT == events[0].type )
+ {
+ DeleteTextEvent();
+ }
+ }
+
+ // Discard temporary text
+ events.clear();
+}
+
+void Controller::ReplaceTextEvent( const std::string& text )
+{
+ // Reset buffers.
+ mImpl->mLogicalModel->mText.Clear();
+ mImpl->mLogicalModel->mScriptRuns.Clear();
+ mImpl->mLogicalModel->mFontRuns.Clear();
+ mImpl->mLogicalModel->mLineBreakInfo.Clear();
+ mImpl->mLogicalModel->mWordBreakInfo.Clear();
+ mImpl->mLogicalModel->mBidirectionalParagraphInfo.Clear();
+ mImpl->mLogicalModel->mCharacterDirections.Clear();
+ mImpl->mLogicalModel->mBidirectionalLineInfo.Clear();
+ mImpl->mLogicalModel->mLogicalToVisualMap.Clear();
+ mImpl->mLogicalModel->mVisualToLogicalMap.Clear();
+ mImpl->mVisualModel->mGlyphs.Clear();
+ mImpl->mVisualModel->mGlyphsToCharacters.Clear();
+ mImpl->mVisualModel->mCharactersToGlyph.Clear();
+ mImpl->mVisualModel->mCharactersPerGlyph.Clear();
+ mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
+ mImpl->mVisualModel->mGlyphPositions.Clear();
+ mImpl->mVisualModel->mLines.Clear();
+ mImpl->mVisualModel->ClearCaches();
+
+ // Convert text into UTF-32
+ Vector<Character>& utf32Characters = mImpl->mLogicalModel->mText;
+ 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.
+ Length characterCount = Utf8ToUtf32( utf8, text.size(), utf32Characters.Begin() );
+ utf32Characters.Resize( characterCount );
+
+ // Reset the cursor position
+ if( mImpl->mTextInput )
+ {
+ mImpl->mTextInput->mPrimaryCursorPosition = characterCount;
+ // TODO - handle secondary cursor
+ }
+
+ // The natural size needs to be re-calculated.
+ mImpl->mRecalculateNaturalSize = true;
+
+ // Apply modifications to the model
+ mImpl->mOperationsPending = ALL_OPERATIONS;
+ UpdateModel( ALL_OPERATIONS );
+ mImpl->mOperationsPending = static_cast<OperationsMask>( LAYOUT |
+ ALIGN |
+ UPDATE_ACTUAL_SIZE |
+ REORDER );
+}
+
+void Controller::InsertTextEvent( const std::string& text )
+{
+ DALI_ASSERT_DEBUG( NULL != mImpl->mTextInput && "Unexpected InsertTextEvent" );
+
+ // TODO - Optimize this
+ mImpl->mLogicalModel->mScriptRuns.Clear();
+ mImpl->mLogicalModel->mFontRuns.Clear();
+ mImpl->mLogicalModel->mLineBreakInfo.Clear();
+ mImpl->mLogicalModel->mWordBreakInfo.Clear();
+ mImpl->mLogicalModel->mBidirectionalParagraphInfo.Clear();
+ mImpl->mLogicalModel->mCharacterDirections.Clear();
+ mImpl->mLogicalModel->mBidirectionalLineInfo.Clear();
+ mImpl->mLogicalModel->mLogicalToVisualMap.Clear();
+ mImpl->mLogicalModel->mVisualToLogicalMap.Clear();
+ mImpl->mVisualModel->mGlyphs.Clear();
+ mImpl->mVisualModel->mGlyphsToCharacters.Clear();
+ mImpl->mVisualModel->mCharactersToGlyph.Clear();
+ mImpl->mVisualModel->mCharactersPerGlyph.Clear();
+ mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
+ mImpl->mVisualModel->mGlyphPositions.Clear();
+ mImpl->mVisualModel->mLines.Clear();
+ mImpl->mVisualModel->ClearCaches();
+
+ // Convert text into UTF-32
+ Vector<Character> utf32Characters;
+ 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.
+ Length characterCount = Utf8ToUtf32( utf8, text.size(), utf32Characters.Begin() );
+ utf32Characters.Resize( characterCount );
+
+ // Insert at current cursor position
+ Vector<Character>& modifyText = mImpl->mLogicalModel->mText;
+ CharacterIndex& cursorIndex = mImpl->mTextInput->mPrimaryCursorPosition;
+
+ if( cursorIndex < modifyText.Count() )
+ {
+ modifyText.Insert( modifyText.Begin() + cursorIndex, utf32Characters.Begin(), utf32Characters.End() );
+ }
+ else
+ {
+ modifyText.Insert( modifyText.End(), utf32Characters.Begin(), utf32Characters.End() );
+ }
+
+ // Advance the cursor position
+ ++cursorIndex;
+
+ // The natural size needs to be re-calculated.
+ mImpl->mRecalculateNaturalSize = true;
+
+ // Apply modifications to the model; TODO - Optimize this
+ mImpl->mOperationsPending = ALL_OPERATIONS;
+ UpdateModel( ALL_OPERATIONS );
+ mImpl->mOperationsPending = static_cast<OperationsMask>( LAYOUT |
+ ALIGN |
+ UPDATE_ACTUAL_SIZE |
+ REORDER );
+
+ // Queue a cursor reposition event; this must wait until after DoRelayout()
+ mImpl->mTextInput->mUpdateCursorPosition = true;
+}
+
+void Controller::DeleteTextEvent()
+{
+ DALI_ASSERT_DEBUG( NULL != mImpl->mTextInput && "Unexpected InsertTextEvent" );
+
+ // TODO - Optimize this
+ mImpl->mLogicalModel->mScriptRuns.Clear();
+ mImpl->mLogicalModel->mFontRuns.Clear();
+ mImpl->mLogicalModel->mLineBreakInfo.Clear();
+ mImpl->mLogicalModel->mWordBreakInfo.Clear();
+ mImpl->mLogicalModel->mBidirectionalParagraphInfo.Clear();
+ mImpl->mLogicalModel->mCharacterDirections.Clear();
+ mImpl->mLogicalModel->mBidirectionalLineInfo.Clear();
+ mImpl->mLogicalModel->mLogicalToVisualMap.Clear();
+ mImpl->mLogicalModel->mVisualToLogicalMap.Clear();
+ mImpl->mVisualModel->mGlyphs.Clear();
+ mImpl->mVisualModel->mGlyphsToCharacters.Clear();
+ mImpl->mVisualModel->mCharactersToGlyph.Clear();
+ mImpl->mVisualModel->mCharactersPerGlyph.Clear();
+ mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
+ mImpl->mVisualModel->mGlyphPositions.Clear();
+ mImpl->mVisualModel->mLines.Clear();
+ mImpl->mVisualModel->ClearCaches();
+
+ // Delte at current cursor position
+ Vector<Character>& modifyText = mImpl->mLogicalModel->mText;
+ CharacterIndex& cursorIndex = mImpl->mTextInput->mPrimaryCursorPosition;
+
+ if( cursorIndex > 0 &&
+ cursorIndex-1 < modifyText.Count() )
+ {
+ modifyText.Remove( modifyText.Begin() + cursorIndex - 1 );
+
+ // Cursor position retreat
+ --cursorIndex;
+ }
+
+ // The natural size needs to be re-calculated.
+ mImpl->mRecalculateNaturalSize = true;
+
+ // Apply modifications to the model; TODO - Optimize this
+ mImpl->mOperationsPending = ALL_OPERATIONS;
+ UpdateModel( ALL_OPERATIONS );
+ mImpl->mOperationsPending = static_cast<OperationsMask>( LAYOUT |
+ ALIGN |
+ UPDATE_ACTUAL_SIZE |
+ REORDER );
+
+ // Queue a cursor reposition event; this must wait until after DoRelayout()
+ mImpl->mTextInput->mUpdateCursorPosition = true;
+}
+
+void Controller::UpdateModel( OperationsMask operationsRequired )
+{
+ // Calculate the operations to be done.
+ const OperationsMask operations = static_cast<OperationsMask>( mImpl->mOperationsPending & operationsRequired );
+
+ Vector<Character>& utf32Characters = mImpl->mLogicalModel->mText;
+
+ const Length numberOfCharacters = mImpl->mLogicalModel->GetNumberOfCharacters();
+
+ Vector<LineBreakInfo>& lineBreakInfo = mImpl->mLogicalModel->mLineBreakInfo;
+ 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( numberOfCharacters, TextAbstraction::LINE_NO_BREAK );
+
+ SetLineBreakInfo( utf32Characters,
+ lineBreakInfo );
+ }
+
+ Vector<WordBreakInfo>& wordBreakInfo = mImpl->mLogicalModel->mWordBreakInfo;
+ if( GET_WORD_BREAKS & operations )
+ {
+ // Retrieves the word break info. The word break info is used to layout the text (where to wrap the text in lines).
+ wordBreakInfo.Resize( numberOfCharacters, TextAbstraction::WORD_NO_BREAK );
+
+ SetWordBreakInfo( utf32Characters,
+ wordBreakInfo );
+ }
+
+ const bool getScripts = GET_SCRIPTS & operations;
+ const bool validateFonts = VALIDATE_FONTS & operations;
+
+ Vector<ScriptRun>& scripts = mImpl->mLogicalModel->mScriptRuns;
+ Vector<FontRun>& validFonts = mImpl->mLogicalModel->mFontRuns;
+
+ 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 );
+ }
+
+ if( validateFonts )
+ {
+ if( 0u == validFonts.Count() )
+ {
+ // Copy the requested font defaults received via the property system.
+ // These may not be valid i.e. may not contain glyphs for the necessary scripts.
+ GetDefaultFonts( validFonts, numberOfCharacters );
+ }
+
+ // 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,
+ validFonts );
+ }
+ }
+
+ Vector<Character> mirroredUtf32Characters;
+ bool textMirrored = false;
+ if( BIDI_INFO & operations )
+ {
+ // Count the number of LINE_NO_BREAK to reserve some space for the vector of paragraph's
+ // bidirectional info.
+
+ Length numberOfParagraphs = 0u;
+
+ const TextAbstraction::LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
+ for( Length index = 0u; index < numberOfCharacters; ++index )
+ {
+ if( TextAbstraction::LINE_NO_BREAK == *( lineBreakInfoBuffer + index ) )
+ {
+ ++numberOfParagraphs;
+ }
+ }
+
+ Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = mImpl->mLogicalModel->mBidirectionalParagraphInfo;
+ bidirectionalInfo.Reserve( numberOfParagraphs );
+
+ // Calculates the bidirectional info for the whole paragraph if it contains right to left scripts.
+ SetBidirectionalInfo( utf32Characters,
+ scripts,
+ lineBreakInfo,
+ bidirectionalInfo );
+
+ if( 0u != bidirectionalInfo.Count() )
+ {
+ // This paragraph has right to left text. Some characters may need to be mirrored.
+ // TODO: consider if the mirrored string can be stored as well.
+
+ textMirrored = GetMirroredText( utf32Characters, mirroredUtf32Characters );
+
+ // Only set the character directions if there is right to left characters.
+ Vector<CharacterDirection>& directions = mImpl->mLogicalModel->mCharacterDirections;
+ directions.Resize( numberOfCharacters );
+
+ GetCharactersDirection( bidirectionalInfo,
+ directions );
+ }
+ else
+ {
+ // There is no right to left characters. Clear the directions vector.
+ mImpl->mLogicalModel->mCharacterDirections.Clear();
+ }
+
+ }
+
+ Vector<GlyphInfo>& glyphs = mImpl->mVisualModel->mGlyphs;
+ Vector<CharacterIndex>& glyphsToCharactersMap = mImpl->mVisualModel->mGlyphsToCharacters;
+ Vector<Length>& charactersPerGlyph = mImpl->mVisualModel->mCharactersPerGlyph;
+ if( SHAPE_TEXT & operations )
+ {
+ const Vector<Character>& textToShape = textMirrored ? mirroredUtf32Characters : utf32Characters;
+ // Shapes the text.
+ ShapeText( textToShape,
+ lineBreakInfo,
+ scripts,
+ validFonts,
+ glyphs,
+ glyphsToCharactersMap,
+ charactersPerGlyph );
+
+ // Create the 'number of glyphs' per character and the glyph to character conversion tables.
+ mImpl->mVisualModel->CreateGlyphsPerCharacterTable( numberOfCharacters );
+ mImpl->mVisualModel->CreateCharacterToGlyphTable( numberOfCharacters );
+ }
+
+ const Length numberOfGlyphs = glyphs.Count();
+
+ if( GET_GLYPH_METRICS & operations )
+ {
+ mImpl->mFontClient.GetGlyphMetrics( glyphs.Begin(), numberOfGlyphs );
+ }
+}
+
+bool Controller::DoRelayout( const Size& size,
+ OperationsMask operationsRequired,
+ Size& layoutSize )
+{
+ bool viewUpdated( false );
+
+ // Calculate the operations to be done.
+ const OperationsMask operations = static_cast<OperationsMask>( mImpl->mOperationsPending & operationsRequired );
+
+ if( LAYOUT & operations )
+ {
+ // Some vectors with data needed to layout and reorder may be void
+ // after the first time the text has been laid out.
+ // Fill the vectors again.
+
+ Length numberOfGlyphs = mImpl->mVisualModel->GetNumberOfGlyphs();
+
+ if( 0u == numberOfGlyphs )
+ {
+ // Nothing else to do if there is no glyphs.
+ return true;
+ }
+
+ Vector<LineBreakInfo>& lineBreakInfo = mImpl->mLogicalModel->mLineBreakInfo;
+ Vector<WordBreakInfo>& wordBreakInfo = mImpl->mLogicalModel->mWordBreakInfo;
+ Vector<GlyphInfo>& glyphs = mImpl->mVisualModel->mGlyphs;
+ Vector<CharacterIndex>& glyphsToCharactersMap = mImpl->mVisualModel->mGlyphsToCharacters;
+ Vector<Length>& charactersPerGlyph = mImpl->mVisualModel->mCharactersPerGlyph;
+
+ // Set the layout parameters.
+ LayoutParameters layoutParameters( size,
+ mImpl->mLogicalModel->mText.Begin(),
+ lineBreakInfo.Begin(),
+ wordBreakInfo.Begin(),
+ numberOfGlyphs,
+ glyphs.Begin(),
+ glyphsToCharactersMap.Begin(),
+ charactersPerGlyph.Begin() );
+
+ // The laid-out lines.
+ // It's not possible to know in how many lines the text is going to be laid-out,
+ // but it can be resized at least with the number of 'paragraphs' to avoid
+ // some re-allocations.
+ Vector<LineRun>& lines = mImpl->mVisualModel->mLines;
+
+ // Delete any previous laid out lines before setting the new ones.
+ lines.Clear();
+
+ // The capacity of the bidirectional paragraph info is the number of paragraphs.
+ lines.Reserve( mImpl->mLogicalModel->mBidirectionalParagraphInfo.Capacity() );
+
+ // Resize the vector of positions to have the same size than the vector of glyphs.
+ Vector<Vector2>& glyphPositions = mImpl->mVisualModel->mGlyphPositions;
+ glyphPositions.Resize( numberOfGlyphs );
+
+ // Update the visual model.
+ viewUpdated = mImpl->mLayoutEngine.LayoutText( layoutParameters,
+ glyphPositions,
+ lines,
+ layoutSize );
+
+ if( viewUpdated )
+ {
+ // Reorder the lines
+ if( REORDER & operations )
+ {
+ Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = mImpl->mLogicalModel->mBidirectionalParagraphInfo;
+
+ // Check first if there are paragraphs with bidirectional info.
+ if( 0u != bidirectionalInfo.Count() )
+ {
+ // Get the lines
+ const Length numberOfLines = mImpl->mVisualModel->GetNumberOfLines();
+
+ // Reorder the lines.
+ Vector<BidirectionalLineInfoRun> lineBidirectionalInfoRuns;
+ lineBidirectionalInfoRuns.Reserve( numberOfLines ); // Reserve because is not known yet how many lines have right to left characters.
+ ReorderLines( bidirectionalInfo,
+ lines,
+ lineBidirectionalInfoRuns );
+
+ // Set the bidirectional info into the model.
+ const Length numberOfBidirectionalInfoRuns = lineBidirectionalInfoRuns.Count();
+ mImpl->mLogicalModel->SetVisualToLogicalMap( lineBidirectionalInfoRuns.Begin(),
+ numberOfBidirectionalInfoRuns );
+
+ // Set the bidirectional info per line into the layout parameters.
+ layoutParameters.lineBidirectionalInfoRunsBuffer = lineBidirectionalInfoRuns.Begin();
+ layoutParameters.numberOfBidirectionalInfoRuns = numberOfBidirectionalInfoRuns;
+
+ // Get the character to glyph conversion table and set into the layout.
+ layoutParameters.charactersToGlyphsBuffer = mImpl->mVisualModel->mCharactersToGlyph.Begin();
+
+ // Get the glyphs per character table and set into the layout.
+ layoutParameters.glyphsPerCharacterBuffer = mImpl->mVisualModel->mGlyphsPerCharacter.Begin();
+
+ // Re-layout the text. Reorder those lines with right to left characters.
+ mImpl->mLayoutEngine.ReLayoutRightToLeftLines( layoutParameters,
+ glyphPositions );
+
+ // Free the allocated memory used to store the conversion table in the bidirectional line info run.
+ for( Vector<BidirectionalLineInfoRun>::Iterator it = lineBidirectionalInfoRuns.Begin(),
+ endIt = lineBidirectionalInfoRuns.End();
+ it != endIt;
+ ++it )
+ {
+ BidirectionalLineInfoRun& bidiLineInfo = *it;
+
+ free( bidiLineInfo.visualToLogicalMap );
+ }
+ }
+ } // REORDER
+
+ if( ALIGN & operations )
+ {
+ mImpl->mLayoutEngine.Align( layoutParameters,
+ layoutSize,
+ lines,
+ glyphPositions );
+ }
+
+ // Sets the actual size.
+ if( UPDATE_ACTUAL_SIZE & operations )
+ {
+ mImpl->mVisualModel->SetActualSize( layoutSize );
+ }
+ } // view updated
+ }
+ else
+ {
+ layoutSize = mImpl->mVisualModel->GetActualSize();
+ }
+
+ return viewUpdated;
+}
+
+void Controller::CalculateTextAlignment( const Size& size )
+{
+ // Get the direction of the first character.
+ const CharacterDirection firstParagraphDirection = mImpl->mLogicalModel->GetCharacterDirection( 0u );
+
+ const Size& actualSize = mImpl->mVisualModel->GetActualSize();
+
+ // If the first paragraph is right to left swap ALIGN_BEGIN and ALIGN_END;
+ LayoutEngine::HorizontalAlignment horizontalAlignment = mImpl->mLayoutEngine.GetHorizontalAlignment();
+ if( firstParagraphDirection &&
+ ( LayoutEngine::HORIZONTAL_ALIGN_CENTER != horizontalAlignment ) )
+ {
+ if( LayoutEngine::HORIZONTAL_ALIGN_BEGIN == horizontalAlignment )
+ {
+ horizontalAlignment = LayoutEngine::HORIZONTAL_ALIGN_END;
+ }
+ else
+ {
+ horizontalAlignment = LayoutEngine::HORIZONTAL_ALIGN_BEGIN;
+ }
+ }
+
+ switch( horizontalAlignment )
+ {
+ case LayoutEngine::HORIZONTAL_ALIGN_BEGIN:
+ {
+ mImpl->mAlignmentOffset.x = 0.f;
+ break;
+ }
+ case LayoutEngine::HORIZONTAL_ALIGN_CENTER:
+ {
+ const int intOffset = static_cast<int>( 0.5f * ( size.width - actualSize.width ) ); // try to avoid pixel alignment.
+ mImpl->mAlignmentOffset.x = static_cast<float>( intOffset );
+ break;
+ }
+ case LayoutEngine::HORIZONTAL_ALIGN_END:
+ {
+ mImpl->mAlignmentOffset.x = size.width - actualSize.width;
+ break;
+ }
+ }
+
+ const LayoutEngine::VerticalAlignment verticalAlignment = mImpl->mLayoutEngine.GetVerticalAlignment();
+ switch( verticalAlignment )
+ {
+ case LayoutEngine::VERTICAL_ALIGN_TOP:
+ {
+ mImpl->mAlignmentOffset.y = 0.f;
+ break;
+ }
+ case LayoutEngine::VERTICAL_ALIGN_CENTER:
+ {
+ const int intOffset = static_cast<int>( 0.5f * ( size.height - actualSize.height ) ); // try to avoid pixel alignment.
+ mImpl->mAlignmentOffset.y = static_cast<float>( intOffset );
+ break;
+ }
+ case LayoutEngine::VERTICAL_ALIGN_BOTTOM:
+ {
+ mImpl->mAlignmentOffset.y = size.height - actualSize.height;
+ break;
+ }
+ }
+}
+
+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();
+ }
+}
+
+bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
+{
+ DALI_ASSERT_DEBUG( mImpl->mTextInput && "Unexpected KeyEvent" );
+
+ if( mImpl->mTextInput &&
+ keyEvent.state == KeyEvent::Down )
+ {
+ int keyCode = keyEvent.keyCode;
+ const std::string& keyString = keyEvent.keyPressed;
+
+ // Pre-process to separate modifying events from non-modifying input events.
+ if( Dali::DALI_KEY_ESCAPE == keyCode )
+ {
+ // Escape key is a special case which causes focus loss
+ KeyboardFocusLostEvent();
+ }
+ else if( Dali::DALI_KEY_CURSOR_LEFT == keyCode ||
+ Dali::DALI_KEY_CURSOR_RIGHT == keyCode ||
+ Dali::DALI_KEY_CURSOR_UP == keyCode ||
+ Dali::DALI_KEY_CURSOR_DOWN == keyCode )
+ {
+ TextInput::Event event( TextInput::CURSOR_KEY_EVENT );
+ event.p1.mInt = keyCode;
+ mImpl->mTextInput->mEventQueue.push_back( event );
+ }
+ else if( Dali::DALI_KEY_BACKSPACE == keyCode )
+ {
+ // Queue a delete event
+ ModifyEvent event;
+ event.type = DELETE_TEXT;
+ mImpl->mModifyEvents.push_back( event );
+ }
+ else if( !keyString.empty() )
+ {
+ // Queue an insert event
+ ModifyEvent event;
+ event.type = INSERT_TEXT;
+ event.text = keyString;
+ mImpl->mModifyEvents.push_back( event );
+ }
+
+ mImpl->mTextInput->ChangeState( TextInput::EDITING ); // todo Confirm this is the best place to change the state of
+
+ RequestRelayout();
+ }
+
+ return false;
+}
+
+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::PanEvent( Gesture::State state, const Vector2& displacement )
+{
+ DALI_ASSERT_DEBUG( mImpl->mTextInput && "Unexpected PanEvent" );
+
+ if( mImpl->mTextInput )
+ {
+ TextInput::Event event( TextInput::PAN_EVENT );
+ event.p1.mInt = state;
+ event.p2.mFloat = displacement.x;
+ event.p3.mFloat = displacement.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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <string>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/events/gesture.h>
+#include <dali/public-api/events/key-event.h>
+#include <dali/public-api/math/vector3.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/object/ref-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/decorator/text-decorator.h>
+#include <dali-toolkit/internal/text/font-run.h>
+#include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-view.h>
+
+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 = 0x0000,
+ CONVERT_TO_UTF32 = 0x0001,
+ GET_SCRIPTS = 0x0002,
+ VALIDATE_FONTS = 0x0004,
+ GET_LINE_BREAKS = 0x0008,
+ GET_WORD_BREAKS = 0x0010,
+ BIDI_INFO = 0x0020,
+ SHAPE_TEXT = 0x0040,
+ GET_GLYPH_METRICS = 0x0080,
+ LAYOUT = 0x0100,
+ UPDATE_ACTUAL_SIZE = 0x0200,
+ REORDER = 0x0400,
+ ALIGN = 0x0800,
+ ALL_OPERATIONS = 0xFFFF
+ };
+
+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 Retrieve any text previously set.
+ *
+ * @return A string of UTF-8 characters.
+ */
+ void GetText( std::string& text ) const;
+
+ /**
+ * @brief Replaces any placeholder text previously set.
+ *
+ * @param[in] text A string of UTF-8 characters.
+ */
+ void SetPlaceholderText( const std::string& text );
+
+ /**
+ * @brief Retrieve any placeholder text previously set.
+ *
+ * @return A string of UTF-8 characters.
+ */
+ void GetPlaceholderText( std::string& text ) const;
+
+ /**
+ * @brief Set the default font family.
+ *
+ * @param[in] defaultFontFamily The default font family.
+ */
+ void SetDefaultFontFamily( const std::string& defaultFontFamily );
+
+ /**
+ * @brief Retrieve the default font family.
+ *
+ * @return The default font family.
+ */
+ const std::string& GetDefaultFontFamily() const;
+
+ /**
+ * @brief Set the default font style.
+ *
+ * @param[in] defaultFontStyle The default font style.
+ */
+ void SetDefaultFontStyle( const std::string& defaultFontStyle );
+
+ /**
+ * @brief Retrieve the default font style.
+ *
+ * @return The default font style.
+ */
+ const std::string& GetDefaultFontStyle() const;
+
+ /**
+ * @brief Set the default point size.
+ *
+ * @param[in] defaultFontStyle The default point size.
+ */
+ void SetDefaultPointSize( float pointSize );
+
+ /**
+ * @brief Retrieve the default point size.
+ *
+ * @return The default point size.
+ */
+ float GetDefaultPointSize() const;
+
+ /**
+ * @brief Retrieve the default fonts.
+ *
+ * @param[out] fonts The default font family, style and point sizes.
+ * @param[in] numberOfCharacters The number of characters in the logical model.
+ */
+ void GetDefaultFonts( Dali::Vector<FontRun>& fonts, Length numberOfCharacters ) const;
+
+ /**
+ * @brief Set the text color
+ *
+ * @param textColor The text color
+ */
+ void SetTextColor( const Vector4& textColor );
+
+ /**
+ * @brief Retrieve the text color
+ *
+ * @return The text color
+ */
+ const Vector4& GetTextColor() const;
+
+ /**
+ * @brief Set the shadow offset.
+ *
+ * @param[in] shadowOffset The shadow offset, 0,0 indicates no shadow.
+ */
+ void SetShadowOffset( const Vector2& shadowOffset );
+
+ /**
+ * @brief Retrieve the shadow offset.
+ *
+ * @return The shadow offset.
+ */
+ const Vector2& GetShadowOffset() const;
+
+ /**
+ * @brief Set the shadow color.
+ *
+ * @param[in] shadowColor The shadow color.
+ */
+ void SetShadowColor( const Vector4& shadowColor );
+
+ /**
+ * @brief Retrieve the shadow color.
+ *
+ * @return The shadow color.
+ */
+ const Vector4& GetShadowColor() const;
+
+ /**
+ * @brief Set the underline color.
+ *
+ * @param[in] color color of underline.
+ */
+ void SetUnderlineColor( const Vector4& color );
+
+ /**
+ * @brief Retrieve the underline color.
+ *
+ * @return The underline color.
+ */
+ const Vector4& GetUnderlineColor() const;
+
+ /**
+ * @brief Set the underline enabled flag.
+ *
+ * @param[in] enabled The underline enabled flag.
+ */
+ void SetUnderlineEnabled( bool enabled );
+
+ /**
+ * @brief Returns whether the text is underlined or not.
+ *
+ * @return The underline state.
+ */
+ bool IsUnderlineEnabled() const;
+
+ /**
+ * @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 Called to enable/disable cursor blink.
+ *
+ * @note Only editable controls should calls this.
+ * @param[in] enabled Whether the cursor should blink or not.
+ */
+ void SetEnableCursorBlink( bool enable );
+
+ /**
+ * @brief Query whether cursor blink is enabled.
+ *
+ * @return Whether the cursor should blink or not.
+ */
+ bool GetEnableCursorBlink() const;
+
+ /**
+ * @brief Query the current scroll position; the UI control is responsible for moving actors to this position.
+ *
+ * @return The scroll position.
+ */
+ const Vector2& GetScrollPosition() const;
+
+ /**
+ * @brief Query the alignment offset.
+ *
+ * @return The alignmnet offset.
+ */
+ const Vector2& GetAlignmentOffset() const;
+
+ /**
+ * @copydoc Control::GetNaturalSize()
+ */
+ Vector3 GetNaturalSize();
+
+ /**
+ * @copydoc Control::GetHeightForWidth()
+ */
+ float GetHeightForWidth( float width );
+
+ /**
+ * @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 Size& size );
+
+ /**
+ * @brief Process queued events which modify the model.
+ */
+ void ProcessModifyEvents();
+
+ /**
+ * @brief Used to process an event queued from SetText()
+ *
+ * @param[in] newText The new text to store in the logical model.
+ */
+ void ReplaceTextEvent( const std::string& newText );
+
+ /**
+ * @brief Used to process an event queued from key events etc.
+ *
+ * @param[in] text The text to insert into the logical model.
+ */
+ void InsertTextEvent( const std::string& text );
+
+ /**
+ * @brief Used to process an event queued from backspace key etc.
+ */
+ void DeleteTextEvent();
+
+ /**
+ * @brief Update the model following text replace/insert etc.
+ *
+ * @param[in] operationsRequired The layout operations which need to be done.
+ */
+ void UpdateModel( OperationsMask operationsRequired );
+
+ /**
+ * @brief Lays-out the text.
+ *
+ * GetNaturalSize(), GetHeightForWidth() and Relayout() calls this method.
+ *
+ * @param[in] size A the size of a bounding box to layout text within.
+ * @param[in] operations The layout operations which need to be done.
+ * @param[out] layoutSize The size of the laid-out text.
+ */
+ bool DoRelayout( const Size& size,
+ OperationsMask operations,
+ Size& layoutSize );
+
+ /**
+ * @brief Calulates the alignment of the whole text inside the bounding box.
+ *
+ * @param[in] size The size of the bounding box.
+ */
+ void CalculateTextAlignment( const Size& size );
+
+ /**
+ * @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();
+
+ // Text-input Event Queuing
+
+ /**
+ * @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 key events are received.
+ *
+ * @param[in] event The key event.
+ */
+ bool KeyEvent( const Dali::KeyEvent& event );
+
+ /**
+ * @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 );
+
+ /**
+ * @brief Caller by editable UI controls when a pan gesture occurs.
+ *
+ * @param[in] state The state of the gesture.
+ * @param[in] displacement This distance panned since the last pan gesture.
+ */
+ void PanEvent( Gesture::State state, const Vector2& displacement );
+
+ /**
+ * @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 when the user does not specify a font
+ struct FontDefaults;
+
+ // 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 TextAbstraction::CharacterDirection CharacterDirection; ///< The character's direction: @e false is left to right, @e true is right to left.
+
+typedef uint32_t GlyphIndex; ///< An index into an array of glyphs.
+typedef uint32_t ScriptRunIndex; ///< An index into an array of script runs.
+typedef uint32_t FontRunIndex; ///< An index into an array of font runs.
+typedef uint32_t BidirectionalRunIndex; ///< An index into an array of font runs.
+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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/text/text-io.h>
+
+// EXTERNAL INCLUDES
+#include <iostream>
+#include <dali/public-api/text-abstraction/font-client.h>
+#include <dali/public-api/text-abstraction/script.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+std::ostream& operator<< (std::ostream& o, const Vector<Character>& text)
+{
+ o << std::hex;
+
+ for( unsigned int i=0; i<text.Count(); ++i )
+ {
+ o << text[i];
+ if( i+1 < text.Count() )
+ {
+ o << " ";
+ }
+ }
+
+ return o << std::dec;
+}
+
+std::ostream& operator<< (std::ostream& o, const Vector<ScriptRun>& scriptRun)
+{
+ for( unsigned int i=0; i<scriptRun.Count(); ++i )
+ {
+ // e.g. Print "0->9: LATIN" for a ten character run staring from beginning of the model
+ o << scriptRun[i].characterRun.characterIndex << "->" << (scriptRun[i].characterRun.characterIndex + scriptRun[i].characterRun.numberOfCharacters ) << ": ";
+ o << TextAbstraction::ScriptName[scriptRun[i].script];
+
+ if( i+1 < scriptRun.Count() )
+ {
+ o << ", ";
+ }
+ }
+
+ return o << std::dec;
+}
+
+std::ostream& operator<< (std::ostream& o, const Vector<FontRun>& fontRun)
+{
+ TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+
+ for( unsigned int i=0; i<fontRun.Count(); ++i )
+ {
+ // e.g. Print "0->9: ID:1 TizenSansKorean style:Regular size:10.0" for a ten character run staring from beginning of the model
+ o << fontRun[i].characterRun.characterIndex << "->" << (fontRun[i].characterRun.characterIndex + fontRun[i].characterRun.numberOfCharacters ) << ": ";
+
+ FontId id = fontRun[i].fontId;
+ TextAbstraction::FontDescription fontDescription;
+ fontClient.GetDescription( id, fontDescription );
+ o << "ID:" << id << ", " << fontDescription.family << " style:" << fontDescription.style << " size:" << (fontClient.GetPointSize(id) / 64);
+
+ if( i+1 < fontRun.Count() )
+ {
+ o << ", ";
+ }
+ }
+
+ return o << std::dec;
+}
+
+std::ostream& operator<< (std::ostream& o, const Vector<LineRun>& lineRuns)
+{
+ for( unsigned int i=0; i<lineRuns.Count(); ++i )
+ {
+ // e.g. Print "Line 0 Glyphs: 0->9 Characters: 0->9 (10)" for a ten character run staring from beginning of the model
+ o << "Line " << i << " Glyphs: " << lineRuns[i].glyphIndex << "->" << (lineRuns[i].glyphIndex + lineRuns[i].numberOfGlyphs );
+ o << " Characters: " << lineRuns[i].characterRun.characterIndex << "->" << (lineRuns[i].characterRun.characterIndex + lineRuns[i].characterRun.numberOfCharacters );
+ o << " Width: " << lineRuns[i].width;
+ o << " Ascender: " << lineRuns[i].ascender;
+ o << " Descender: " << lineRuns[i].descender;
+
+ if( i+1 < lineRuns.Count() )
+ {
+ o << ", ";
+ }
+ }
+
+ return o << std::dec;
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TEXT_ABSTRACTION_TEXT_IO_H__
+#define __DALI_TEXT_ABSTRACTION_TEXT_IO_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 <iosfwd>
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/font-run.h>
+#include <dali-toolkit/internal/text/line-run.h>
+#include <dali-toolkit/internal/text/script-run.h>
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Print a vector of characters.
+ *
+ * @param [in] o The output stream operator.
+ * @param [in] text The text to print.
+ * @return The output stream operator.
+ */
+std::ostream& operator<< (std::ostream& o, const Vector<Character>& text);
+
+/**
+ * @brief Print a vector of script runs.
+ *
+ * @param [in] o The output stream operator.
+ * @param [in] scriptRuns The script runs to print.
+ * @return The output stream operator.
+ */
+std::ostream& operator<< (std::ostream& o, const Vector<ScriptRun>& scriptRuns);
+
+/**
+ * @brief Print a vector of font runs.
+ *
+ * @param [in] o The output stream operator.
+ * @param [in] fontRuns The font runs to print.
+ * @return The output stream operator.
+ */
+std::ostream& operator<< (std::ostream& o, const Vector<FontRun>& fontRuns);
+
+/**
+ * @brief Print a vector of line runs.
+ *
+ * @param [in] o The output stream operator.
+ * @param [in] lineRuns The line runs to print.
+ * @return The output stream operator.
+ */
+std::ostream& operator<< (std::ostream& o, const Vector<LineRun>& lineRuns);
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TEXT_ABSTRACTION_TEXT_IO_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/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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/vector4.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/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;
+
+ /**
+ * @brief Retrieves the text color
+ *
+ * @return The text color
+ */
+ virtual const Vector4& GetTextColor() const = 0;
+
+ /**
+ * @brief Retrieves the shadow offset, 0 indicates no shadow.
+ *
+ * @return The shadow offset.
+ */
+ virtual const Vector2& GetShadowOffset() const = 0;
+
+ /**
+ * @brief Retrieves the shadow color.
+ *
+ * @return The shadow color.
+ */
+ virtual const Vector4& GetShadowColor() const = 0;
+
+ /**
+ * @brief Retrieves the underline color.
+ *
+ * @return The underline color.
+ */
+ virtual const Vector4& GetUnderlineColor() const = 0;
+
+ /**
+ * @brief Returns whether is underline is enabled or not.
+ *
+ * @return The underline state.
+ */
+ virtual bool IsUnderlineEnabled() 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/internal/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;
+}
+
+const Vector4& View::GetTextColor() const
+{
+ if ( mImpl->mVisualModel )
+ {
+ VisualModel& model = *mImpl->mVisualModel;
+ return model.GetTextColor();
+ }
+ return Vector4::ZERO;
+}
+
+const Vector2& View::GetShadowOffset() const
+{
+ if ( mImpl->mVisualModel )
+ {
+ VisualModel& model = *mImpl->mVisualModel;
+ return model.GetShadowOffset();
+ }
+ return Vector2::ZERO;
+}
+
+const Vector4& View::GetShadowColor() const
+{
+ if ( mImpl->mVisualModel )
+ {
+ VisualModel& model = *mImpl->mVisualModel;
+ return model.GetShadowColor();
+ }
+ return Vector4::ZERO;
+}
+
+const Vector4& View::GetUnderlineColor() const
+{
+ if ( mImpl->mVisualModel )
+ {
+ VisualModel& model = *mImpl->mVisualModel;
+ return model.GetUnderlineColor();
+ }
+ return Vector4::ZERO;
+}
+
+bool View::IsUnderlineEnabled() const
+{
+ if ( mImpl->mVisualModel )
+ {
+ VisualModel& model = *mImpl->mVisualModel;
+ return model.IsUnderlineEnabled();
+ }
+ return false;
+}
+
+Length View::GetNumberOfGlyphs() const
+{
+ if( mImpl->mVisualModel )
+ {
+ VisualModel& model = *mImpl->mVisualModel;
+
+ Length glyphCount = model.GetNumberOfGlyphs();
+ Length positionCount = model.GetNumberOfGlyphPositions();
+
+ DALI_ASSERT_DEBUG( positionCount <= glyphCount && "Invalid glyph positions in Model" );
+
+ return (positionCount < glyphCount) ? positionCount : glyphCount;
+ }
+
+ 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/internal/text/text-view-interface.h>
+#include <dali-toolkit/internal/text/visual-model-impl.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;
+
+ /**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::GetTextColor()
+ */
+ virtual const Vector4& GetTextColor() const;
+
+ /**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::GetShadowOffset()
+ */
+ virtual const Vector2& GetShadowOffset() const;
+
+ /**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::GetShadowColor()
+ */
+ virtual const Vector4& GetShadowColor() const;
+
+ /**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::GetUnderlineColor()
+ */
+ virtual const Vector4& GetUnderlineColor() const;
+
+ /**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::IsUnderlineEnabled()
+ */
+ virtual bool IsUnderlineEnabled() 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/internal/text/visual-model-impl.h>
+
+// EXTERNAL INCLUDES
+#include <memory.h>
+#include <dali/public-api/math/vector2.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+VisualModelPtr VisualModel::New()
+{
+ return VisualModelPtr( new VisualModel() );
+}
+
+void VisualModel::SetGlyphs( const GlyphInfo* glyphs,
+ const CharacterIndex* characterIndices,
+ const Length* charactersPerGlyph,
+ Length numberOfGlyphs )
+{
+ if( 0u == numberOfGlyphs )
+ {
+ mGlyphs.Clear();
+ mGlyphsToCharacters.Clear();
+ mCharactersToGlyph.Clear();
+ mCharactersPerGlyph.Clear();
+ mGlyphsPerCharacter.Clear();
+ }
+ else
+ {
+ if( NULL != glyphs )
+ {
+ mGlyphs.Resize( numberOfGlyphs );
+ memcpy( mGlyphs.Begin(), glyphs, numberOfGlyphs * sizeof( GlyphInfo ) );
+ }
+
+ if( NULL != characterIndices )
+ {
+ mGlyphsToCharacters.Resize( numberOfGlyphs );
+ memcpy( mGlyphsToCharacters.Begin(), characterIndices, numberOfGlyphs * sizeof( CharacterIndex ) );
+ }
+
+ if( NULL != charactersPerGlyph )
+ {
+ mCharactersPerGlyph.Resize( numberOfGlyphs );
+ memcpy( mCharactersPerGlyph.Begin(), charactersPerGlyph, numberOfGlyphs * sizeof( Length ) );
+
+ // Build the glyphs per character table.
+ CreateGlyphsPerCharacterTable();
+
+ // Build the characters to glyph conversion table.
+ CreateCharacterToGlyphTable();
+ }
+ }
+}
+
+void VisualModel::CreateCharacterToGlyphTable( Length numberOfCharacters )
+{
+ // 1) Reserve some space for the characters to avoid reallocations.
+ if( 0u == numberOfCharacters )
+ {
+ // If no number of characters is given, just set something sensible to avoid reallocations.
+ numberOfCharacters = static_cast<Length> ( static_cast<float>( mGlyphs.Count() ) * 1.3f );
+ }
+ mCharactersToGlyph.Reserve( numberOfCharacters );
+
+ DALI_ASSERT_DEBUG( mGlyphsPerCharacter.Count() != 0u ||
+ ( 0u == numberOfCharacters ) );
+
+ const Length* const glyphsPerCharacterBuffer = mGlyphsPerCharacter.Begin();
+
+ // 2) Traverse the glyphs and set the glyph indices per character.
+
+ // Index to the glyph.
+ GlyphIndex glyphIndex = 0u;
+ CharacterIndex characterIndex = 0u;
+ for( Vector<Length>::ConstIterator it = mCharactersPerGlyph.Begin(),
+ endIt = mCharactersPerGlyph.End();
+ it != endIt;
+ ++it )
+ {
+ const Length numberOfCharactersPerGlyph = *it;
+
+ Length numberOfGlyphs = 0u;
+ // Set the glyph indices.
+ for( Length index = 0u; index < numberOfCharactersPerGlyph; ++index, ++characterIndex )
+ {
+ mCharactersToGlyph.PushBack( glyphIndex );
+ numberOfGlyphs += *( glyphsPerCharacterBuffer + characterIndex );
+ }
+ glyphIndex += numberOfGlyphs;
+ }
+}
+
+void VisualModel::CreateGlyphsPerCharacterTable( Length numberOfCharacters )
+{
+ // 1) Reserve some space for the characters to avoid reallocations.
+ if( 0u == numberOfCharacters )
+ {
+ // If no number of characters is given, just set something sensible to avoid reallocations.
+ numberOfCharacters = static_cast<Length> ( static_cast<float>( mGlyphs.Count() ) * 1.3f );
+ }
+ mGlyphsPerCharacter.Reserve( numberOfCharacters );
+
+ // 2) Traverse the glyphs and set the number of glyphs per character.
+
+ // The number of 'characters per glyph' equal to zero.
+ Length zeroCharactersPerGlyph = 0u;
+
+ for( Vector<Length>::ConstIterator it = mCharactersPerGlyph.Begin(),
+ endIt = mCharactersPerGlyph.End();
+ it != endIt;
+ ++it )
+ {
+ const Length numberOfCharactersPerGlyph = *it;
+
+ // Set the glyphs per character.
+ if( 0u == numberOfCharactersPerGlyph )
+ {
+ ++zeroCharactersPerGlyph;
+ }
+ else
+ {
+ const Length numberOfZeroGlyphsPerCharacter = ( numberOfCharactersPerGlyph - 1u );
+ for( Length zeroIndex = 0u; zeroIndex < numberOfZeroGlyphsPerCharacter ; ++zeroIndex )
+ {
+ mGlyphsPerCharacter.PushBack( 0u );
+ }
+
+ mGlyphsPerCharacter.PushBack( 1u + zeroCharactersPerGlyph );
+
+ zeroCharactersPerGlyph = 0u;
+ }
+ }
+}
+
+Length VisualModel::GetNumberOfGlyphs() const
+{
+ return mGlyphs.Count();
+}
+
+void VisualModel::GetGlyphs( GlyphInfo* glyphs,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+ memcpy( glyphs, mGlyphs.Begin() + glyphIndex, numberOfGlyphs * sizeof( GlyphInfo ) );
+}
+
+const GlyphInfo& VisualModel::GetGlyphInfo( GlyphIndex glyphIndex ) const
+{
+ return mGlyphs[glyphIndex];
+}
+
+void VisualModel::ReplaceGlyphs( GlyphIndex glyphIndex,
+ Length numberOfGlyphsToRemove,
+ const GlyphInfo* const glyphs,
+ const Length* const numberOfCharacters,
+ Length numberOfGlyphsToInsert )
+{
+}
+
+CharacterIndex VisualModel::GetCharacterIndex( GlyphIndex glyphIndex ) const
+{
+ return mGlyphsToCharacters[glyphIndex];
+}
+
+Length VisualModel::GetCharactersPerGlyph( GlyphIndex glyphIndex ) const
+{
+ return mCharactersPerGlyph[glyphIndex];
+}
+
+GlyphIndex VisualModel::GetGlyphIndex( CharacterIndex characterIndex ) const
+{
+ return mCharactersToGlyph[characterIndex];
+}
+
+void VisualModel::GetCharacterToGlyphMap( GlyphIndex* characterToGlyphMap,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ memcpy( characterToGlyphMap, mCharactersToGlyph.Begin() + characterIndex, numberOfCharacters * sizeof( GlyphIndex ) );
+}
+
+void VisualModel::GetGlyphToCharacterMap( CharacterIndex* glyphToCharacter,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+ memcpy( glyphToCharacter, mGlyphsToCharacters.Begin() + glyphIndex, numberOfGlyphs * sizeof( CharacterIndex ) );
+}
+
+void VisualModel::GetCharactersPerGlyphMap( Length* charactersPerGlyph,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+ memcpy( charactersPerGlyph, mCharactersPerGlyph.Begin() + glyphIndex, numberOfGlyphs * sizeof( Length ) );
+}
+
+void VisualModel::GetGlyphsPerCharacterMap( Length* glyphsPerCharacter,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ memcpy( glyphsPerCharacter, mGlyphsPerCharacter.Begin() + characterIndex, numberOfCharacters * sizeof( Length ) );
+}
+
+void VisualModel::SetGlyphPositions( const Vector2* glyphPositions,
+ Length numberOfGlyphs )
+{
+ if( 0u == numberOfGlyphs )
+ {
+ mGlyphPositions.Clear();
+ }
+ else
+ {
+ mGlyphPositions.Resize( numberOfGlyphs );
+ memcpy( mGlyphPositions.Begin(), glyphPositions, numberOfGlyphs * sizeof( Vector2 ) );
+ }
+}
+
+Length VisualModel::GetNumberOfGlyphPositions() const
+{
+ return mGlyphPositions.Count();
+}
+
+void VisualModel::GetGlyphPositions( Vector2* glyphPositions,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+ memcpy( glyphPositions, mGlyphPositions.Begin() + glyphIndex, numberOfGlyphs * sizeof( Vector2 ) );
+}
+
+const Vector2& VisualModel::GetGlyphPosition( GlyphIndex glyphIndex ) const
+{
+ return *( mGlyphPositions.Begin() + glyphIndex );
+}
+
+void VisualModel::ReplaceGlyphPositions( GlyphIndex glyphIndex,
+ Length numberOfGlyphsToRemove,
+ const Vector2* const positions,
+ Length numberOfGlyphsToInsert )
+{
+}
+
+void VisualModel::SetLines( const LineRun* const lines,
+ Length numberOfLines )
+{
+ if( 0u == numberOfLines )
+ {
+ mLines.Clear();
+ }
+ else
+ {
+ mLines.Resize( numberOfLines );
+ memcpy( mLines.Begin(), lines, numberOfLines * sizeof( LineRun ) );
+ }
+}
+
+Length VisualModel::GetNumberOfLines() const
+{
+ return mLines.Count();
+}
+
+void VisualModel::GetLines( LineRun* lines,
+ LineIndex lineIndex,
+ Length numberOfLines ) const
+{
+ memcpy( lines, mLines.Begin() + lineIndex, numberOfLines * sizeof( LineRun ) );
+}
+
+void VisualModel::GetNumberOfLines( GlyphIndex glyphIndex,
+ Length numberOfGlyphs,
+ LineIndex& firstLine,
+ Length& numberOfLines ) const
+{
+ // Initialize the number of lines and the first line.
+ firstLine = 0u;
+ numberOfLines = 0u;
+ bool firstLineFound = false;
+
+ const GlyphIndex lastGlyphIndex = glyphIndex + numberOfGlyphs;
+
+ // Traverse the lines and count those lines within the range of glyphs.
+ for( Vector<LineRun>::ConstIterator it = mLines.Begin(),
+ endIt = mLines.End();
+ it != endIt;
+ ++it )
+ {
+ const LineRun& line = *it;
+
+ if( ( line.glyphIndex + line.numberOfGlyphs > glyphIndex ) &&
+ ( lastGlyphIndex > line.glyphIndex ) )
+ {
+ firstLineFound = true;
+ ++numberOfLines;
+ }
+ else if( lastGlyphIndex <= line.glyphIndex )
+ {
+ // nothing else to do.
+ break;
+ }
+
+ if( !firstLineFound )
+ {
+ ++firstLine;
+ }
+ }
+}
+
+void VisualModel::GetLinesOfGlyphRange( LineRun* lines,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+ LineIndex firstLine = 0u;
+ Length numberOfLines = 0u;
+
+ GetNumberOfLines( glyphIndex,
+ numberOfGlyphs,
+ firstLine,
+ numberOfLines );
+
+ memcpy( lines, mLines.Begin() + firstLine, numberOfLines * sizeof( LineRun ) );
+}
+
+LineIndex VisualModel::GetLineOfGlyph( GlyphIndex glyphIndex )
+{
+ const CharacterIndex characterIndex = *( mGlyphsToCharacters.Begin() + glyphIndex );
+
+ return GetLineOfCharacter( characterIndex );
+}
+
+LineIndex VisualModel::GetLineOfCharacter( CharacterIndex characterIndex )
+{
+ // 1) Check first in the cached line.
+
+ const LineRun& lineRun = *( mLines.Begin() + mCachedLineIndex );
+
+ if( ( lineRun.characterRun.characterIndex <= characterIndex ) &&
+ ( characterIndex < lineRun.characterRun.characterIndex + lineRun.characterRun.numberOfCharacters ) )
+ {
+ return mCachedLineIndex;
+ }
+
+ // 2) Is not in the cached line. Check in the other lines.
+
+ LineIndex index = characterIndex < lineRun.characterRun.characterIndex ? 0u : mCachedLineIndex + 1u;
+
+ for( Vector<LineRun>::ConstIterator it = mLines.Begin() + index,
+ endIt = mLines.End();
+ it != endIt;
+ ++it, ++index )
+ {
+ const LineRun& lineRun = *it;
+
+ if( characterIndex < lineRun.characterRun.characterIndex + lineRun.characterRun.numberOfCharacters )
+ {
+ mCachedLineIndex = index;
+ break;
+ }
+ }
+
+ return index;
+}
+
+void VisualModel::ReplaceLines( GlyphIndex glyphIndex,
+ Length numberOfGlyphsToRemove,
+ const LineRun* const lines,
+ Length numberOfGlyphsToInsert )
+{
+}
+
+void VisualModel::SetNaturalSize( const Vector2& size )
+{
+ mNaturalSize = size;
+}
+
+const Vector2& VisualModel::GetNaturalSize() const
+{
+ return mNaturalSize;
+}
+
+void VisualModel::SetActualSize( const Vector2& size )
+{
+ mActualSize = size;
+}
+
+const Vector2& VisualModel::GetActualSize() const
+{
+ return mActualSize;
+}
+
+void VisualModel::SetTextColor( const Vector4& textColor )
+{
+ mTextColor = textColor;
+
+ if ( !mUnderlineColorSet )
+ {
+ mUnderlineColor = textColor;
+ }
+}
+
+void VisualModel::SetShadowOffset( const Vector2& shadowOffset )
+{
+ mShadowOffset = shadowOffset;
+}
+
+void VisualModel::SetShadowColor( const Vector4& shadowColor )
+{
+ mShadowColor = shadowColor;
+}
+
+void VisualModel::SetUnderlineColor( const Vector4& color )
+{
+ mUnderlineColor = color;
+ mUnderlineColorSet = true;
+}
+
+void VisualModel::SetUnderlineEnabled( bool enabled )
+{
+ mUnderlineEnabled = enabled;
+}
+
+const Vector4& VisualModel::GetTextColor() const
+{
+ return mTextColor;
+}
+
+const Vector2& VisualModel::GetShadowOffset() const
+{
+ return mShadowOffset;
+}
+
+const Vector4& VisualModel::GetShadowColor() const
+{
+ return mShadowColor;
+}
+
+const Vector4& VisualModel::GetUnderlineColor() const
+{
+ return mUnderlineColor;
+}
+
+bool VisualModel::IsUnderlineEnabled() const
+{
+ return mUnderlineEnabled;
+}
+
+void VisualModel::ClearCaches()
+{
+ mCachedLineIndex = 0u;
+}
+
+VisualModel::~VisualModel()
+{
+}
+
+VisualModel::VisualModel()
+: mGlyphs(),
+ mGlyphsToCharacters(),
+ mCharactersToGlyph(),
+ mCharactersPerGlyph(),
+ mGlyphsPerCharacter(),
+ mGlyphPositions(),
+ mLines(),
+ mTextColor(),
+ mShadowColor(),
+ mUnderlineColor(),
+ mShadowOffset(),
+ mNaturalSize(),
+ mActualSize(),
+ mCachedLineIndex( 0u ),
+ mUnderlineEnabled( false ),
+ mUnderlineColorSet( false )
+{
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_VISUAL_MODEL_IMPL_H__
+#define __DALI_TOOLKIT_TEXT_VISUAL_MODEL_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/math/vector4.h>
+#include <dali/public-api/object/ref-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/line-run.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.
+ *
+ * @note If the number of glyphs is zero, all buffers are cleared.
+ * @note If one pointer is NULL and the number of glyphs is not zero, the buffer is not touched.
+ *
+ * @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 );
+
+ /**
+ * @brief Creates the character to glyph conversion table.
+ *
+ * @pre The glyphs per character table needs to be created first.
+ *
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void CreateCharacterToGlyphTable( Length numberOfCharacters = 0u );
+
+ /**
+ * @brief Creates an array containing the number of glyphs per character.
+ *
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void CreateGlyphsPerCharacterTable( Length numberOfCharacters = 0u );
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief Retrieves a glyph.
+ *
+ * @param[in] glyphIndex Index to a glyph.
+ *
+ * @return A glyph.
+ */
+ const GlyphInfo& GetGlyphInfo( GlyphIndex glyphIndex ) const;
+
+ /**
+ * @brief Replaces glyphs.
+ *
+ * If the @p numberOfGlyphsToRemove is zero, this operation is like an insert.
+ * If the @p numberOfGlyphsToInsert is zero, this operation is like a remove.
+ *
+ * @param[in] glyphIndex Where to replace the glyphs.
+ * @param[in] numberOfGlyphsToRemove The number of glyphs to be removed.
+ * @param[in] glyphs Pointer to a buffer with the new glyphs.
+ * @param[in] numberOfCharacters Pointer to a buffer with the number of characters per glyph.
+ * @param[in] numberOfGlyphsToInsert The number of new glyphs in the buffer.
+ */
+ void ReplaceGlyphs( GlyphIndex glyphIndex,
+ Length numberOfGlyphsToRemove,
+ const GlyphInfo* const glyphs,
+ const Length* const numberOfCharacters,
+ Length numberOfGlyphsToInsert );
+
+ // 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;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief Retrieves for each character the number of glyphs the character is shaped.
+ *
+ * @param[out] glyphsPerCharacter Pointer to a buffer where the number of glyphs for each character are copied.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void GetGlyphsPerCharacterMap( Length* glyphsPerCharacter,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ // Position interface
+
+ /**
+ * @brief Replaces any glyph positions previously set.
+ *
+ * @note If the number of glyphs is zero the position buffer is cleared.
+ *
+ * @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 number of glyph positions set.
+ *
+ * @note This may be less than the number of glyphs in the model.
+ * @return The number of glyphs.
+ */
+ Length GetNumberOfGlyphPositions() const;
+
+ /**
+ * @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;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief Replaces glyph's positions.
+ *
+ * If the @p numberOfGlyphsToRemove is zero, this operation is like an insert.
+ * If the @p numberOfGlyphsToInsert is zero, this operation is like a remove.
+ *
+ * @param[in] glyphIndex Where to replace the glyph's positions.
+ * @param[in] numberOfGlyphsToRemove The number of glyph's positions to be removed.
+ * @param[in] positions Pointer to a buffer with the new glyph's positions.
+ * @param[in] numberOfGlyphsToInsert The number of new glyph's positions in the buffer.
+ */
+ void ReplaceGlyphPositions( GlyphIndex glyphIndex,
+ Length numberOfGlyphsToRemove,
+ const Vector2* const positions,
+ Length numberOfGlyphsToInsert );
+
+ // Line interface.
+
+ /**
+ * @brief 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.
+ *
+ * @note If the number of lines is zero or the pointer is NULL, the lines buffer is cleared.
+ *
+ * @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 );
+
+ /**
+ * @brief Retrieves the number of lines of the whole text.
+ *
+ * @return The number of lines.
+ */
+ Length GetNumberOfLines() const;
+
+ /**
+ * @brief 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;
+
+ /**
+ * @brief Retrieves the number of lines and the index to the first line where the given range of glyphs is laid out.
+ *
+ * @param[in] glyphIndex Index to the first glyph.
+ * @param[in] numberOfGlyphs The number of glyph.
+ * @param[out] firstLine Index to the line containing the glyph index.
+ * @param[out] numberOfLines The number of lines.
+ */
+ void GetNumberOfLines( GlyphIndex glyphIndex,
+ Length numberOfGlyphs,
+ LineIndex& firstLine,
+ Length& numberOfLines ) const;
+ /**
+ * @brief 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;
+
+ /**
+ * @brief Retrieves the line index where the glyph is laid-out.
+ *
+ * @param[in] glyphIndex The glyph's index.
+ *
+ * @return The line index.
+ */
+ LineIndex GetLineOfGlyph( GlyphIndex glyphIndex );
+
+ /**
+ * @brief Retrieves the line index where the character is laid-out.
+ *
+ * @param[in] characterIndex The character's index.
+ *
+ * @return The line index.
+ */
+ LineIndex GetLineOfCharacter( CharacterIndex characterIndex );
+
+ /**
+ * @brief Replaces lines for the given range of glyphs.
+ *
+ * If the @p numberOfGlyphsToRemove is zero, this operation is like an insert.
+ * If the @p numberOfGlyphsToInsert is zero, this operation is like a remove.
+ *
+ * @param[in] glyphIndex Index of the first glyph where to replace the line info.
+ * @param[in] numberOfGlyphsToRemove The number of glyphs to be the line info removed.
+ * @param[in] lines Pointer to a buffer with the lines.
+ * @param[in] numberOfGlyphsToInsert The number of characters to be the line info inserted.
+ */
+ void ReplaceLines( GlyphIndex glyphIndex,
+ Length numberOfGlyphsToRemove,
+ const LineRun* const lines,
+ Length numberOfGlyphsToInsert );
+
+ // Size interface
+
+ /**
+ * @brief Sets the natural size.
+ *
+ * @param[in] size The text's natural size.
+ */
+ void SetNaturalSize( const Vector2& size );
+
+ /**
+ * @brief Retrieves the natural size.
+ *
+ * @return The text's natural size.
+ */
+ const Vector2& GetNaturalSize() const;
+
+ /**
+ * @brief Sets the text's actual size after it has been laid out.
+ *
+ * @param[in] size The text's size.
+ */
+ void SetActualSize( const Vector2& size );
+
+ /**
+ * @brief Retrieves the text's actual size after it has been laid out.
+ *
+ * @return The text's size.
+ */
+ const Vector2& GetActualSize() const;
+
+ /**
+ * @brief Set the text's color
+ *
+ * @param[in] textColor The text's color
+ */
+ void SetTextColor( const Vector4& textColor );
+
+ /**
+ * @brief Retrieve the text's color
+ *
+ * @return The text's color
+ */
+ const Vector4& GetTextColor() const;
+
+ /**
+ * @brief Sets the text's shadow offset.
+ *
+ * @param[in] shadowOffset The shadow offset, 0,0 indicates no shadow.
+ */
+ void SetShadowOffset( const Vector2& shadowOffset );
+
+ /**
+ * @brief Retrieves the text's shadow offset.
+ *
+ * @return The text's shadow offset, 0,0 indicates no shadow.
+ */
+ const Vector2& GetShadowOffset() const;
+
+ /**
+ * @brief Sets the text's shadow color.
+ *
+ * @param[in] shadowColor The shadow color.
+ */
+ void SetShadowColor( const Vector4& shadowColor );
+
+ /**
+ * @brief Retrieves the text's shadow color.
+ *
+ * @return The text's shadow color.
+ */
+ const Vector4& GetShadowColor() const;
+
+ /**
+ * @brief Sets the text's underline color.
+ *
+ * @param[in] color The text's underline color.
+ */
+ void SetUnderlineColor( const Vector4& color );
+
+ /**
+ * @brief Retrieves the text's underline color.
+ *
+ * @return The text's underline color.
+ */
+ const Vector4& GetUnderlineColor() const;
+
+ /**
+ * @brief Sets the text underline flag.
+ *
+ * @param[in] enabled true if underlined.
+ */
+ void SetUnderlineEnabled( bool enabled );
+
+ /**
+ * @brief Returns whether the text is underlined or not.
+ *
+ * @return underline state.
+ */
+ bool IsUnderlineEnabled() const;
+
+ /**
+ * @brief Clear the caches.
+ */
+ void ClearCaches();
+
+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 );
+
+public:
+
+ Vector<GlyphInfo> mGlyphs; ///< For each glyph, the font's id, glyph's index within the font and glyph's metrics.
+ Vector<CharacterIndex> mGlyphsToCharacters; ///< For each glyph, the index of the first character.
+ Vector<GlyphIndex> mCharactersToGlyph; ///< For each character, the index of the first glyph.
+ Vector<Length> mCharactersPerGlyph; ///< For each glyph, the number of characters that form the glyph.
+ Vector<Length> mGlyphsPerCharacter; ///< For each character, the number of glyphs that are shaped.
+ Vector<Vector2> mGlyphPositions; ///< For each glyph, the position.
+ Vector<LineRun> mLines; ///< The laid out lines.
+
+ Vector4 mTextColor; ///< The text color
+ Vector4 mShadowColor; ///< Color of drop shadow
+ Vector4 mUnderlineColor; ///< Color of underline
+ Vector2 mShadowOffset; ///< Offset for drop shadow, 0 indicates no shadow
+
+private:
+
+ Size mNaturalSize; ///< Size of the text with no line wrapping.
+ Size mActualSize; ///< Size of the laid-out text considering the layout properties set.
+
+ // Caches to increase performance in some consecutive operations.
+ LineIndex mCachedLineIndex; ///< Used to increase performance in consecutive calls to GetLineOfGlyph() or GetLineOfCharacter() with consecutive glyphs or characters.
+
+public:
+ bool mUnderlineEnabled:1; ///< Underline enabled flag
+ bool mUnderlineColorSet:1; ///< Has the underline color been explicitly set?
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_VISUAL_MODEL_IMPL_H__
void SetButtonImage( Image image );
/**
- * @copydoc SetButtonImage( Image image )
+ * @brief SetButtonImage
+ *
+ * @param[in] image The Actor to be used as the button image.
+ *
+ * The natural size of the button would be the size of this Actor
+ * if it's larger than the background and label
*/
void SetButtonImage( Actor image );
void SetBackgroundImage( Image image );
/**
- * @copydoc SetBackgroundImage( Image image )
+ * @brief SetBackgroundImage
+ *
+ * @param[in] image The Actor to be used as the background image.
+ *
+ * The natural size of the button would be the size of this Actor
+ * if it's larger than the button and label
*/
void SetBackgroundImage( Actor image );
#include <stack>
#include <dali/public-api/actors/image-actor.h>
#include <dali/public-api/actors/mesh-actor.h>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/geometry/mesh.h>
actor.SetZ( BACKGROUND_ACTOR_Z_POSITION );
actor.SetRelayoutEnabled( false );
- Constraint constraint = Constraint::New<Vector3>( constrainingIndex,
- ParentSource( Actor::Property::SIZE ),
+ Constraint constraint = Constraint::New<Vector3>( actor,
+ constrainingIndex,
EqualToConstraint() );
- actor.ApplyConstraint( constraint );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.Apply();
}
} // unnamed namespace
// Construction & Destruction
Impl(Control& controlImpl)
: mControlImpl( controlImpl ),
+ mStyleName(""),
mBackground( NULL ),
mStartingPinchScale( NULL ),
mKeyEventSignal(),
switch ( index )
{
+ case Toolkit::Control::Property::STYLE_NAME:
+ {
+ controlImpl.SetStyleName( value.Get< std::string >() );
+ break;
+ }
+
case Toolkit::Control::Property::BACKGROUND_COLOR:
{
controlImpl.SetBackgroundColor( value.Get< Vector4 >() );
switch ( index )
{
+ case Toolkit::Control::Property::STYLE_NAME:
+ {
+ value = controlImpl.GetStyleName();
+ break;
+ }
+
case Toolkit::Control::Property::BACKGROUND_COLOR:
{
value = controlImpl.GetBackgroundColor();
// Data
Control& mControlImpl;
+ std::string mStyleName;
Background* mBackground; ///< Only create the background if we use it
Vector3* mStartingPinchScale; ///< The scale when a pinch gesture starts, TODO: consider removing this
Toolkit::Control::KeyEventSignalType mKeyEventSignal;
static PropertyRegistration PROPERTY_1;
static PropertyRegistration PROPERTY_2;
static PropertyRegistration PROPERTY_3;
+ static PropertyRegistration PROPERTY_4;
};
// Properties registered without macro to use specific member variables.
-PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "background-color", Toolkit::Control::Property::BACKGROUND_COLOR, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
-PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "background-image", Toolkit::Control::Property::BACKGROUND_IMAGE, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
-PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "key-input-focus", Toolkit::Control::Property::KEY_INPUT_FOCUS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "style-name", Toolkit::Control::Property::STYLE_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "background-color", Toolkit::Control::Property::BACKGROUND_COLOR, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "background-image", Toolkit::Control::Property::BACKGROUND_IMAGE, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "key-input-focus", Toolkit::Control::Property::KEY_INPUT_FOCUS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
Toolkit::Control Control::New()
{
return mImpl->mLongPressGestureDetector;
}
+void Control::SetStyleName( const std::string& styleName )
+{
+ if( styleName != mImpl->mStyleName )
+ {
+ mImpl->mStyleName = styleName;
+
+ // Apply new style
+ Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
+ GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+ }
+}
+
+const std::string& Control::GetStyleName() const
+{
+ return mImpl->mStyleName;
+}
+
void Control::SetBackgroundColor( const Vector4& color )
{
Background& background( mImpl->GetBackground() );
Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
// Register for style changes
- styleManager.StyleChangeSignal().Connect( this, &Control::DoStyleChange );
+ styleManager.StyleChangeSignal().Connect( this, &Control::OnStyleChange );
// SetTheme
GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
{
}
-void Control::OnThemeChange( Toolkit::StyleManager styleManager )
-{
- GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
-}
-
-void Control::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
+void Control::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange change )
{
+ // By default the control is only interested in theme (not font) changes
+ if( change.themeChange )
+ {
+ GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+ }
}
void Control::OnPinch(const PinchGesture& pinch)
mImpl->SignalDisconnected( slotObserver, callback );
}
-void Control::DoStyleChange( Toolkit::StyleManager styleManager, StyleChange change )
-{
- if( change.themeChange )
- {
- OnThemeChange( styleManager );
- }
- else if( change.defaultFontChange || change.defaultFontSizeChange )
- {
- OnFontChange( change.defaultFontChange, change.defaultFontSizeChange );
- }
-}
-
} // namespace Internal
} // namespace Toolkit
// Background
/**
+ * @copydoc Dali::Toolkit::Control::SetStyleName
+ */
+ void SetStyleName( const std::string& styleName );
+
+ /**
+ * @copydoc Dali::Toolkit::Control::GetStyleName
+ */
+ const std::string& GetStyleName() const;
+
+ /**
* @copydoc Dali::Toolkit::Control::SetBackgroundColor
*/
void SetBackgroundColor( const Vector4& color );
virtual void OnActivated();
/**
- * @brief This method should be overridden by deriving classes when
- * they wish to be notified when the style manager changes the theme.
+ * @brief This method should be overridden by deriving classes requiring notifications when the style changes.
*
* @param[in] styleManager The StyleManager object.
+ * @param[in] change Information denoting what has changed.
*/
- virtual void OnThemeChange( Toolkit::StyleManager styleManager );
-
- /**
- * @brief This method should be overridden by deriving classes when
- * they wish to be notified when the style changes the default font.
- *
- * @param[in] defaultFontChange Information denoting whether the default font has changed.
- * @param[in] defaultFontSizeChange Information denoting whether the default font size has changed.
- */
- virtual void OnFontChange( bool defaultFontChange, bool defaultFontSizeChange );
+ virtual void OnStyleChange( Toolkit::StyleManager styleManager, StyleChange change );
/**
* @brief Called whenever a pinch gesture is detected on this control.
*/
virtual void SignalDisconnected( SlotObserver* slotObserver, CallbackBase* callback );
- // Style
-
- /**
- * @brief This method is the callback for the StyleChangeSignal from StyleManager
- *
- * @param[in] styleManager The StyleManager Object
- * @param[in] change Information denoting what has changed.
- */
- DALI_INTERNAL void DoStyleChange( Toolkit::StyleManager styleManager, StyleChange change );
-
private:
// Undefined
return GetImplementation().GetLongPressGestureDetector();
}
+void Control::SetStyleName( const std::string& styleName )
+{
+ GetImplementation().SetStyleName( styleName );
+}
+
+const std::string& Control::GetStyleName() const
+{
+ return GetImplementation().GetStyleName();
+}
+
void Control::SetBackgroundColor( const Vector4& color )
{
GetImplementation().SetBackgroundColor( color );
{
enum
{
- BACKGROUND_COLOR = PROPERTY_START_INDEX, ///< name "background-color", @see SetBackgroundColor, type Vector4
+ STYLE_NAME = PROPERTY_START_INDEX, ///< name "style-name", @see SetStyleName, type std::string
+ BACKGROUND_COLOR, ///< name "background-color", @see SetBackgroundColor, type Vector4
BACKGROUND_IMAGE, ///< name "background-image", @see SetBackgroundImage, type Map
KEY_INPUT_FOCUS, ///< name "key-input-focus", @see SetKeyInputFocus, type bool
};
// Background
/**
+ * @brief Sets the name of the style to be applied to the control.
+ *
+ * @param[in] styleName A string matching a style described in a stylesheet.
+ */
+ void SetStyleName( const std::string& styleName );
+
+ /**
+ * @brief Retrieves the name of the style to be applied to the control (if any).
+ *
+ * @return A string matching a style or an empty string.
+ */
+ const std::string& GetStyleName() const;
+
+ // Background
+
+ /**
* @brief Sets the background color of the control.
*
* @param[in] color The required background color of the control
imageData.Update();
image = ImageActor::New( imageData );
- image.SetAnchorPoint( AnchorPoint::CENTER );
image.SetParentOrigin( ParentOrigin::CENTER );
if( border )
* 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
+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;
+ std::string GetTitle() const;
/**
* @brief Adds a button to this Popup.
#include <dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h>
// EXTERNAL INCLUDES
-#include <dali/public-api/animation/active-constraint.h>
+#include <dali/public-api/animation/animation.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/time-period.h>
namespace
{
- // Functors which wrap constraint functions with stored item IDs
- struct WrappedQuaternionConstraint
+// Lerps between current and target using the progress
+template< typename Type >
+void Lerp( Type& current, const Type& target, float progress )
+{
+ current += ((target - current) * progress);
+}
+
+// Functors which wrap constraint functions with stored item IDs
+struct WrappedQuaternionConstraint
+{
+ WrappedQuaternionConstraint( Dali::Toolkit::ItemLayout::QuaternionFunction wrapMe, unsigned int itemId )
+ :mWrapMe(wrapMe),
+ mItemId(itemId)
{
- WrappedQuaternionConstraint(Dali::Toolkit::ItemLayout::QuaternionFunction wrapMe, unsigned int itemId)
- :mWrapMe(wrapMe),
- mItemId(itemId)
- {
- }
+ }
- Dali::Quaternion operator()(const Dali::Quaternion& current, const Dali::PropertyInput& layoutPosition, const Dali::PropertyInput& scrollSpeed, const Dali::PropertyInput& layoutSize)
- {
- float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast<float>(mItemId);
+ void operator()( Dali::Quaternion& current, const Dali::PropertyInputContainer& inputs )
+ {
+ float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast<float>(mItemId);
+ float weight = inputs[3]->GetFloat();
- return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3());
- }
+ current = Dali::Quaternion::Slerp( current, mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() ), weight );
+ }
- Dali::Toolkit::ItemLayout::QuaternionFunction mWrapMe;
- unsigned int mItemId;
- };
+ Dali::Toolkit::ItemLayout::QuaternionFunction mWrapMe;
+ unsigned int mItemId;
+};
- struct WrappedVector3Constraint
+struct WrappedVector3Constraint
+{
+ WrappedVector3Constraint( Dali::Toolkit::ItemLayout::Vector3Function wrapMe, unsigned int itemId )
+ : mWrapMe(wrapMe),
+ mItemId(itemId)
{
- WrappedVector3Constraint(Dali::Toolkit::ItemLayout::Vector3Function wrapMe, unsigned int itemId)
- : mWrapMe(wrapMe),
- mItemId(itemId)
- {
- }
+ }
- Dali::Vector3 operator()(const Dali::Vector3& current, const Dali::PropertyInput& layoutPosition, const Dali::PropertyInput& scrollSpeed, const Dali::PropertyInput& layoutSize)
- {
- float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast<float>(mItemId);
+ void operator()( Dali::Vector3& current, const Dali::PropertyInputContainer& inputs )
+ {
+ float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast<float>(mItemId);
+ float weight = inputs[3]->GetFloat();
- return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3());
- }
+ Lerp( current, mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() ), weight );
+ }
- Dali::Toolkit::ItemLayout::Vector3Function mWrapMe;
- unsigned int mItemId;
- };
+ Dali::Toolkit::ItemLayout::Vector3Function mWrapMe;
+ unsigned int mItemId;
+};
- struct WrappedVector4Constraint
+struct WrappedVector4Constraint
+{
+ WrappedVector4Constraint( Dali::Toolkit::ItemLayout::Vector4Function wrapMe, unsigned int itemId )
+ : mWrapMe(wrapMe),
+ mItemId(itemId)
{
- WrappedVector4Constraint(Dali::Toolkit::ItemLayout::Vector4Function wrapMe, unsigned int itemId)
- : mWrapMe(wrapMe),
- mItemId(itemId)
- {
- }
+ }
- Dali::Vector4 operator()(const Dali::Vector4& current, const Dali::PropertyInput& layoutPosition, const Dali::PropertyInput& scrollSpeed, const Dali::PropertyInput& layoutSize)
- {
- float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast<float>(mItemId);
+ void operator()( Dali::Vector4& current, const Dali::PropertyInputContainer& inputs )
+ {
+ float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast<float>(mItemId);
+ float weight = inputs[3]->GetFloat();
- return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3());
- }
+ Lerp( current, mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() ), weight );
+ }
- Dali::Toolkit::ItemLayout::Vector4Function mWrapMe;
- unsigned int mItemId;
- };
+ Dali::Toolkit::ItemLayout::Vector4Function mWrapMe;
+ unsigned int mItemId;
+};
- struct WrappedBoolConstraint
+struct WrappedBoolConstraint
+{
+ WrappedBoolConstraint( Dali::Toolkit::ItemLayout::BoolFunction wrapMe, unsigned int itemId )
+ : mWrapMe(wrapMe),
+ mItemId(itemId)
{
- WrappedBoolConstraint(Dali::Toolkit::ItemLayout::BoolFunction wrapMe, unsigned int itemId)
- : mWrapMe(wrapMe),
- mItemId(itemId)
- {
- }
+ }
- bool operator()(const bool& current, const Dali::PropertyInput& layoutPosition, const Dali::PropertyInput& scrollSpeed, const Dali::PropertyInput& layoutSize)
- {
- float offsetLayoutPosition = layoutPosition.GetFloat() + static_cast<float>(mItemId);
+ void operator()( bool& current, const Dali::PropertyInputContainer& inputs )
+ {
+ float weight = inputs[3]->GetFloat();
- return mWrapMe(current, offsetLayoutPosition, scrollSpeed.GetFloat(), layoutSize.GetVector3());
+ if ( weight >= 1.0f )
+ {
+ float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast<float>(mItemId);
+ current = mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() );
}
+ }
- Dali::Toolkit::ItemLayout::BoolFunction mWrapMe;
- unsigned int mItemId;
- };
+ Dali::Toolkit::ItemLayout::BoolFunction mWrapMe;
+ unsigned int mItemId;
+};
} //Unnamed namespace
{
ItemLayout::ItemLayout()
-: mOrientation(ControlOrientation::Up),
- mAlphaFunction(Dali::Constraint::DEFAULT_ALPHA_FUNCTION)
+: mOrientation( ControlOrientation::Up ),
+ mAlphaFunction( AlphaFunctions::Linear ),
+ mWeightObject()
{
}
Property::Index scrollSpeedProperty = itemView.GetPropertyIndex("item-view-scroll-speed");
Property::Index scrollPositionProperty = scrollPositionObject.GetPropertyIndex("scroll-position");
+ // We want to animate the layout in so use a weight object to do this
+ if ( !mWeightObject )
+ {
+ mWeightObject = WeightObject::New();
+ }
+
ItemLayout::Vector3Function positionConstraint;
if (GetPositionConstraint(itemId, positionConstraint))
{
WrappedVector3Constraint wrapped(positionConstraint, itemId);
- Constraint constraint = Constraint::New<Vector3>( Actor::Property::POSITION,
- Source( scrollPositionObject, scrollPositionProperty ),
- ParentSource( scrollSpeedProperty ),
- ParentSource( Actor::Property::SIZE ),
- wrapped );
- constraint.SetApplyTime(durationSeconds);
- constraint.SetAlphaFunction(mAlphaFunction);
- actor.ApplyConstraint(constraint);
+ Constraint constraint = Constraint::New<Vector3>( actor, Actor::Property::POSITION, wrapped );
+ constraint.AddSource( Source( scrollPositionObject, scrollPositionProperty ) );
+ constraint.AddSource( ParentSource( scrollSpeedProperty ) );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) );
+ constraint.Apply();
}
ItemLayout::QuaternionFunction rotationConstraint;
{
WrappedQuaternionConstraint wrapped(rotationConstraint, itemId);
- Constraint constraint = Constraint::New<Quaternion>( Actor::Property::ORIENTATION,
- Source( scrollPositionObject, scrollPositionProperty ),
- ParentSource( scrollSpeedProperty ),
- ParentSource( Actor::Property::SIZE ),
- wrapped );
- constraint.SetApplyTime(durationSeconds);
- constraint.SetAlphaFunction(mAlphaFunction);
-
- actor.ApplyConstraint(constraint);
+ Constraint constraint = Constraint::New<Quaternion>( actor, Actor::Property::ORIENTATION, wrapped );
+ constraint.AddSource( Source( scrollPositionObject, scrollPositionProperty ) );
+ constraint.AddSource( ParentSource( scrollSpeedProperty ) );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) );
+ constraint.Apply();
}
ItemLayout::Vector3Function scaleConstraint;
{
WrappedVector3Constraint wrapped(scaleConstraint, itemId);
- Constraint constraint = Constraint::New<Vector3>( Actor::Property::SCALE,
- Source( scrollPositionObject, scrollPositionProperty ),
- ParentSource( scrollSpeedProperty ),
- ParentSource( Actor::Property::SIZE ),
- wrapped );
- constraint.SetApplyTime(durationSeconds);
- constraint.SetAlphaFunction(mAlphaFunction);
-
- actor.ApplyConstraint(constraint);
+ Constraint constraint = Constraint::New<Vector3>( actor, Actor::Property::SCALE, wrapped );
+ constraint.AddSource( Source( scrollPositionObject, scrollPositionProperty ) );
+ constraint.AddSource( ParentSource( scrollSpeedProperty ) );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) );
+ constraint.Apply();
}
ItemLayout::Vector4Function colorConstraint;
{
WrappedVector4Constraint wrapped(colorConstraint, itemId);
- Constraint constraint = Constraint::New<Vector4>( Actor::Property::COLOR,
- Source( scrollPositionObject, scrollPositionProperty ),
- ParentSource( scrollSpeedProperty ),
- ParentSource( Actor::Property::SIZE ),
- wrapped );
-
- constraint.SetApplyTime(durationSeconds);
- constraint.SetAlphaFunction(mAlphaFunction);
+ Constraint constraint = Constraint::New<Vector4>( actor, Actor::Property::COLOR, wrapped );
+ constraint.AddSource( Source( scrollPositionObject, scrollPositionProperty ) );
+ constraint.AddSource( ParentSource( scrollSpeedProperty ) );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) );
constraint.SetRemoveAction(Dali::Constraint::Discard);
-
- actor.ApplyConstraint(constraint);
+ constraint.Apply();
}
ItemLayout::BoolFunction visibilityConstraint;
{
WrappedBoolConstraint wrapped(visibilityConstraint, itemId);
- Constraint constraint = Constraint::New<bool>( Actor::Property::VISIBLE,
- Source( scrollPositionObject, scrollPositionProperty ),
- ParentSource( scrollSpeedProperty ),
- ParentSource( Actor::Property::SIZE ),
- wrapped );
-
- constraint.SetApplyTime(durationSeconds);
- constraint.SetAlphaFunction(mAlphaFunction);
+ Constraint constraint = Constraint::New<bool>( actor, Actor::Property::VISIBLE, wrapped );
+ constraint.AddSource( Source( scrollPositionObject, scrollPositionProperty ) );
+ constraint.AddSource( ParentSource( scrollSpeedProperty ) );
+ constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
+ constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) );
// Release visibility constraints the same time as the color constraint
constraint.SetRemoveAction(Dali::Constraint::Discard);
- actor.ApplyConstraint(constraint);
+ constraint.Apply();
}
+
+ KeyFrames keyFrames = KeyFrames::New();
+ keyFrames.Add( 0.0f, 0.0f );
+ keyFrames.Add( 1.0f, 1.0f );
+
+ Animation applyAnimation = Dali::Animation::New( durationSeconds );
+ applyAnimation.AnimateBetween( Property( mWeightObject, WeightObject::WEIGHT ), keyFrames, mAlphaFunction, durationSeconds );
+ applyAnimation.Play();
}
}
protected:
ControlOrientation::Type mOrientation; ///< the orientation of the layout.
- AlphaFunction mAlphaFunction; ///<Alpha function to be applied when removing/adding constraints
+ AlphaFunction mAlphaFunction; ///< Alpha function to be applied when removing/adding constraints
+ Handle mWeightObject; ///< Weight object gets created to apply the constraints over a certain time
};
} // namespace Toolkit
namespace Toolkit
{
-Vector3 MoveActorConstraint(const Vector3& current,
- const PropertyInput& scrollPositionProperty)
+void MoveActorConstraint( Vector3& current, const PropertyInputContainer& inputs )
{
- return current + scrollPositionProperty.GetVector3();
+ current += inputs[0]->GetVector3();
}
-Vector3 WrapActorConstraint(const Vector3& current,
- const PropertyInput& actorScaleProperty,
- const PropertyInput& actorAnchorPointProperty,
- const PropertyInput& actorSizeProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& scrollWrap)
+void WrapActorConstraint( Vector3& position, const PropertyInputContainer& inputs )
{
- Vector3 position = current;
- bool wrap = scrollWrap.GetBoolean();
+ bool wrap = inputs[5]->GetBoolean();
if(wrap)
{
- const Vector3& min = scrollPositionMin.GetVector3();
- const Vector3& max = scrollPositionMax.GetVector3();
+ const Vector3& min = inputs[3]->GetVector3();
+ const Vector3& max = inputs[4]->GetVector3();
- const Vector3& anchor = actorAnchorPointProperty.GetVector3();
- const Vector3 scale = actorScaleProperty.GetVector3();
- const Vector3 size = actorSizeProperty.GetVector3();
+ const Vector3& anchor = inputs[1]->GetVector3();
+ const Vector3 scale = inputs[0]->GetVector3();
+ const Vector3 size = inputs[2]->GetVector3();
if(fabsf(min.x - max.x) > Math::MACHINE_EPSILON_1)
{
position.y = WrapInDomain(position.y + offsetY, min.y, max.y) - offsetY;
}
}
-
- return position;
}
} // namespace Toolkit
*/
// EXTERNAL INCLUDES
-
-// INTERNAL INCLUDES
+#include <dali/public-api/animation/constraint.h>
namespace Dali
{
*
* Moves an Actor in accordance to scroll position.
*/
-DALI_IMPORT_API Vector3 MoveActorConstraint(const Vector3& current,
- const PropertyInput& scrollPositionProperty);
+DALI_IMPORT_API void MoveActorConstraint( Vector3& current, const PropertyInputContainer& inputs );
/**
* Wrap Actor constraint.
*
* Wraps an Actors position in accordance to min/max bounds of domain.
*/
-DALI_IMPORT_API Vector3 WrapActorConstraint(const Vector3& current,
- const PropertyInput& actorScaleProperty,
- const PropertyInput& actorAnchorPointProperty,
- const PropertyInput& actorSizeProperty,
- const PropertyInput& scrollPositionMin,
- const PropertyInput& scrollPositionMax,
- const PropertyInput& scrollWrap);
+DALI_IMPORT_API void WrapActorConstraint( Vector3& position, const PropertyInputContainer& inputs );
} // namespace Toolkit
--- /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
+{
+
+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>
+
+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:
+
+ /**
+ * @brief The start and end property ranges for this control.
+ */
+ enum PropertyRange
+ {
+ PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
+ PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000 ///< Reserve property indices
+ };
+
+ /**
+ * @brief An enumeration of properties belonging to the TextLabel class.
+ */
+ struct Property
+ {
+ enum
+ {
+ RENDERING_BACKEND = PROPERTY_START_INDEX, ///< name "rendering-backend", The type or rendering e.g. bitmap-based, type INT
+ PLACEHOLDER_TEXT, ///< name "placeholder-text", The text to display when the TextField is empty, type STRING
+ TEXT, ///< name "text", The text to display in UTF-8 format, type STRING
+ FONT_FAMILY, ///< name "font-family", The requested font family, type STRING
+ FONT_STYLE, ///< name "font-style", The requested font style e.g. Regular/Italic, type STRING
+ POINT_SIZE, ///< name "point-size", The size of font in points, type FLOAT
+ EXCEED_POLICY, ///< name "exceed-policy" Specifies how the text is truncated when it does not fit, type INT
+ PRIMARY_CURSOR_COLOR, ///< name "primary-cursor-color", The color to apply to the primary cursor, type VECTOR4
+ SECONDARY_CURSOR_COLOR, ///< name "secondary-cursor-color", The color to apply to the secondary cursor, type VECTOR4
+ ENABLE_CURSOR_BLINK, ///< name "enable-cursor-blink", Whether the cursor should blink or not, type BOOLEAN
+ CURSOR_BLINK_INTERVAL, ///< name "cursor-blink-interval", The time interval between cursor on/off states, type FLOAT
+ CURSOR_BLINK_DURATION, ///< name "cursor-blink-duration", The cursor will stop blinking after this duration (if non-zero), type FLOAT
+ GRAB_HANDLE_IMAGE, ///< name "grab-handle-image", The image to display for grab handle, type STRING
+ DECORATION_BOUNDING_BOX, ///< name "decoration-bounding-box", The decorations (handles etc) will positioned within this area on-screen, type RECTANGLE
+ HORIZONTAL_ALIGNMENT, ///< name "horizontal-alignment", The line horizontal alignment, type STRING, values "BEGIN", "CENTER", "END"
+ VERTICAL_ALIGNMENT ///< name "vertical-alignment", The line vertical alignment, type STRING, values "TOP", "CENTER", "BOTTOM"
+ };
+ };
+
+ /**
+ * @brief Specifies how the text is truncated when it does not fit
+ *
+ * The default value is \e EXCEED_POLICY_CLIP.
+ */
+ enum ExceedPolicy
+ {
+ EXCEED_POLICY_ORIGINAL, ///< The text will be display at original size, and may exceed the TextField boundary.
+ EXCEED_POLICY_CLIP ///< The end of text will be clipped to fit within the TextField.
+ };
+
+ /**
+ * 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
+{
+
+TextLabel TextLabel::New()
+{
+ return Internal::TextLabel::New();
+}
+
+TextLabel TextLabel::New( const std::string& text )
+{
+ TextLabel label = Internal::TextLabel::New();
+ label.SetProperty( TextLabel::Property::TEXT, text );
+
+ return label;
+}
+
+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>
+
+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:
+
+ /**
+ * @brief The start and end property ranges for this control.
+ */
+ enum PropertyRange
+ {
+ PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
+ PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000 ///< Reserve property indices
+ };
+
+ /**
+ * @brief An enumeration of properties belonging to the TextLabel class.
+ */
+ struct Property
+ {
+ enum
+ {
+ RENDERING_BACKEND = PROPERTY_START_INDEX, ///< name "rendering-backend", The type or rendering e.g. bitmap-based, type INT
+ TEXT, ///< name "text", The text to display in UTF-8 format, type STRING
+ FONT_FAMILY, ///< name "font-family", The requested font family, type STRING
+ FONT_STYLE, ///< name "font-style", The requested font style e.g. Regular/Italic, type STRING
+ POINT_SIZE, ///< name "point-size", The size of font in points, type FLOAT
+ MULTI_LINE, ///< name "multi-line", The single-line or multi-line layout option, type BOOLEAN
+ HORIZONTAL_ALIGNMENT, ///< name "horizontal-alignment", The line horizontal alignment, type STRING, values "BEGIN", "CENTER", "END"
+ VERTICAL_ALIGNMENT, ///< name "vertical-alignment", The line vertical alignment, type STRING, values "TOP", "CENTER", "BOTTOM"
+ TEXT_COLOR, ///< name "text-color", The text color, type VECTOR4
+ SHADOW_OFFSET, ///< name "shadow-offset", The drop shadow offset 0 indicates no shadow, type VECTOR2
+ SHADOW_COLOR, ///< name "shadow-color", The color of a drop shadow, type VECTOR4
+ UNDERLINE_ENABLED, ///< name "underline-enabled", The underline enabled flag type BOOLEAN
+ UNDERLINE_COLOR, ///< name "underline-color", The color of the underline type VECTOR4
+ };
+ };
+
+ /**
+ * @brief Create the TextLabel control.
+ *
+ * @return A handle to the TextLabel control.
+ */
+ static TextLabel New();
+
+ /**
+ * @brief Create the TextLabel control.
+ *
+ * @param[in] text The text to display.
+ * @return A handle to the TextLabel control.
+ */
+ static TextLabel New( const std::string& text );
+
+ /**
+ * @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) 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-selection-popup.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h>
+
+using namespace Dali;
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+TextSelectionPopup TextSelectionPopup::New()
+{
+ return Internal::TextSelectionPopup::New();
+}
+
+TextSelectionPopup::TextSelectionPopup()
+{
+}
+
+TextSelectionPopup::TextSelectionPopup( const TextSelectionPopup& handle )
+: Control( handle )
+{
+}
+
+TextSelectionPopup& TextSelectionPopup::operator=( const TextSelectionPopup& handle )
+{
+ if( &handle != this )
+ {
+ Control::operator=( handle );
+ }
+ return *this;
+}
+
+TextSelectionPopup::~TextSelectionPopup()
+{
+}
+
+TextSelectionPopup TextSelectionPopup::DownCast( BaseHandle handle )
+{
+ return Control::DownCast<TextSelectionPopup, Internal::TextSelectionPopup>(handle);
+}
+
+TextSelectionPopup::TextSelectionPopup( Internal::TextSelectionPopup& implementation )
+: Control(implementation)
+{
+}
+
+TextSelectionPopup::TextSelectionPopup( Dali::Internal::CustomActor* internal )
+: Control( internal )
+{
+ VerifyCustomActorPointer<Internal::TextSelectionPopup>( internal );
+}
+
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_SELECTION_POPUP_H__
+#define __DALI_TOOLKIT_TEXT_SELECTION_POPUP_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>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class TextSelectionPopup;
+}
+
+/**
+ * @brief A control which provides a Popup with a number of buttons
+ *
+ * The style of the pop can be set through style sheets, this includes the images for the buttons
+ * A Show and Hide API is provided.
+ *
+ * If the buttons exceed the size constraints of the popup then it will offer scrolling.
+ *
+ *
+ */
+class DALI_IMPORT_API TextSelectionPopup : public Control
+{
+public:
+
+ /**
+ * @brief The start and end property ranges for this control.
+ */
+ enum PropertyRange
+ {
+ PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
+ PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000 ///< Reserve property indices
+ };
+
+ /**
+ * @brief An enumeration of properties belonging to the TextLabel class.
+ */
+ struct Property
+ {
+ enum
+ {
+
+ POPUP_MAX_SIZE, ///< name "popup-max-size", The max size the Popup can be, type VECTOR2
+ POPUP_BACKGROUND_IMAGE, ///< name "popup-background-image", The image to display for popup background type STRING
+ POPUP_CLIPBOARD_BUTTON_ICON_IMAGE, ///< name "popup-clipboard-button-image", The image to use as the popup clipboard icon, type STRING
+ POPUP_CUT_BUTTON_ICON_IMAGE, ///< name "popup-cut-button-image", The image to use as the popup cut icon, type STRING
+ POPUP_COPY_BUTTON_ICON_IMAGE, ///< name "popup-copy-button-image", The image to use as the popup copy icon, type STRING
+ POPUP_PASTE_BUTTON_ICON_IMAGE, ///< name "popup-paste-button-image", The image to use as the popup paste icon, type STRING
+ POPUP_SELECT_BUTTON_ICON_IMAGE, ///< name "popup-select-button-image", The image to use as the popup select icon, type STRING
+ POPUP_SELECT_ALL_BUTTON_ICON_IMAGE, ///< name "popup-select-all-button-image", The image to use as the popup select all icon, type STRING
+ };
+ };
+
+ /**
+ * Create the TextSelectionPopup control.
+ * @return A handle to the TextSelectionPopup control.
+ */
+ static TextSelectionPopup New();
+
+ /**
+ * @brief Creates an empty handle.
+ */
+ TextSelectionPopup();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param[in] handle The handle to copy from.
+ */
+ TextSelectionPopup( const TextSelectionPopup& handle );
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @param[in] handle The handle to copy from.
+ * @return A reference to this.
+ */
+ TextSelectionPopup& operator=( const TextSelectionPopup& handle );
+
+ /**
+ * @brief Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~TextSelectionPopup();
+
+ /**
+ * @brief Downcast a handle to TextSelectionPopup.
+ *
+ * If the BaseHandle points is a TextSelectionPopup 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 TextSelectionPopup or an empty handle
+ */
+ static TextSelectionPopup 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 TextSelectionPopup( Internal::TextSelectionPopup& 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 TextSelectionPopup( Dali::Internal::CustomActor* internal );
+
+}; // Class TextSelectionPopup
+
+} // namespace Toolkit
+
+} // namepsace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_SELECTION_POPUP_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:
-
- /**
- * @brief The start and end property ranges for this control.
- */
- enum PropertyRange
- {
- PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
- PROPERTY_END_INDEX = PROPERTY_START_INDEX + 512 ///< Reserve property indices
- };
-
- /**
- * @brief An enumeration of properties belonging to the TextInput class.
- */
- struct Property
- {
- enum
- {
- HIGHLIGHT_COLOR = PROPERTY_START_INDEX, // Property, name "highlight-color", type Vector4
- CUT_AND_PASTE_COLOR, // Property, name "cut-and-paste-bg-color", type Vector4
- CUT_AND_PASTE_PRESSED_COLOR, // Property, name "cut-and-paste-pressed-color", type Vector4
- CUT_AND_PASTE_BORDER_COLOR, // Property, name "cut-and-paste-border-color", type Vector4
- CUT_AND_PASTE_ICON_COLOR, // Property, name "cut-and-paste-icon-color", type Vector4
- CUT_AND_PASTE_ICON_PRESSED_COLOR, // Property, name "cut-and-paste-icon-pressed-color", type Vector4
- CUT_AND_PASTE_TEXT_COLOR, // Property, name "cut-and-paste-text-color", type Vector4
- CUT_AND_PASTE_TEXT_PRESSED_COLOR, // Property, name "cut-and-paste-text-pressed-color", type Vector4
- CUT_BUTTON_POSITION_PRIORITY, // Property, name "cut-button-position-priority", type unsigned int
- COPY_BUTTON_POSITION_PRIORITY, // Property, name "copy-button-position-priority", type unsigned int
- PASTE_BUTTON_POSITION_PRIORITY, // Property, name "paste-button-position-priority", type unsigned int
- SELECT_BUTTON_POSITION_PRIORITY, // Property, name "select-button-position-priority", type unsigned int
- SELECT_ALL_BUTTON_POSITION_PRIORITY, // Property, name "select-all-button-position-priority", type unsigned int
- CLIPBOARD_BUTTON_POSITION_PRIORITY, // Property, name "clipboard-button-position-priority", type unsigned int
- POP_UP_OFFSET_FROM_TEXT, // Property, name "popup-offset-from-text", type Vector4
- CURSOR_COLOR, // 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:
-
- /**
- * @brief The start and end property ranges for this control.
- */
- enum PropertyRange
- {
- PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
- PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000 ///< Reserve property indices
- };
-
- /**
- * @brief An enumeration of properties belonging to the TextView class.
- */
- struct Property
- {
- enum
- {
- MARKUP_ENABLED = PROPERTY_START_INDEX, ///< name "markup-enabled", @see SetMarkupProcessingEnabled(), type bool
- TEXT, ///< name "text", @see SetText(), type std::string
- MULTILINE_POLICY, ///< name "multiline-policy", @see SetMultilinePolicy(), type std::string
- WIDTH_EXCEED_POLICY, ///< name "width-exceed-policy", @see SetWidthExceedPolicy(), type std::string
- HEIGHT_EXCEED_POLICY, ///< name "height-exceed-policy", @see SetHeightExceedPolicy(), type std::string
- LINE_JUSTIFICATION, ///< name "line-justification", @see SetLineJustification(), type std::string
- FADE_BOUNDARY, ///< name "fade-boundary", @see SetFadeBoundary(), type Vector4
- LINE_HEIGHT_OFFSET, ///< name "line-height-offset", @see SetLineHeightOffset(), type float
- HORIZONTAL_ALIGNMENT, ///< name "horizontal-alignment", @see SetTextAlignment(), type std::string
- VERTICAL_ALIGNMENT, ///< name "vertical-alignment", @see SetTextAlignment(), type std::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__
* Layer contentLayer = Layer::New();
* contentLayer.SetAnchorPoint( AnchorPoint::CENTER );
* contentLayer.SetParentOrigin( ParentOrigin::CENTER );
- * contentLayer.ApplyConstraint( ParentConstraint::Size::New( ParentSize() ) );
* view.AddContentLayer( contentLayer );
* \endcode
*
const unsigned int TOOLKIT_MAJOR_VERSION = 1;
const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 36;
+const unsigned int TOOLKIT_MICRO_VERSION = 37;
const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
$(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/text-controls/text-selection-popup.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_table_view_header_files = \
$(public_api_src_dir)/controls/table-view/table-view.h
-public_api_text_input_header_files = \
- $(public_api_src_dir)/controls/text-input/text-input.h
-
-public_api_text_view_header_files = \
- $(public_api_src_dir)/controls/text-view/text-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_src_dir)/controls/text-controls/text-selection-popup.h
public_api_tool_bar_header_files = \
$(public_api_src_dir)/controls/tool-bar/tool-bar.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 \
$(public_api_src_dir)/scripting/script.h \
$(public_api_src_dir)/scripting/script-plugin.h
+public_api_rendering_backend_header_files = \
+ $(public_api_src_dir)/text/rendering-backend.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
#include <dali-toolkit/public-api/shader-effects/motion-blur-effect.h>
// EXTERNAL INCLUDES
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
Dali::Property::Index uModelProperty = newEffect.GetPropertyIndex( MOTION_BLUR_MODEL_LASTFRAME );
- Constraint constraint = Constraint::New<Matrix>( uModelProperty,
- Source( renderable, Actor::Property::WORLD_MATRIX ),
- EqualToConstraint() );
+ Constraint constraint = Constraint::New<Matrix>( newEffect, uModelProperty, EqualToConstraint() );
+ constraint.AddSource( Source( renderable, Actor::Property::WORLD_MATRIX ) );
// and set up constraint.
- newEffect.ApplyConstraint( constraint );
+ constraint.Apply();
return newEffect;
}
#include <dali-toolkit/public-api/shader-effects/motion-stretch-effect.h>
// EXTERNAL INCLUDES
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
Dali::Property::Index uModelProperty = newEffect.GetPropertyIndex( MOTION_STRETCH_MODELVIEW_LASTFRAME );
- Constraint constraint = Constraint::New<Matrix>( uModelProperty,
- Source( renderable, Actor::Property::WORLD_MATRIX ),
- EqualToConstraint() );
+ Constraint constraint = Constraint::New<Matrix>( newEffect, uModelProperty, EqualToConstraint() );
+ constraint.AddSource( Source( renderable, Actor::Property::WORLD_MATRIX ) );
// and set up constraint.
- newEffect.ApplyConstraint(constraint);
+ constraint.Apply();
return newEffect;
}
#include <dali-toolkit/public-api/shader-effects/nine-patch-mask-effect.h>
// EXTERNAL INCLUDES
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/property-input.h>
#include <dali/public-api/shader-effects/shader-effect.h>
namespace NinePatchMaskEffect
{
-struct NinePatchMaskEffectSizeConstraint
+namespace
{
- Vector2 operator()( const Vector2& current, const PropertyInput& property )
- {
- const Vector3& actorSize = property.GetVector3();
- return Vector2( actorSize.x, actorSize.y );
- }
-};
+
+void NinePatchMaskEffectSizeConstraint( Vector2& current, const PropertyInputContainer& inputs )
+{
+ const Vector3& actorSize = inputs[0]->GetVector3();
+ current.x = actorSize.x;
+ current.y = actorSize.y;
+}
+
+} // unnamed namespace
static void DoApply( ImageActor actor, const std::string& maskImage, const Vector2& maskSize, Vector4 maskBorder )
{
maskEffect.SetEffectImage( ResourceImage::New( maskImage ) );
maskEffect.SetUniform( "uImageSize", Vector2(0,0) /*Constrained to actor size*/ );
- maskEffect.ApplyConstraint( Constraint::New<Vector2>( maskEffect.GetPropertyIndex("uImageSize"),
- Source(actor, Actor::Property::SIZE),
- NinePatchMaskEffectSizeConstraint() ) );
+
+ Constraint constraint = Constraint::New<Vector2>( maskEffect, maskEffect.GetPropertyIndex("uImageSize"), NinePatchMaskEffectSizeConstraint );
+ constraint.AddSource( Source(actor, Actor::Property::SIZE) );
+ constraint.Apply();
maskEffect.SetUniform( "uMaskSize", maskSize );
// 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
*/
// EXTERNAL INCLUDES
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/property-input.h>
} // namespace
/**
- * ReciprocalConstraint
+ * InverseConstraint
*
* f(current, property) = 1.0 / property
*/
-struct ReciprocalConstraint
+void InverseConstraint( float& current, const PropertyInputContainer& inputs )
{
- ReciprocalConstraint(){}
-
- float operator()(const float current, const PropertyInput& property)
- {
- return 1.0f / property.GetFloat();
- }
-};
-
+ current = 1.0f / inputs[0]->GetFloat();
+}
////////////////////////////////////////////////////
//
// precalc 1.0 / uInsideCircleSizeScale on CPU to save shader insns, using constraint to tie to the normal property
Dali::Property::Index insideCircleSizeScalePropertyIndex = handle.GetPropertyIndex(SOFT_BUTTON_INSIDE_SHAPE_SIZE_SCALE_PROPERTY_NAME);
Dali::Property::Index recipInsideCircleSizeScalePropertyIndex = handle.GetPropertyIndex(SOFT_BUTTON_RECIP_INSIDE_SHAPE_SIZE_SCALE_PROPERTY_NAME);
- Constraint constraint = Constraint::New<float>( recipInsideCircleSizeScalePropertyIndex, LocalSource(insideCircleSizeScalePropertyIndex), ReciprocalConstraint());
- handle.ApplyConstraint(constraint);
+ Constraint constraint = Constraint::New<float>( handle, recipInsideCircleSizeScalePropertyIndex, InverseConstraint );
+ constraint.AddSource( LocalSource(insideCircleSizeScalePropertyIndex) );
+ constraint.Apply();
}
return handle;
--- /dev/null
+#ifndef __DALI_TOOLKIT_RENDERING_BACKEND_H__
+#define __DALI_TOOLKIT_RENDERING_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.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+// 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
+};
+
+const unsigned int DEFAULT_RENDERING_BACKEND = RENDERING_SHARED_ATLAS;
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_RENDERING_BACKEND_H__
--- /dev/null
+/*
+Copyright (c) 2000-2014 Samsung Electronics Co., Ltd All Rights Reserved
+
+This file is part of Dali Toolkit
+
+PROPRIETARY/CONFIDENTIAL
+
+This software is the confidential and proprietary information of
+SAMSUNG ELECTRONICS ("Confidential Information"). You shall not
+disclose such Confidential Information and shall use it only in
+accordance with the terms of the license agreement you entered
+into with SAMSUNG ELECTRONICS.
+
+SAMSUNG make no representations or warranties about the suitability
+of the software, either express or implied, including but not limited
+to the implied warranties of merchantability, fitness for a particular
+purpose, or non-infringement. SAMSUNG shall not be liable for any
+damages suffered by licensee as a result of using, modifying or
+distributing this software or its derivatives.
+*/
+
+
+
+//******************************************************************************
+//
+// Default style theme for Tizen dark theme, The values should come from
+// UX design document.
+//
+//******************************************************************************
+
+{
+ "styles":
+ {
+ "textlabel":
+ {
+ "font-family":"SamsungSans",
+ "font-style":"Regular"
+ },
+
+ "textlabel-font-size-0":
+ {
+ "point-size":8
+ },
+ "textlabel-font-size-1":
+ {
+ "point-size":10
+ },
+ "textlabel-font-size-2":
+ {
+ "point-size":15
+ },
+ "textlabel-font-size-3":
+ {
+ "point-size":19
+ },
+ "textlabel-font-size-4":
+ {
+ "point-size":25
+ },
+
+ "textfield":
+ {
+ "font-family":"SamsungSans",
+ "font-style":"Regular"
+ },
+
+ "textfield-font-size-0":
+ {
+ "point-size":10
+ },
+ "textfield-font-size-1":
+ {
+ "point-size":10
+ },
+ "textfield-font-size-2":
+ {
+ "point-size":10
+ },
+ "textfield-font-size-3":
+ {
+ "point-size":10
+ },
+ "textfield-font-size-4":
+ {
+ "point-size":10
+ },
+
+ "scrollview":
+ {
+ "overshoot-effect-color":"B018"
+ }
+ }
+}
--- /dev/null
+./tizen-dark-theme.json
\ No newline at end of file
{
"styles":
{
- "textinput":
+ "textlabel":
{
- "highlight-color":"F060",
- "cut-and-paste-bg-color":"B061L41",
- "cut-and-paste-pressed-color":"B061L41P",
- "cut-and-paste-border-color":"B061L42",
- "cut-and-paste-icon-color":"T126",
- "cut-and-paste-icon-pressed-color":"T126P",
- "cut-and-paste-text-color":"T1221",
- "cut-and-paste-text-pressed-color":"T1221P",
- "cut-button-position-priority":4,
- "copy-button-position-priority":3,
- "paste-button-position-priority":5,
- "select-button-position-priority":1,
- "select-all-button-position-priority":2,
- "clipboard-button-position-priority":6,
- "cursor-color":"F052"
+ "font-family":"HelveticaNeue",
+ "font-style":"Regular",
+ "point-size":18
+ },
+ "textfield":
+ {
+ "font-family":"HelveticaNeue",
+ "font-style":"Regular",
+ "point-size":18
},
"scrollview":
{
* - \link hello-world Hello World - explained \endlink
*
* \section Actors Actors
- * - \link image-text-mesh-actor Image, Text and Mesh actors \endlink
+ * - \link image-mesh-actor Image and Mesh actors \endlink
* - \link event-system Event Handling \endlink
* - \link custom-actor Custom Actor \endlink
*
* - \link size-negotiation Size Negotiation \endlink
*
* \section UIControls UI Controls
+ * - \link text-label Text Label \endlink
* - \link item-view Item View \endlink
- * - \link text-view Text View \endlink
- * - \link text-input Text Input \endlink
* - \link scroll-view Scroll View \endlink
* - \link size-negotiation-controls Size Negotiation for Controls \endlink
- * - \link markup-processor Markup Processor \endlink
* - \link type-registration Type Registration \endlink
* - \link properties Properties \endlink
* - \link background Background \endlink
</td>
</table>
-This can be used for ALL existing controls like TextView as well:
+This can be used for ALL existing controls like TextLabel as well:
@code
-Dali::Toolkit::TextView textView = Dali::Toolkit::TextView::New( "Hello World" );
-textView.SetBackgroundColor( Dali::Color::RED );
+Dali::Toolkit::TextLabel label = Dali::Toolkit::TextLabel::New( "Hello World" );
+label.SetBackgroundColor( Dali::Color::RED );
@endcode
<table border=0 cellpadding=10><tr>
<td>
-\image html BackgroundTextView.png
+\image html BackgroundTextLabel.png
</td>
</table>
-/*! \page image-text-mesh-actor Image, Text and Mesh actors
+/*! \page image-mesh-actor Image and Mesh actors
*
*
* <h1 class="pg">Overview</h1>
- * The Dali::ImageActor, Dali::TextActor, Dali::MeshActor are inherited from Dali::Actor and provide means to display resources like Images, Text and Geometries (Triangle meshes) on the stage.
+ * The Dali::ImageActor & Dali::MeshActor are inherited from Dali::Actor and provide means to display resources like Images and Geometries (Triangle meshes) on the stage.
* All the Dali::Actor methods can be called on them.<br>
*
* - <b>ImageActor:</b> An actor for displaying Images. It allows the developer to display a Dali::Image object on the stage.<br>
- * - <b>TextActor:</b> An actor for displaying text.<br>
* - <b>MeshActor:</b> An actor for displaying one or more mesh geometries. It may have children, which may be plain actors or other mesh actors.<br>
*
* <h1 class="pg">Image Actor</h1>
* @endcode
*
*
- *
- *
- *
- * <h1 class="pg">Text Actor</h1>
- *
- *
- * <h2 class="pg">Displaying Text</h2>
- * The text displayed by the text actor is initialised/set on construction, which can be changed later.
- *
- * @code
- * Dali::TextActor myTextActor = Dali::TextActor::New("Hi");
- * std::string str("Hello");
- * if (myTextActor.GetText() != str)
- * {
- * myTextActor.SetText(str);
- * }
- * @endcode
- *
- *
- * <h2 class="pg">Fonts</h2>
- * It's possible to specify a font for the text displayed by the text actor.
- * @code
- * Dali::Font freeSerif = Dali::Font::New("FreeSerif", 8);
- * myTextActor.SetFont(freeSerif);
- * @endcode
- *
- *
- * <h2 class="pg">Ellipsis</h2>
- * It is possible to display an ellipsis in the TextActor when the text is truncated.
- * @code
- * std::string str("...");
- * if (myTextActor.GetEllipsis() != str)
- * {
- * myTextActor.SetEllipsis(str);
- * }
- * @endcode
- *
- * <h2 class="pg">Style</h2>
- *
- * By calling the Dali::TextActor::SetTextStyle or by passing a Dali::TextStyle to the constructor, it's possible to define styling parameters such as color, font, size, outline, glow, shadow, italics or bold.
- * @code
- * TextStyle style;
- * style.SetItalic( true );
- *
- * myTextActor.SetTextStyle( style );
- * @endcode
- *
- * @see Dali::TextActor::SetTextStyle()
- *
- * It is possible to specify the text fit style for the text actor. The developer can specify whether the ellipsis should appear on the left, centre, or at the end
- * @code
- * // default : NONE
- * myTextActor.SetTextFitStyle(TextUtilities::EllipsizeRight);
- * @endcode
- *
- * <h2 class="pg">Loading state</h2>
- * It is possible to get the font loading status for the text and do processing accordingly.
- * @code
- * // observe text loading and do some processing when it's done
- * if( Dali::ResourceLoadingSucceeded == myTextActor.GetLoadingState() )
- * {
- * // text already loaded, Do the processing here
- * OnTextFontLoaded();
- * }
- * else
- * {
- * // text not yet loaded, Connect to the SignalTextAvailable signal and Do the processing when it occurs
- * myTextActor.SignalTextAvailable().Connect(this, &MyClass::OnTextFontLoaded);
- * }
- * @endcode
- *
- *
- *
- *
* <h1 class="pg">Mesh Actor</h1>
*
* <h2 class="pg">Construction</h2>
+++ /dev/null
-/*! \page markup-processor Markup processor
- *
- * <h1 class="pg">Overview</h1>
- *
- * Dali::Toolkit::MarkupProcessor functions provide mechanisms to build and modify a Dali::Toolkit::MarkupProcessor::StyledTextArray used to store text with style.
- *
- * <h1 class="pg">Build a styled text array from a markup string</h1>
- *
- * Dali::Toolkit::MarkupProcessor::GetStyledTextArray() could be used to convert an html-ish markup string into a styled text array. This string uses html-ish tags to
- * define the text's style as follows:
- *
- * <ul>
- * <li>\e \<b\>\</b\> Bold text.
- * i.e. \<b\>Bold text\</b\>"
- * \image html text-view/Bold.png
- *
- * <li>\e \<i\>\</i\> Italic text.
- * i.e. \<i\>Italic text\</i\>"
- * \image html text-view/Italic.png
- *
- * <li>\e \<u\>\</u\> Underlined text.
- * i.e. \<u\>Underline text\</u\>"
- * \image html text-view/Underline.png
- *
- * <li>\e \<br /\> New line.
- *
- * <li>\e \<font\>\</font\> Specifies font properties:
- * <ul>
- * <li> \e face The name of a font or font family.
- * <li> \e style The style of a font.
- * <li> \e size Font point size. @see Dali::PointSize.
- * <li> \e color Font color. See the \ref color section for more details.
- * </ul>
- *
- * i.e. \<font face='FreeSerif' style='Regular'\>FreeSerif font\</font\>
- * \image html text-view/FreeSerifFont.png
- *
- * <li>\e \<shadow\>\</shadow\> Specifies shadow properties.
- * <ul>
- * <li> \e paramx X offset.
- * <li> \e paramy Y offset.
- * <li> \e color Shadow color. See the \ref color section for more details.
- * </ul>
- *
- * i.e. \<shadow color='black' paramx='1.5' paramy='1.5'\>Black shadow\</shadow\>
- * \image html text-view/Black-Shadow.png
- *
- * @see Dali::TextActor::SetShadow()
- * <br><br>
- * <li>\e \<glow\>\</glow\> Specifies glow properties.
- * <ul>
- * <li> \e param Glow around the text.
- * <li> \e color Glow color. See the \ref color section for more details.
- * </ul>
- *
- * i.e. \<smooth param='0.65'\>\<glow color='blue' param='0.05'\>Blue glow\</glow\>\</smooth\>
- * \image html text-view/Blue-Glow.png
- *
- * @see Dali::TextActor::SetGlow()
- * <br><br>
- * <li>\e \<outline\>\</outline\> Specifies outline properties.
- * <ul>
- * <li> \e paramx X thickness.
- * <li> \e paramy Y thickness.
- * <li> \e color Outline color. See the \ref color section for more details.
- * </ul>
- *
- * i.e. \<outline color='red' paramx='0.5' paramy='0.5'\>Red outline\</outline\>
- * \image html text-view/Red-Outline.png
- *
- * @see Dali::TextActor::SetOutline()
- * <br><br>
- * <li>\e \<smooth\>\</smooth\> Specify the smooth edge.
- * <ul>
- * <li> \e param Distance field.
- * </ul>
- *
- * i.e. \<smooth param='0.3'\>Smooth text\</smooth\>
- * \image html text-view/Smooth-Text.png
- *
- * @see Dali::TextActor::SetSmoothEdge()
- * </ul>
- *
- * See also \ref color, \ref special_characters and \ref example for more details.
- *
- * <h1 class="pg">Get a markup string from a styled text array</h1>
- *
- * Dali::Toolkit::MarkupProcessor::GetMarkupString() could be used to convert a styled text array into an html-ish markup string.
- *
- * <h1 class="pg">Modify a styled text array</h1>
- *
- * Different functions are provided to modify whole or part of a styled text array with a given style. A mask could be used to modify only some properties of the style.
- *
- * @see Dali::Toolkit::MarkupProcessor::SetTextStyle( StyledTextArray& styledTextArray, const TextStyle& style, TextStyle::Mask mask )
- * @see Dali::Toolkit::MarkupProcessor::SetTextStyle( const Text& text, StyledTextArray& styledTextArray, const TextStyle& style, TextStyle::Mask mask )
- * @see Dali::Toolkit::MarkupProcessor::SetTextStyleToRange( StyledTextArray& styledTextArray, const TextStyle& style, TextStyle::Mask mask, std::size_t begin, std::size_t end )
- *
- * <h1 class="pg">Appendix</h1>
- * \section color Color
- *
- * Different options could be used to define a color:
- *
- * <ul>
- * <li> Hexadecimal with alpha channel. 0xAARRGGBB with the alpha channel in the most significant bits.
- * <li> Hexadecimal without alpha channel. 0xRRGGBB.
- * <li> Web color format (six or three digits). \#RRGGBB, \#RGB
- * <li> Some colors could be defined with natural language: <em>black, white, red, green, blue, yellow, magenta, cyan</em> and \e transparent.
- * </ul>
- *
- * \section special_characters Special characters
- *
- * \< and \> characters are used to build the html-ish tags. To type them is needed to add a back slash character in front of them.
- * @note in c and c++ the back slash is represented with a double back slash '\\\\'.
- *
- * i.e. text.SetText("a \\< b \\< c");
- * \image html text-view/AlessBlessC.png
- *
- * It transform any pair CR+LF new line characters into a single LF new line character.
- *
- * \section fonts Font Style, Weight and Smooth
- *
- * This appendix shows the differences and relations between the font style, the font weight, the smoothness and the italics.
- *
- * When a font is loaded, Dali uses different mechanisms to modify the render of glyphs.<br><br>
- * i.e \<font face='Samsung Sans' size='24'\>Hello World\</font\> produces the "Hello World" bellow.
- * \image html text-view/FontAppendix01.png
- * By adding the \<i\> \<b\> \<smooth\> tags to the markup string or using the Dali::TextStyle::SetItalics(), Dali::TextStyle::SetWeight() or Dali::TextStyle::SetSmoothEdge() methods,
- * Dali modifies how glyphs of the same font are rendered.<br><br>
- * i.e \<i\>\<font face='Samsung Sans' size='24'\>Hello World\</font\>\</i\>
- * \image html text-view/FontAppendix02.png
- * i.e \<b\>\<font face='Samsung Sans' size='24'\>Hello World\</font\>\</b\>
- * \image html text-view/FontAppendix03.png
- *
- * The smooth parameter can be used to adjust the thickness of the rendered glyphs.<br><br>
- * i.e<br> \<smooth param=0.65\>\<font face='Samsung Sans' size='24'\>Hello World\</font\>\</smooth\>\<br /\><br>
- * \<font face='Samsung Sans' size='24'\>Hello World\</font\>\<br /\><br>
- * \<smooth param=0.4\>\<font face='Samsung Sans' size='24'\>Hello World\</font\>\</smooth\>\<br /\><br>
- * \<b\>\<font face='Samsung Sans' size='24'\>Hello World\</font\>\</b\>\<br /\><br>
- * \<smooth param=0.2\>\<font face='Samsung Sans' size='24'\>Hello World\</font\>\</smooth\>
- *
- * \image html text-view/FontAppendix04.png
- *
- * All "Hello World" above have been rendered using the same font, saving some memory. Alternatively, the platform can provide fonts with different styles.<br>
- *
- * i.e. Samsung platform provides among others:<br>
- * Samsung Sans:style=Light<br>
- * Samsung Sans:style=Regular<br>
- * Samsung Sans:style=Medium<br>
- *
- * \<font face='Samsung Sans' style='Light' size='24'\>Hello World\</font\>\<br /\><br>
- * \<font face='Samsung Sans' style='Regular' size='24'\>Hello World\</font\>\<br /\><br>
- * \<font face='Samsung Sans' style='Medium' size='24'\>Hello World\</font\>
- * \image html text-view/FontAppendix05.png
- *
- * The three "Hello World" above have been rendered with three different fonts.<br>
- *
- * The <i>fc-list</i> command can be executed on the platform command line to check with fonts and which styles are supported.
- *
- * \section example Example
- *
- * \code
- * const std::string text( "<font size='16' color='black'>"
- * "<i>Italics: 기울임 꼴</i><br/>"
- * "<u>Underline: 밑줄</u><br/>"
- * "<b>Bold: 두꺼운</b><br/>"
- * "<font face='FreeSerif'>Font FreeSerif</font><br/>"
- * "<font color='white'><shadow color='black' paramx='1.5' paramy='1.5'>Shadow: 그림자</shadow></font><br/>"
- * "<font color='white'><smooth param='0.75'><glow color='blue' param='0.1'>Glow: 빛나다</glow></smooth></font><br/>"
- * "<font color='white'><outline color='red' paramx='0.5' paramy='0.5'>Outline: 윤곽선</outline></font><br/>"
- * "<smooth param='0.3'>Smooth: 부드럽게</smooth><br/>"
- * "</font>" );
- *
- * Toolkit::MarkupProcessor::StyledTextArray styledText;
- * Toolkit::MarkupProcessor::GetStyledTextArray( text, styledText, true );
- *
- * Toolkit::TextView textView = Toolkit::TextView::New( styledText );
- * textView.SetParentOrigin( ParentOrigin::CENTER );
- *
- * Stage::GetCurrent().Add( textView );
- * \endcode
- *
- * \image html text-view/text-view.png
- * Text generated with the example above.
- */
+++ /dev/null
-/*! \page text-input Text Input
- *
- TextInput is a Dali::Actor which allows the input of text from an on-screen virtual keyboard or attached hardware keyboard.
-
-
-<h2 class="pg">Basic Text Input Set-up</h2>
-
- The below code creates a new TextInput
-
- @code
- Dali::Toolkit::TextInput myTextInput;
- myTextInput = Dali::Toolkit::TextInput::New();
- @endcode
-
- The following code sets the size and adds it to the stage
- @code
- myTextInput.SetParentOrigin(ParentOrigin::CENTER);
- myTextInput.SetSize(stageWidth*0.25f, stageWidth*0.5f);
- Stage::GetCurrent().Add(myTextInput);
- @endcode
-
- For a TextInput to receive input from the keyboard it must be in edit mode.
-
- To enter edit mode the below call can be made. If the virtual on-screen keyboard is supported then it will be displayed.
- Internally TextInput will set focus to this TextInput and key events will be sent to it.
-
- @code myTextInput.SetEditable(true);@endcode
-
- After this call the TextInput will receive any key press. If you have more than one TextInput the focus will change between them when the edit mode is
- initiated on any Text Input.
-
- To automatically start edit mode when the TextInput is "tapped" you can call the following:
-
- @code myTextInput.SetEditOnTouch()@endcode
-
- You will then need to end edit mode by making the call below or swiping away the keyboard (Virtual On-screen Keyboard)
- @code myTextInput.SetEditable(false);@endcode
-
- The call will hide the virtual keyboard if previously shown by Text Input.
-
- Then the input string as plain text can be retrieved using
- @code Dali::Toolkit::TextInput::GetText()@endcode
-
-<h2 class="pg"> Text Selection </h2>
-
- The SetTextSelectable API when set to true enables text to be highlighted, once highlighted the text style can be changed,
- the text can be cut, or copied, overwritten with new text or deleted.
-
- The user does a Long-Press on the text to get the option of text selection.
-
- @code Dali::Toolkit::TextInput::SetTextSelectable( true ) @endcode
-
-<h2 class="pg"> Text Styling </h2>
-
- In conjunction with TextView and the Markup processor, TextInput enables text to be styled.
-
- There are 3 ways to effect the text styling.
-
- SetActiveStyle, new input text is set to the Red glow style
- @code
- TextStyle style;
- style.SetGlow ( true, Dali::Color::RED );
- myTextInput.SetActiveStyle( style, MarkupProcessor::GLOW );
- @endcode
-
- ApplyStyle, selected/highlighted text now has the Red glow style
- @code
- TextStyle style;
- style.SetGlow ( true, Dali::Color::RED );
- myTextInput.ApplyStyle( style, MarkupProcessor::GLOW );
- @endcode
-
- ApplyStyleToAll, all text now has the Red glow style
- @code
- TextStyle style;
- style.SetGlow ( true, Dali::Color::RED );
- myTextInput.ApplyStyleToAll( style, MarkupProcessor::GLOW );
- @endcode
-
- Then the input string with Mark-up defining the style can be retrieved using
- @code Dali::Toolkit::TextInput::GetMarkupText()@endcode
- This would be usefull if you wish to save the styled text the user has input so it can be re-displayed another time.
-
- Signals are emitted when style changes.
-
- See Dali::Toolkit::TextInput::StyleMask for available styling options.
-
-
-
-
- */
-
--- /dev/null
+/*! \page text-label Text Label
+ *
+\section overview Overview
+The Dali::Toolkit::TextLabel is a Dali::Toolkit::Control which renders a short text string.\n
+Text labels are lightweight, non-editable and do not respond to user input.
+
+\subsection basictextlabelusage Basic usage
+
+To display a TextLabel the TEXT property must be set using a UTF-8 string.
+
+\code
+TextLabel label = TextLabel::New();
+label.SetProperty( TextLabel::Property::TEXT, "Hello World" );
+Stage::GetCurrent().Add( label );
+\endcode
+
+The label must also be added to the stage, or to an actor which is on the stage.\n
+In this example the text-label will be automatically given a natural size i.e. large enough to fit the text.\n
+The position of the label on-screen is dependent on the parent-origin and anchor-point properties:
+
+<table border=0 cellpadding=10>
+<tr>
+ <td>
+ \image html TextLabelTopLeft.png
+ </td>
+ <td>
+ \image html TextLabelCenter.png
+ </td>
+</tr>
+<tr>
+ <td>
+ (ParentOrigin::TOP_LEFT, AnchorPoint::TOP_LEFT)
+ </td>
+ <td>
+ (ParentOrigin::CENTER, AnchorPoint::CENTER)
+ </td>
+</tr>
+</table>
+
+\subsection fontselection Font Selection
+
+By default TextLabel will automatically select a suitable font from the platform.\n
+Typically fonts do not support all scripts, for example Latin fonts often do not provide Arabic glyphs.\n
+Therefore you should expect TextLabel to select different fonts for each script.
+
+Alternatively a font may be requested using eiter or all of FONT_FAMILY, FONT_STYLE, and POINT_SIZE properties:
+\code
+label.SetProperty( TextLabel::Property::FONT_FAMILY, "HelveticaNue" );
+label.SetProperty( TextLabel::Property::FONT_STYLE, "Regular" );
+label.SetProperty( TextLabel::Property::POINT_SIZE, 12.0f );
+\endcode
+However the TextLabel will fall-back to using the default font, if the requested font does not support the required scripts.
+
+\subsection fontselection Text Alignment
+
+Wrapping can be enabled using the MULTI_LINE property:\n
+\code
+label.SetProperty( TextLabel::Property::MULTI_LINE, true );
+\endcode
+
+The text can be either aligned to the start, end, or center of the available area:
+\code
+label.SetProperty( TextLabel::Property::ALIGNMENT, "BEGIN" ); // "CENTER" or "END"
+\endcode
+
+<table border=0 cellpadding=10>
+<tr>
+ <td>
+ Here is the "BEGIN" alignment shown for left-to-right (Latin) and right-to-left (Arabic) scripts:
+ </td>
+</tr>
+<tr>
+ <td>
+ \image html LatinBegin.png
+ </td>
+ <td>
+ \image html ArabicBegin.png
+ </td>
+</tr>
+<tr>
+ <td>
+ Here is the "CENTER" alignment shown for left-to-right (Latin) and right-to-left (Arabic) scripts:
+ </td>
+</tr>
+<tr>
+ <td>
+ \image html LatinCenter.png
+ </td>
+ <td>
+ \image html ArabicCenter.png
+ </td>
+</tr>
+<tr>
+ <td>
+ Here is the "END" alignment shown for left-to-right (Latin) and right-to-left (Arabic) scripts:
+ </td>
+</tr>
+<tr>
+ <td>
+ \image html LatinEnd.png
+ </td>
+ <td>
+ \image html ArabicEnd.png
+ </td>
+</tr>
+</table>
+
+*/
+++ /dev/null
-/*! \page text-view Text View
- *
- * \section overview Overview
- *
- * The Dali::Toolkit::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.
- *
- * Dali::Toolkit::TextView also provides text layout information which could be used in other UI Dali::Toolkit::Control classes or other applications.
- *
- * \section multiline Multi-line wrapping
- *
- * Different multi-line and exceed policies could be set to layout the given text.
- *
- * Both multi-line and exceed policies work together.
- * Dali::Toolkit::TextView::MultilinePolicy policies define how to wrap a line if it doesn't fit inside the boundary's width
- * whereas Dali::Toolkit::TextView::ExceedPolicy policies define what to do if the wrapped text is bigger than the text view's boundary.
- *
- * i.e. \e SplitByWord could be used as 'multi-line policy' to wrap a line if it's too long. If one of the words is longer than the text-view's width, \e Split could be
- * used as 'width exceed policy' to split a word in different lines. If the text is too long and exceeds the text-view's height, \e EllipsizedEnd could be
- * used as 'height exceed policy' to render only the text which fits inside the boundaries of the text-view.
- *
- * @see more \ref examples.
- *
- * \subsection multiline_policies Multi-line policies
- *
- * <ul>
- * <li><em>Split by new line character</em>.
- * Text will be wrapped when an <em>end of line \\n</em> or <em>\<br /\></em> is found.
- *
- * <li><em>Split by word</em>.
- * Text will be wrapped when an <em>end of line \\n</em> or <em>\<br /\></em> is found or if the text doesn't fit in the text view width.
- * In that case, some words will be moved to a new line.
- *
- * <li><em>Split by character</em>.
- * Text will be wrapped when an <em>end of line \\n</em> or <em>\<br /\></em> is found or if the text doesn't fit in the text view width.
- * In that case, words which don't fit will be wrapped in two and the remaining text moved to a new line.
- * </ul>
- * Dali::Toolkit::TextView::SplitByNewLineChar is set by default.
- *
- * \subsection exceed_policies Exceed policies
- *
- * <ul>
- * <li><em>Original size</em>.
- * Text will be displayed with its original size.
- *
- * <li><em>Fade</em>.
- * Text will be faded out.
- *
- * <li><em>Split</em>.
- * Text will be wrapped and moved to a new line.
- *
- * <li><em>Shrink to fit</em>.
- * Text will be shrunk to fit in the text view's boundary.
- *
- * <li><em>Ellipsize at the end</em>.
- * Text will be truncated to fit in the text view's boundary and the ellipsize text will be added. ( '...' by default).
- * </ul>
- * Dali::Toolkit::TextView::Original is set by default.
- *
- * @see Dali::Toolkit::TextView::SetMultilinePolicy
- * @see Dali::Toolkit::TextView::SetWidthExceedPolicy
- * @see Dali::Toolkit::TextView::SetHeightExceedPolicy
- * @see Dali::Toolkit::TextView::SetFadeBoundary
- * @see Dali::Toolkit::TextView::SetEllipsizeText
- *
- * @note Multiple combinations are possible but not all of them are already implemented.
- * @see \ref exceed_policies_combinations table to check which combinations are implemented
- *
- * \section scroll Scroll
- *
- * Text could be scrolled if it exceeds the boundaries of the text-view.
- *
- * @see Dali::Toolkit::TextView::SetScrollEnabled
- * @see Dali::Toolkit::TextView::SetScrollPosition
- *
- * \section line_height_spacing Line height spacing
- *
- * The default space between lines could be modified by setting an offset with Dali::Toolkit::TextView::SetLineHeightOffset().
- *
- * <h1 class="pg">Font support and multi-language detection</h1>
- *
- * Dali::Toolit::TextView uses the font specified in the styled text array to display the given text.
- *
- * See \link markup-processor Markup Processor \endlink for more details on how to create styling markup strings and styled text arrays.
- *
- * To support multi-language texts, text-view does the following actions per character:
- * <ul>
- * <li> Check if there is a font defined in the styled text array.
- * <li> If there isn't, try to use the default platform font.
- * <li> Check if the character is supported by the font.
- * <li> If isn't, find the most suitable font for the character.
- * </ul>
- *
- * \section text_alignment Text alignment and justification
- *
- * Dali::Toolkit::TextView provides a method to align the whole text inside the text view's boundary as well as a method to justify each line
- * inside the text.
- *
- * The Dali::Toolkit::Alignment::Type is used to align the whole text in the text view's area.
- * A text could be horizontally aligned (left, center, right) and/or vertically aligned (top, center, bottom).
- * Dali::Toolkit::Alignment::HorizontalCenter | Dali::Toolkit::Alignment::VerticalCenter is set by default.
- *
- * The Dali::Toolkit::TextView::LineJustification is used to justify each line inside the text (left, center, right, justified).
- * Dali::Toolkit::TextView::Left is set by default.
- *
- * @see Dali::Toolkit::TextView::SetTextAlignment @see Dali::Toolkit::TextView::SetLineJustification
- *
- * \section text_styling Text styling
- *
- * Dali::Toolkit::TextView supports all text styling features provided by Dali::TextActor (font type, color, size, outline, etc).
- *
- * Different techniques are provided to set or modify the text view's style:
- *
- * <ul>
- * <li> By setting a Dali::Toolkit::MarkupProcessor::StyledTextArray with the Dali::Toolkit::TextView::SetText(const MarkupProcessor::StyledTextArray& text) method.
- * <li> By setting a new Dali::TextStyle to the current text with the Dali::Toolkit::TextView::SetStyleToCurrentText() method.
- * <li> By setting an html-ish markup string which contains both text and style with the Dali::Toolkit::TextView::SetText(const std::string& text) method.
- @note By default the style markup processor is disabled. @see Dali::Toolkit::TextView::SetMarkupProcessingEnabled to enable the markup processing.
- * </ul>
- *
- * See \link markup-processor Markup Processor \endlink for more details on how to create styling markup strings and styled text arrays.
- *
- * \section retrieve Retrieve text layout information
- *
- * The Dali::Toolkit::TextView::GetTextLayoutInfo() retrieves how the input text has been laid out.
- *
- * For each character it retrieves its size and position, visibility, etc. @see Dali::Toolkit::TextView::CharacterLayoutInfo.
- *
- * For each laid-out line it retrieves the index of the first character of the line, size, etc. @see Dali::Toolkit::TextView::LineLayoutInfo.
- *
- * \section appendix Appendix
- * \subsection examples Examples
- *
- * The following examples show how to use TextView. The grey square is an actor which has been added just to show the size of the text-view.
- *
- * Creation of a text view actor with all its parameters by default.
- * \code
- * Toolkit::TextView textView = Toolkit::TextView::New( "Hello world!" );
- * textView.SetParentOrigin( ParentOrigin::CENTER );
- *
- * Stage::GetCurrent().Add( textView );
- * \endcode
- *
- * This example wraps the text in lines only when a \\n character is found. The size of the text-view will be automatically resized to fit the whole text inside.
- * \code
- * const std::string text( "<font color='black'>"
- * "Lorem ipsum dolor sit amet, consectetur adipisicing elit,\n"
- * "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
- * "</font>" );
- *
- * Toolkit::TextView textView = Toolkit::TextView::New( "" );
- * textView.SetMarkupProcessingEnabled( true );
- * textView.SetText( text );
- * textView.SetParentOrigin( ParentOrigin::CENTER );
- *
- * textView.SetMultilinePolicy( Toolkit::TextView::SplitByNewLineChar );
- * textView.SetWidthExceedPolicy( Toolkit::TextView::Original );
- * textView.SetHeightExceedPolicy( Toolkit::TextView::Original );
- * textView.SetLineJustification( Toolkit::TextView::Center );
- *
- * Stage::GetCurrent().Add( textView );
- * \endcode
- * \image html text-view/text-view-example-01.png
- *
- * This example wraps the lines by the next word when it exceeds the width of the text-view. The height exceed policy is set to \e Original so it may exceed the height of the text-view.
- *
- * \code
- * const std::string text( "<font color='black'>"
- * "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
- * "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
- * "</font>" );
- *
- * Toolkit::TextView textView = Toolkit::TextView::New( "" );
- * textView.SetMarkupProcessingEnabled( true );
- * textView.SetText( text );
- * textView.SetParentOrigin( ParentOrigin::CENTER );
- * textView.SetSize( 300.f, 125.f );
- *
- * textView.SetMultilinePolicy( Toolkit::TextView::SplitByWord );
- * textView.SetWidthExceedPolicy( Toolkit::TextView::Original );
- * textView.SetHeightExceedPolicy( Toolkit::TextView::Original );
- * textView.SetLineJustification( Toolkit::TextView::Center );
- *
- * Stage::GetCurrent().Add( textView );
- * \endcode
- * \image html text-view/text-view-example-02.png
- *
- * This example wraps the lines by the next word when it exceeds the width of the text-view. If a word is bigger than the text-view's width, it splits the word. If the text exceeds the height of the text-view, the text is ellipsized.
- *
- * \code
- * const std::string text( "<font color='black'>"
- * "Loremipsumdolorsitametconsectetur adipisicing elit,\n"
- * "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
- * "</font>" );
- * const std::string ellipsizeText( "<font color='black'>...</font>" );
- *
- * Toolkit::TextView textView = Toolkit::TextView::New( "" );
- * textView.SetMarkupProcessingEnabled( true );
- * textView.SetText( text );
- * textView.SetEllipsizeText( ellipsizeText );
- * textView.SetParentOrigin( ParentOrigin::CENTER );
- * textView.SetSize( 300.f, 125.f );
- *
- * textView.SetMultilinePolicy( Toolkit::TextView::SplitByWord );
- * textView.SetWidthExceedPolicy( Toolkit::TextView::Split );
- * textView.SetHeightExceedPolicy( Toolkit::TextView::EllipsizeEnd );
- * textView.SetLineJustification( Toolkit::TextView::Center );
- *
- * Stage::GetCurrent().Add( textView );
- * \endcode
- * \image html text-view/text-view-example-03.png
- *
- * This example is similar to the one above but the ellipsized text has been set to "" so nothing is shown.
- *
- * \code
- * const std::string text( "<font color='black'>"
- * "Loremipsumdolorsitametconsecteturadipisicingelit"
- * "seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua."
- * "</font>" );
- * const std::string ellipsizeText( "" );
- *
- * Toolkit::TextView textView = Toolkit::TextView::New( "" );
- * textView.SetMarkupProcessingEnabled( true );
- * textView.SetText( text );
- * textView.SetEllipsizeText( ellipsizeText );
- * textView.SetParentOrigin( ParentOrigin::CENTER );
- * textView.SetSize( 300.f, 125.f );
- *
- * textView.SetMultilinePolicy( Toolkit::TextView::SplitByWord );
- * textView.SetWidthExceedPolicy( Toolkit::TextView::Split );
- * textView.SetHeightExceedPolicy( Toolkit::TextView::EllipsizeEnd );
- * textView.SetLineJustification( Toolkit::TextView::Center );
- *
- * Stage::GetCurrent().Add( textView );
- * \endcode
- * \image html text-view/text-view-example-04.png
- *
- * This example shows how to fade the text out when it exceeds the boundaries of the text-view.
- *
- * \code
- * const std::string text( "<font color='black'>"
- * "Lorem ipsum dolor sit amet,\n"
- * "consectetur adipisicing elit,\n"
- * "sed do eiusmod tempor incididunt\n"
- * "ut labore et dolore magna aliqua."
- * "</font>" );
- *
- * Toolkit::TextView textView = Toolkit::TextView::New();
- * textView.SetMarkupProcessingEnabled( true );
- * textView.SetText( text );
- * textView.SetParentOrigin( ParentOrigin::CENTER );
- * textView.SetSize( 300.f, 100.f );
- *
- * Toolkit::TextView::FadeBoundary fadeBoundary( PixelSize( 10 ), PixelSize( 10 ), PixelSize( 10 ), PixelSize( 10 ) );
- * textView.SetFadeBoundary( fadeBoundary );
- *
- * textView.SetMultilinePolicy( Toolkit::TextView::SplitByNewLineChar );
- * textView.SetWidthExceedPolicy( Toolkit::TextView::Fade );
- * textView.SetHeightExceedPolicy( Toolkit::TextView::Fade );
- * textView.SetLineJustification( Toolkit::TextView::Center );
- *
- * Stage::GetCurrent().Add( textView );
- * \endcode
- * \image html text-view/text-view-example-05.png
- *
- * This example enables the scroll feature. The screen-shots show three different images of the same text in different scroll positions.
- *
- * \code
- * const std::string text( "<font color='black'>"
- * "Lorem ipsum dolor sit amet, consectetur adipisicing elit,\n"
- * "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
- * "</font>" );
- *
- * Toolkit::TextView textView = Toolkit::TextView::New();
- * textView.SetMarkupProcessingEnabled( true );
- * textView.SetText( text );
- * textView.SetParentOrigin( ParentOrigin::CENTER );
- * textView.SetSize( 300.f, 60.f );
- *
- * textView.SetMultilinePolicy( Toolkit::TextView::SplitByNewLineChar );
- * textView.SetWidthExceedPolicy( Toolkit::TextView::Original );
- * textView.SetHeightExceedPolicy( Toolkit::TextView::Original );
- * textView.SetLineJustification( Toolkit::TextView::Center );
- *
- * textView.SetScrollEnabled( true );
- *
- * Stage::GetCurrent().Add( textView );
- * \endcode
- * \image html text-view/text-view-example-06.png
- * \image html text-view/text-view-example-07.png
- * \image html text-view/text-view-example-08.png
- *
- * See \link markup-processor Markup Processor \endlink \ref example for more styling markup string examples.
- *
- * \subsection exceed_policies_combinations Implemented exceed policies combinations
- *
- * The following tables show which exceed policies are implemented for each multi-line policy. Each column has one width exceed policy (Original, Fade, Split, ShrinkToFit and EllipsizeEnd),
- * each row has one height exceed policy (Original, Fade, ShrinkToFit and EllipsizeEnd).
- *
- * @note The Split value is not valid for the height exceed policy.
- *
- * \htmlonly
- * <table border="1" align="center">
- * <tr align="center">
- * <th align="center" colspan="7">SplitByNewLineChar</th>
- * </tr>
- * <tr align="center">
- * <th colspan="2" rowspan="2"></th><th align="center" colspan="6">Width exceed policies</th>
- * </tr>
- * <tr>
- * <th>Original</th><th>Fade</th><th>Split</th><th>ShrinkToFit</th><th>EllipsizeEnd</th>
- * </tr>
- * <tr align="center">
- * <th rowspan="4">Height<br />exceed<br />policies</th>
- * <th>Original</th>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * </tr>
- * <tr align="center">
- * <th>Fade</th>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * </tr>
- * <tr align="center">
- * <th>ShrinkToFit</th>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#A00>✗</font></td>
- * </tr>
- * <tr align="center">
- * <th>EllipsizeEnd</th>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#0A0>✓</font></td>
- * </tr>
- * </table>
- * \endhtmlonly
- *
- * \n
- *
- * \htmlonly
- * <table border="1" align="center">
- * <tr align="center">
- * <th align="center" colspan="7">SplitByWord</th>
- * </tr>
- * <tr align="center">
- * <th colspan="2" rowspan="2"></th><th align="center" colspan="6">Width exceed policies</th>
- * </tr>
- * <tr>
- * <th>Original</th><th>Fade</th><th>Split</th><th>ShrinkToFit</th><th>EllipsizeEnd</th>
- * </tr>
- * <tr align="center">
- * <th rowspan="4">Height<br />exceed<br />policies</th>
- * <th>Original</th>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * </tr>
- * <tr align="center">
- * <th>Fade</th>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * </tr>
- * <tr align="center">
- * <th>ShrinkToFit</th>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#A00>✗</font></td>
- * </tr>
- * <tr align="center">
- * <th>EllipsizeEnd</th>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#0A0>✓</font></td>
- * </tr>
- * </table>
- * \endhtmlonly
- *
- * \n
- *
- * \htmlonly
- * <table border="1" align="center">
- * <tr align="center">
- * <th align="center" colspan="7">SplitByChar</th>
- * </tr>
- * <tr align="center">
- * <th colspan="2" rowspan="2"></th><th align="center" colspan="6">Width exceed policies</th>
- * </tr>
- * <tr>
- * <th>Original</th><th>Fade</th><th>Split</th><th>ShrinkToFit</th><th>EllipsizeEnd</th>
- * </tr>
- * <tr align="center">
- * <th rowspan="4">Height<br />exceed<br />policies</th>
- * <th>Original</th>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * </tr>
- * <tr align="center">
- * <th>Fade</th>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#0A0>✓</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * </tr>
- * <tr align="center">
- * <th>ShrinkToFit</th>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * </tr>
- * <tr align="center">
- * <th>EllipsizeEnd</th>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * <td><font color=#A00>✗</font></td>
- * </tr>
- * </table>
- * \endhtmlonly
- */
-
Name: dali-toolkit
Summary: The OpenGLES Canvas Core Library Toolkit
-Version: 1.0.36
+Version: 1.0.37
Release: 1
Group: System/Libraries
License: Apache-2.0
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
$(v8_plugin_dir)/actors/actor-wrapper.cpp \
$(v8_plugin_dir)/actors/actor-api.cpp \
$(v8_plugin_dir)/actors/layer-api.cpp \
- $(v8_plugin_dir)/actors/text-actor-api.cpp \
$(v8_plugin_dir)/actors/image-actor-api.cpp \
$(v8_plugin_dir)/actors/camera-actor-api.cpp \
$(v8_plugin_dir)/actors/mesh-actor-api.cpp \
$(v8_plugin_dir)/actors/renderable-actor-api.cpp \
$(v8_plugin_dir)/constants/constants-wrapper.cpp \
- $(v8_plugin_dir)/text/font-api.cpp \
- $(v8_plugin_dir)/text/font-wrapper.cpp \
$(v8_plugin_dir)/animation/animation-api.cpp \
$(v8_plugin_dir)/animation/animation-wrapper.cpp \
$(v8_plugin_dir)/animation/path-api.cpp \
#include "actor-api.h"
// EXTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
// INTERNAL INCLUDES
#include <v8-utils.h>
} //unanmed namespace
-namespace TextViewApi
+namespace TextLabelApi
{
Actor New( const v8::FunctionCallbackInfo< v8::Value >& args )
{
- return Dali::Toolkit::TextView::New();
+ return Dali::Toolkit::TextLabel::New();
}
}
*
* @for Actor
* @method getActorType
- * @return {String} Actor, ImageActor, TextActor, MeshActor, Layer, CameraActor ...
+ * @return {String} Actor, ImageActor, MeshActor, Layer, CameraActor ...
*/
void ActorApi::GetActorType( const v8::FunctionCallbackInfo<v8::Value>& args )
{
namespace V8Plugin
{
-namespace TextViewApi
+namespace TextLabelApi
{
/**
* Temporary TextView constructor
#include <actors/layer-api.h>
#include <actors/actor-api.h>
#include <actors/image-actor-api.h>
-#include <actors/text-actor-api.h>
#include <actors/mesh-actor-api.h>
#include <actors/camera-actor-api.h>
#include <actors/renderable-actor-api.h>
v8::Persistent<v8::ObjectTemplate> ActorWrapper::mActorTemplate;
v8::Persistent<v8::ObjectTemplate> ActorWrapper::mImageActorTemplate;
-v8::Persistent<v8::ObjectTemplate> ActorWrapper::mTextActorTemplate;
v8::Persistent<v8::ObjectTemplate> ActorWrapper::mMeshActorTemplate;
v8::Persistent<v8::ObjectTemplate> ActorWrapper::mCameraActorTemplate;
v8::Persistent<v8::ObjectTemplate> ActorWrapper::mLayerActorTemplate;
-v8::Persistent<v8::ObjectTemplate> ActorWrapper::mTextViewTemplate;
+v8::Persistent<v8::ObjectTemplate> ActorWrapper::mTextLabelTemplate;
namespace
{
{
{ &ActorWrapper::mActorTemplate }, // ACTOR
{ &ActorWrapper::mImageActorTemplate }, // IMAGE_ACTOR
- { &ActorWrapper::mTextActorTemplate }, // TEXT_ACTOR
{ &ActorWrapper::mMeshActorTemplate }, // MESH_ACTOR
{ &ActorWrapper::mLayerActorTemplate }, // LAYER_ACTOR
{ &ActorWrapper::mCameraActorTemplate}, // CAMERA_ACTOR
- { &ActorWrapper::mTextViewTemplate }
+ { &ActorWrapper::mTextLabelTemplate }
};
/**
ACTOR_API = 1 << 0,
RENDERABLE_ACTOR_API = 1 << 1,
IMAGE_ACTOR_API = 1 << 2,
- TEXT_ACTOR_API = 1 << 3,
- MESH_ACTOR_API = 1 << 4,
- LAYER_API = 1 << 5,
- CAMERA_ACTOR_API = 1 << 6,
+ MESH_ACTOR_API = 1 << 3,
+ LAYER_API = 1 << 4,
+ CAMERA_ACTOR_API = 1 << 5,
};
/**
{
{"Actor", ActorWrapper::ACTOR, ActorApi::New, ACTOR_API },
{"ImageActor", ActorWrapper::IMAGE_ACTOR, ImageActorApi::New, ACTOR_API | RENDERABLE_ACTOR_API | IMAGE_ACTOR_API },
- {"TextActor", ActorWrapper::TEXT_ACTOR, TextActorApi::New, ACTOR_API | RENDERABLE_ACTOR_API | TEXT_ACTOR_API },
{"MeshActor", ActorWrapper::MESH_ACTOR, MeshActorApi::New, ACTOR_API | RENDERABLE_ACTOR_API | MESH_ACTOR_API },
{"Layer", ActorWrapper::LAYER_ACTOR, LayerApi::New, ACTOR_API | LAYER_API },
{"CameraActor",ActorWrapper::CAMERA_ACTOR, CameraActorApi::New, ACTOR_API | CAMERA_ACTOR_API },
- {"TextView", ActorWrapper::TEXT_VIEW, TextViewApi::New, ACTOR_API },
+ {"TextLabel", ActorWrapper::TEXT_LABEL, TextLabelApi::New, ACTOR_API },
};
else
{
// run the constructor for this type of actor so it can pull out
- // custom parameters, e.g. new TextActor("hello world"); or ImageActor( MyImage );
+ // custom parameters, e.g. new ImageActor( MyImage );
actor = (ActorApiLookup[actorType].constructor)( args );
}
return actor;
// ignore GetFadeInDuration use imageActor.fadeInDuration
//{ "GetCurrentImageSize", ImageActorApi::GetCurrentImageSize, IMAGE_ACTOR_API },
-
- /**************************************
- * Text Actor API (in order of text-actor.h)
- **************************************/
- //ignore SetText use textActor.text
- { "SetToNaturalSize", TextActorApi::SetToNaturalSize, TEXT_ACTOR_API },
- // ignore GetFont use textActor.font
- // ignore SetFont use textActor.font
- // ignore SetGradient use textActor.gradientColor
- // ignore GetGradient textActor.gradientColor
- // ignore SetGradientStartPoint use textActor.gradientStartPoint
- // ignore GetGradientStartPoint textActor.gradientStartPoint
- // ignore SetGradientEndPoint use textActor.gradientEndPoint
- // ignore GetGradientEndPoint textActor.gradientEndPoint
- // @todo? SetTextStyle ( can use individual properties as a work around )
- // @todo? GetTextStyle ( can use individual properties as a work around )
- // ignore SetTextColor use textActor.textColor
- // ignore GetTextColor use textActor.textColor
- // ignore SetSmoothEdge use textActor.smoothEdge
- // ignore SetOutline use textActor.outLineEnable, outlineColor, thicknessWidth
- // ignore SetGlow use textActor.glowEnable, glowColor, glowIntensity
- // ignore SetShadow use textActor.shadowEnable, shadowColor, shadowOffset, shadowSize
- // ignore SetItalics use textActor.italicsAngle ?
- // ignore GetItalics @todo add italics flag? or just stick with angle
- // ignore GetItalicsAngle use textActor.italicsAngle
- // ignore SetUnderline use textActor.underline
- // ignore GetUnderline use textActor.underline
- // ignore SetWeight use textActor.weight
- // ignore GetWeight use textActor.weight
- // ignore SetFontDetectionAutomatic use textActor.fontDetectionAutomatic
- // ignore IsFontDetectionAutomatic use textActor.fontDetectionAutomatic
- // ignore GetLoadingState text is loaded synchronously
- // ignore TextAvailableSignal text is loaded synchronously
-
/**************************************
* Mesh Actor API (in order of mesh-actor.h)
**************************************/
return;
}
- // find out the callee function name...e.g. TextActor, ImageActor, MeshActor
+ // find out the callee function name...e.g. ImageActor, MeshActor
v8::Local<v8::Function> callee = args.Callee();
v8::Local<v8::Value> v8String = callee->GetName();
std::string typeName = V8Utils::v8StringToStdString( v8String );
UNKNOWN_ACTOR = -1,
ACTOR = 0,
IMAGE_ACTOR =1,
- TEXT_ACTOR =2,
- MESH_ACTOR =3,
- LAYER_ACTOR =4,
- CAMERA_ACTOR =5,
- TEXT_VIEW =6
+ MESH_ACTOR =2,
+ LAYER_ACTOR =3,
+ CAMERA_ACTOR =4,
+ TEXT_LABEL =5
};
/**
// The Actor ObjectTemplates.
static v8::Persistent<v8::ObjectTemplate> mActorTemplate;
static v8::Persistent<v8::ObjectTemplate> mImageActorTemplate;
- static v8::Persistent<v8::ObjectTemplate> mTextActorTemplate;
static v8::Persistent<v8::ObjectTemplate> mMeshActorTemplate;
static v8::Persistent<v8::ObjectTemplate> mCameraActorTemplate;
static v8::Persistent<v8::ObjectTemplate> mLayerActorTemplate;
- static v8::Persistent<v8::ObjectTemplate> mTextViewTemplate;
+ static v8::Persistent<v8::ObjectTemplate> mTextLabelTemplate;
/**
* @return the wrapped actor
+++ /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 "text-actor-api.h"
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/text/text-actor-parameters.h>
-
-// INTERNAL INCLUDES
-#include <object/handle-wrapper.h>
-#include <v8-utils.h>
-#include <object/property-value-wrapper.h>
-#include <text/font-api.h>
-
-
-namespace Dali
-{
-
-namespace V8Plugin
-{
-
-namespace //unnamed name space
-{
-
-struct TextActorParametersInternal
-{
- TextActorParametersInternal()
- : fontDetection( true )
- {
- }
- bool fontDetection;
- Font font;
-};
-
-
-TextActor GetTextActor( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, args.This() );
- return TextActor::DownCast( handleWrapper->mHandle );
-}
-
-
-void GetTextOptions( v8::Isolate* isolate,
- v8::Local<v8::Value > options,
- TextActorParametersInternal& textParams )
-{
- // fontDetection: true / false ( default true)
- // font: dali font object
- v8::HandleScope handleScope( isolate );
-
- if( options->IsObject() )
- {
- v8::Local<v8::Object> obj = options->ToObject();
-
- v8::Local<v8::Value> fontDetect = obj->Get( v8::String::NewFromUtf8( isolate, "fontDetection" ) );
- if( fontDetect->IsBoolean() )
- {
-
- textParams.fontDetection = fontDetect->ToBoolean()->Value();
- }
-
- v8::Local<v8::Value> fontValue = obj->Get( v8::String::NewFromUtf8( isolate, "font" ) );
- if( fontValue->IsObject() )
- {
- textParams.font = FontApi::GetFont( isolate, fontValue );
- }
-
- }
-}
-
-}
-
-/**
- * @constructor
- * @for TextActor
- * @method TextActor
- * @param {String} text
- * @param {Object} [textOptions] data
- * Options text options struct
- * @param {Boolean} [textOptions.fontDetection]
- * if true the fontDetection is used to make sure the text is displayed.
- * E.g. if the current font used by the text-actor does not support certain characters
- * it will find a new font that does. Default = true.
- * @param {Object} [textOptions.font]
- * Dali font object
- * @return {Object} TextActor
- */
-Actor TextActorApi::New( const v8::FunctionCallbackInfo<v8::Value>& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
-
- //
- // TextActor( text, options (optional) )
- //
- // options =
- // {
- // font: font
- // fontDetection: true / false ( default true)
- // }
-
- // get the text (if passed in)
-
- bool found( false );
- std::string text = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
-
- TextActorParametersInternal params;
- TextActor actor;
-
- GetTextOptions( isolate, args[1], params );
-
- TextStyle style;
-
- if( params.font )
- {
- style.SetFontName( params.font.GetName() );
- style.SetFontStyle( params.font.GetStyle() );
- style.SetFontPointSize( PointSize(params.font.GetPointSize()));
-
- }
- TextActorParameters textActorParameters( style, params.fontDetection? TextActorParameters::FONT_DETECTION_OFF:TextActorParameters::FONT_DETECTION_ON );
-
- actor = TextActor::New( text, textActorParameters );
-
- return actor;
-
-}
-
-/**
- * Set text to the natural size of the text string.
- *
- * After this method the text actor always uses the natural size of the text
- * when SetText is called unless SetSize is called to override the size.
- *
- * @for TextActor
- * @method setToNaturalSize
- */
-void TextActorApi::SetToNaturalSize( const v8::FunctionCallbackInfo<v8::Value>& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
-
- TextActor textActor = GetTextActor( isolate, args );
- textActor.SetToNaturalSize();
-}
-
-} // namespace V8Plugin
-
-} // namespace Dali
#include <stage/stage-wrapper.h>
#include <image/image-attributes-wrapper.h>
#include <image/image-wrapper.h>
-#include <text/font-wrapper.h>
#include <animation/path-wrapper.h>
#include <animation/path-constraint-wrapper.h>
#include <animation/animation-wrapper.h>
{
{ "Rotation", PropertyValueWrapper::NewRotation},
{ "Matrix", PropertyValueWrapper::NewMatrix},
- { "Font", FontWrapper::NewFont },
{ "Path", PathWrapper::NewPath },
{ "PathConstraint", PathConstraintWrapper::NewPathConstraint },
{ "Actor", ActorWrapper::NewActor },
v8::Local<v8::Object> stageObject = StageWrapper::WrapStage( mIsolate, Stage::GetCurrent() );
daliObject->Set( v8::String::NewFromUtf8( mIsolate, "stage") , stageObject );
- // fontObject provides static font functionality like GetFontList...
- v8::Local<v8::Object> fontObject = FontWrapper::GetStaticFontObject( mIsolate );
- daliObject->Set( v8::String::NewFromUtf8( mIsolate, "font") , fontObject );
-
// keyboard focus manager is a singleton
v8::Local<v8::Object> keyboardObject = KeyboardFocusManagerWrapper::WrapKeyboardFocusManager( mIsolate,Toolkit::KeyboardFocusManager::Get() );
daliObject->Set( v8::String::NewFromUtf8( mIsolate, "keyboardFocusManager") , keyboardObject );
const GeometryTypePair GeometryTypeTable[]=
{
{"image", GEOMETRY_TYPE_IMAGE },
- {"text", GEOMETRY_TYPE_TEXT },
{"mesh", GEOMETRY_TYPE_UNTEXTURED_MESH },
{"textured-mesh", GEOMETRY_TYPE_TEXTURED_MESH },
};
+++ /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 "font-api.h"
-
-// INTERNAL INCLUDES
-#include <v8-utils.h>
-#include <text/font-wrapper.h>
-#include <object/property-value-wrapper.h>
-
-namespace Dali
-{
-
-namespace V8Plugin
-{
-
-namespace // un named namespace
-{
-
-
-
-
-} //un named namespace
-
-/***************************************
- * IMAGE FUNCTIONS
- *
- ****************************************/
-Font FontApi::GetFont( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::HandleScope handleScope( isolate );
-
- v8::Local<v8::Object> object = args.This();
- v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
- void* ptr = field->Value();
-
- FontWrapper* wrapper = static_cast< FontWrapper *>(ptr);
- return wrapper->GetFont();
-}
-Font FontApi::GetFont( v8::Isolate* isolate, v8::Local<v8::Value>& value )
-{
- v8::HandleScope handleScope( isolate );
- v8::Local<v8::Object> object = value->ToObject();
- v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
- void* ptr = field->Value();
-
- FontWrapper* wrapper = static_cast< FontWrapper *>(ptr);
- return wrapper->GetFont();
-}
-
-struct FontParams
-{
- typedef enum
- {
- NO_SIZE_SET,
- USE_POINT_SIZE,
- USE_PIXEL_SIZE,
- USE_CAP_SIZE,
- } SizeType;
-
-
- FontParams()
- :pointSize( 0 ),
- pixelSize( 0 ),
- capsSize( 0 ),
- sizeType( FontParams::NO_SIZE_SET )
- {
- }
-
- std::string family;
- std::string style;
- PointSize pointSize;
- PixelSize pixelSize;
- CapsHeight capsSize;
- SizeType sizeType;
-
-
-};
-
-
-void ReadFontParameters( v8::Isolate* isolate,
- v8::Local<v8::Value > options,
- FontParams& fontParams )
-{
- // foont options is an optional parameter passed in which holds
- // optional settings
- // var fontOptions = {
- // family: "arial",
- // style: "bold",
- // // one of the following
- // pixelSize: xx
- // pointSize: xx
- // capsHeight:xx // height of a capital letter above the baseline for a particular typeface.
- //
- // };
- v8::HandleScope handleScope( isolate );
- if( !options->IsObject() )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 ( font parameters)" );
- return;
- }
- v8::Local<v8::Object> obj = options->ToObject();
-
- v8::Local<v8::Value> familyValue = obj->Get( v8::String::NewFromUtf8( isolate, "family" ) );
- if( familyValue->IsString() )
- {
- fontParams.family = V8Utils::v8StringToStdString( familyValue );
- }
-
- v8::Local<v8::Value> styleValue = obj->Get( v8::String::NewFromUtf8( isolate, "style" ) );
- if( styleValue->IsString() )
- {
- fontParams.style = V8Utils::v8StringToStdString( styleValue );
- }
-
- v8::Local<v8::Value> pixelSize = obj->Get( v8::String::NewFromUtf8( isolate, "pixelSize" ) );
- v8::Local<v8::Value> pointSize = obj->Get( v8::String::NewFromUtf8( isolate, "pointSize" ) );
- v8::Local<v8::Value> capsHeight = obj->Get( v8::String::NewFromUtf8( isolate, "capsHeight" ) );
-
- if( pixelSize->IsUint32() )
- {
- fontParams.pixelSize.value = pixelSize->ToUint32()->Value();
- fontParams.sizeType = FontParams::USE_PIXEL_SIZE;
- }
- else if( pointSize->IsUint32() )
- {
- fontParams.pointSize.value = pointSize->ToUint32()->Value();
- fontParams.sizeType = FontParams::USE_POINT_SIZE;
- }
- else if( capsHeight->IsUint32() )
- {
- fontParams.capsSize.value = capsHeight->ToUint32()->Value();
- fontParams.sizeType = FontParams::USE_CAP_SIZE;
- }
-
-}
-
-Font FontApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
-
- // if no parameters just create a default font
- if ( args.Length() == 0)
- {
- return Font::New();
- }
- FontParams params;
-
- ReadFontParameters( isolate, args[0], params );
-
- FontParameters fontParams;
- // construct a dali font parameters object
- switch( params.sizeType)
- {
- case FontParams::USE_PIXEL_SIZE:
- {
- fontParams = FontParameters( params.family, params.style, params.pixelSize );
- break;
- }
- case FontParams::USE_POINT_SIZE:
- {
- fontParams = FontParameters( params.family, params.style, params.pointSize );
- break;
- }
- case FontParams::USE_CAP_SIZE:
- {
- fontParams = FontParameters( params.family, params.style, params.capsSize );
- break;
- }
- default:
- {
- fontParams = FontParameters( params.family, params.style, PointSize(0.f));
- break;
- }
- }
- return Font::New( fontParams );
-
-}
-
-
-void FontApi::GetFamilyForText( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
-
-
- bool foundString;
- std::string text = V8Utils::GetStringParameter( PARAMETER_0, foundString, isolate, args );
- if( !foundString )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 ( text )" );
- return;
- }
- std::string family = Font::GetFamilyForText( text );
-
- args.GetReturnValue().Set( v8::String::NewFromUtf8( isolate, family.c_str()) );
-
-}
-void FontApi::GetLineHeightFromCapsHeight( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
-
- FontParams params;
- ReadFontParameters( isolate, args[0], params );
- if( params.sizeType != FontParams::USE_CAP_SIZE )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "caps height not found" );
- return;
- }
-
- PixelSize size = Font::GetLineHeightFromCapsHeight( params.family, params.style, params.capsSize);
- args.GetReturnValue().Set( v8::Integer::New( isolate, size.value ) );
-}
-
-void FontApi::GetInstalledFonts( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
-
- bool found( false );
- std::vector<std::string> fontList;
-
- std::string mode = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
-
- if( mode == "LIST_APPLICATION_FONTS" )
- {
- fontList = Font::GetInstalledFonts( Font::LIST_APPLICATION_FONTS );
- }
- else if( mode == "LIST_ALL_FONTS")
- {
- fontList = Font::GetInstalledFonts( Font::LIST_ALL_FONTS );
- }
- else // default
- {
- fontList = Font::GetInstalledFonts( Font::LIST_SYSTEM_FONTS );
- }
- // create a javascript array
- v8::Local<v8::Array> array = v8::Array::New(isolate, fontList.size() );
- for( std::size_t i = 0; i < fontList.size(); i++)
- {
- const char* fontName = fontList[i].c_str();
- array->Set(v8::Integer::New(args.GetIsolate(), i), v8::String::NewFromUtf8( isolate,fontName));
- }
-
- args.GetReturnValue().Set( array );
-}
-
-void FontApi::MeasureTextWidth( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
- Font font = GetFont( isolate, args );
-
- //float MeasureTextWidth(const std::string& text, float textHeightPx) const;
-
- bool found( false );
- std::string text = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
- if(! found )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "text not found" );
- return;
- }
- int height = V8Utils::GetIntegerParameter( PARAMETER_1, found, isolate, args, 0 );
- if( !found )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "missing text height" );
- return;
- }
- float width = font.MeasureTextWidth( text, height );
-
- args.GetReturnValue().Set( v8::Integer::New( isolate, width ) );
-
-}
-void FontApi::MeasureTextHeight( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
- Font font = GetFont( isolate, args );
-
- //float MeasureTextHeight(const std::string& text, float textHeightPx) const;
-
- bool found( false );
- std::string text = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
- if(! found )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "text not found" );
- return;
- }
- int width= V8Utils::GetIntegerParameter( PARAMETER_1, found, isolate, args, 0 );
- if( !found )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "missing text height" );
- return;
- }
- float height = font.MeasureTextHeight( text, width );
-
- args.GetReturnValue().Set( v8::Integer::New( isolate, height ) );
-}
-void FontApi::MeasureText( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
- Font font = GetFont( isolate, args );
-
- bool found( false );
- std::string text = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
- if(! found )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "text not found" );
- return;
- }
-
- Vector3 vec3 = font.MeasureText( text );
- Dali::Property::Value value( vec3 );
- v8::Local <v8::Object> object = PropertyValueWrapper::WrapDaliProperty( isolate, value);
- args.GetReturnValue().Set( object );
-
-}
-void FontApi::AllGlyphsSupported( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
- Font font = GetFont( isolate, args );
-
- bool found( false );
- std::string text = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
- if(! found )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "text not found" );
- return;
- }
-
- bool supported = font.AllGlyphsSupported( text );
- args.GetReturnValue().Set( v8::Boolean::New( isolate, supported) );
-
-}
-
-// This one function is use to create a property map, instead of the many individual property
-// getters used by the C++ Dali API.
-// propertyMap
-// {
-// name:
-// style:
-// pointSize:
-// pixelSize:
-// lineHeight:
-// ascender:
-// underlineThickness:
-// underlinePosition:
-// isDefaultSystemFont:
-// isDefaultSystemSize:
-// }
-
-void FontApi::GetProperties( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
- Font font = GetFont( isolate, args );
-
- v8::Local<v8::Object> keyObject = v8::Object::New( isolate );
-
- keyObject->Set( v8::String::NewFromUtf8( isolate, "family" ), v8::String::NewFromUtf8( isolate, font.GetName().c_str() ) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "style" ), v8::String::NewFromUtf8( isolate, font.GetStyle().c_str() ) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "pointSize" ), v8::Integer::New( isolate, font.GetPointSize() ) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "pixelSize" ), v8::Integer::New( isolate, font.GetPixelSize() ) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "lineHeight" ), v8::Integer::New( isolate, font.GetLineHeight() ) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "ascender" ), v8::Integer::New( isolate, font.GetAscender() ) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "underlineThickness" ), v8::Integer::New( isolate, font.GetUnderlineThickness() ) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "underlinePosition" ), v8::Integer::New( isolate, font.GetUnderlinePosition()) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "isDefaultSystemFont" ), v8::Boolean::New( isolate, font.IsDefaultSystemFont() ) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "isDefaultSystemSize" ), v8::Boolean::New( isolate, font.IsDefaultSystemSize() ) );
-
- args.GetReturnValue().Set( keyObject );
-
-}
-
-void FontApi::GetMetrics( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
- Font font = GetFont( isolate, args );
-
- bool found( false );
- std::string text = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
-
- if(! found )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "character not found" );
- return;
- }
-
- Text textObject( text );
-
- Font::Metrics metric = font.GetMetrics( textObject[0] );
-
- v8::Local<v8::Object> keyObject = v8::Object::New( isolate );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "advance" ), v8::Integer::New( isolate, metric.GetAdvance() ) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "bearing" ), v8::Integer::New( isolate, metric.GetBearing() ) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "width" ), v8::Integer::New( isolate, metric.GetWidth() ) );
- keyObject->Set( v8::String::NewFromUtf8( isolate, "height" ), v8::Integer::New( isolate, metric.GetHeight() ) );
-
- args.GetReturnValue().Set( keyObject );
-
-}
-
-
-void FontApi::PointsToPixels( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
-
- bool found(false);
- int pointSize= V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
- if( !found )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "missing pointSize" );
- return;
- }
- args.GetReturnValue().Set( v8::Integer::New( isolate, Font::PointsToPixels(pointSize) ) );
-
-}
-void FontApi::PixelsToPoints( const v8::FunctionCallbackInfo< v8::Value >& args )
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
-
- bool found(false);
- int pixelSize= V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
- if( !found )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "missing pixelSize" );
- return;
- }
- args.GetReturnValue().Set( v8::Integer::New( isolate, Font::PixelsToPoints(pixelSize) ) );
-}
-
-
-
-} // namespace V8Plugin
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_V8PLUGIN_FONT_API_H__
-#define __DALI_V8PLUGIN_FONT_API_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 <v8.h>
-#include <dali/public-api/text/font.h>
-
-
-namespace Dali
-{
-
-namespace V8Plugin
-{
-
-namespace FontApi
-{
- Font GetFont( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args );
- Font GetFont( v8::Isolate* isolate, v8::Local<v8::Value>& value );
-
- Font GetFontFromParams( int paramIndex,
- bool& found,
- v8::Isolate* isolate,
- const v8::FunctionCallbackInfo< v8::Value >& args );
-
- /**
- * Constructor
- */
- Font New( const v8::FunctionCallbackInfo< v8::Value >& args );
-
- /**
- * Font API see image.h for a description
- */
- void GetFamilyForText( const v8::FunctionCallbackInfo< v8::Value >& args );
- void GetLineHeightFromCapsHeight( const v8::FunctionCallbackInfo< v8::Value >& args );
- void GetInstalledFonts( const v8::FunctionCallbackInfo< v8::Value >& args );
- void MeasureTextWidth( const v8::FunctionCallbackInfo< v8::Value >& args );
- void MeasureTextHeight( const v8::FunctionCallbackInfo< v8::Value >& args );
- void MeasureText( const v8::FunctionCallbackInfo< v8::Value >& args );
- void AllGlyphsSupported( const v8::FunctionCallbackInfo< v8::Value >& args );
- void GetProperties( const v8::FunctionCallbackInfo< v8::Value >& args );
- void GetMetrics( const v8::FunctionCallbackInfo< v8::Value >& args );
- void PointsToPixels( const v8::FunctionCallbackInfo< v8::Value >& args );
- void PixelsToPoints( const v8::FunctionCallbackInfo< v8::Value >& args );
-
-}; // namespace FontApi
-
-} // namespace V8Plugin
-
-} // namespace Dali
-
-#endif // header __DALI_V8PLUGIN_FONT_API_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 "font-wrapper.h"
-
-// INTERNAL INCLUDES
-#include <v8-utils.h>
-#include <dali-wrapper.h>
-#include <text/font-api.h>
-#include <shared/api-function.h>
-#include <shared/object-template-helper.h>
-
-namespace Dali
-{
-
-namespace V8Plugin
-{
-
-namespace // un-named name space
-{
-
-/**
- * Contains a list of all functions that can be called on the font object
- */
-const ApiFunction FontFunctionTable[]=
-{
- /**************************************
- * Font API (in order of font.h)
- **************************************/
- { "MeasureTextWidth", FontApi::MeasureTextWidth },
- { "MeasureTextHeight", FontApi::MeasureTextHeight },
- { "MeasureText", FontApi::MeasureText },
- { "AllGlyphsSupported", FontApi::AllGlyphsSupported },
- { "GetProperties", FontApi::GetProperties }, // replace all getters
- { "GetMetrics", FontApi::GetMetrics },
-};
-
-const unsigned int FontFunctionTableCount = sizeof(FontFunctionTable)/sizeof(FontFunctionTable[0]);
-
-/**
- * Contains a list of all functions that can be called
- */
-const ApiFunction StaticFontFunctionTable[]=
-{
- /**************************************
- * Static font functions, called without a font object
- **************************************/
- { "GetFamilyForText", FontApi::GetFamilyForText },
- { "GetLineHeightFromCapsHeight", FontApi::GetLineHeightFromCapsHeight },
- { "GetInstalledFonts", FontApi::GetInstalledFonts },
- { "PointsToPixels", FontApi::PointsToPixels },
- { "PixelsToPoints", FontApi::PixelsToPoints },
-};
-
-const unsigned int StaticFontFunctionTableCount = sizeof(StaticFontFunctionTable)/sizeof(FontFunctionTable[0]);
-
-} //un-named space
-
-
-FontWrapper::FontWrapper( const Dali::Font& font, GarbageCollectorInterface& gc )
-: BaseWrappedObject( BaseWrappedObject::FONT , gc )
-{
- mFont = font;
-}
-
-v8::Handle<v8::Object> FontWrapper::WrapFont(v8::Isolate* isolate, const Dali::Font& font )
-{
- v8::EscapableHandleScope handleScope( isolate );
- v8::Local<v8::ObjectTemplate> objectTemplate;
-
- objectTemplate = MakeFontTemplate( isolate );
-
- // create an instance of the template
- v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
-
- // create the Font wrapper
- FontWrapper* pointer = new FontWrapper( font, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
-
- // assign the JavaScript object to the wrapper.
- pointer->SetJavascriptObject( isolate, localObject );
-
- printf("Created Font!\n");
- return handleScope.Escape( localObject );
-}
-
-
-v8::Handle<v8::ObjectTemplate> FontWrapper::MakeFontTemplate( v8::Isolate* isolate )
-{
- v8::EscapableHandleScope handleScope( isolate );
-
- v8::Local<v8::ObjectTemplate> objTemplate = v8::ObjectTemplate::New();
-
- objTemplate->SetInternalFieldCount( BaseWrappedObject::FIELD_COUNT );
-
- // add our function properties
- ObjectTemplateHelper::InstallFunctions( isolate, objTemplate, FontFunctionTable, FontFunctionTableCount );
-
- return handleScope.Escape( objTemplate );
-}
-
-void FontWrapper::NewFont( const v8::FunctionCallbackInfo< v8::Value >& args)
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate);
-
- if(!args.IsConstructCall())
- {
- DALI_SCRIPT_EXCEPTION( isolate, "Font constructor called without 'new'");
- return;
- }
-
- // attribs can be passed by value
- Dali::Font font = FontApi::New( args );
- if( !font )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "bad font parameters\n");
- return;
- }
-
- v8::Local<v8::Object> localObject = WrapFont( isolate, font );
- args.GetReturnValue().Set( localObject );
-}
-
-Font FontWrapper::GetFont()
-{
- return mFont;
-}
-
-v8::Handle<v8::Object> FontWrapper::GetStaticFontObject(v8::Isolate* isolate)
-{
- v8::EscapableHandleScope handleScope( isolate );
-
- v8::Local<v8::ObjectTemplate> objTemplate = v8::ObjectTemplate::New();
-
- // add our functions properties
- ObjectTemplateHelper::InstallFunctions( isolate, objTemplate, StaticFontFunctionTable, StaticFontFunctionTableCount );
-
- v8::Local<v8::Object> localObject = objTemplate->NewInstance();
-
- return handleScope.Escape( localObject );
-
- }
-
-
-} // namespace V8Plugin
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_V8PLUGIN_FONT_WRAPPER_H__
-#define __DALI_V8PLUGIN_FONT_WRAPPER_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 <v8.h>
-#include <dali/public-api/text/font.h>
-
-// INTERNAL INCLUDES
-#include <shared/base-wrapped-object.h>
-
-namespace Dali
-{
-
-namespace V8Plugin
-{
-
-
-/**
- * An Font wrapper.
- * Provides access to Font specific functionality and V8 memory handling.
- */
-class FontWrapper : public BaseWrappedObject
-{
-
-public:
-
- FontWrapper( const Font& font,
- GarbageCollectorInterface& gc );
-
- virtual ~FontWrapper()
- {
- };
-
- /**
- * @brief Creates a new Font wrapped inside a Javascript Object.
- * @note: the actor type ie 'FontFont' is expected to be the name of the callee function.
- * @param[in] args v8 function call arguments interpreted
- */
- static void NewFont( const v8::FunctionCallbackInfo< v8::Value >& args);
-
- /**
- * Wraps a font
- */
- static v8::Handle<v8::Object> WrapFont(v8::Isolate* isolate, const Dali::Font& );
-
- Font GetFont();
-
- static v8::Handle<v8::Object> GetStaticFontObject(v8::Isolate* isolate);
-
-private:
-
- Font mFont;
- static v8::Handle<v8::ObjectTemplate> MakeFontTemplate( v8::Isolate* isolate );
-
-};
-
-} // namespace V8Plugin
-
-} // namespace Dali
-
-#endif // __DALI_V8PLUGIN_FONT_WRAPPER_H__
#include <actors/actor-wrapper.h>
#include <image/image-wrapper.h>
#include <animation/animation-wrapper.h>
-#include <text/font-wrapper.h>
#include <shader-effects/shader-effect-wrapper.h>
v8::Local<v8::Object> image = ImageWrapper::WrapImage(isolate, Image::DownCast(handle) );
args.GetReturnValue().Set( image );
}
- if( typeName == "Font ")
- {
- v8::Local<v8::Object> font = FontWrapper::WrapFont(isolate, Font::DownCast(handle) );
- args.GetReturnValue().Set( font );
- }
if( typeName == "Shader")
{
v8::Local<v8::Object> shader = ShaderEffectWrapper::WrapShaderEffect(isolate, ShaderEffect::DownCast( handle ));