X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=automated-tests%2Fsrc%2Fdali-toolkit%2Futc-Dali-TextEditor.cpp;h=c1435108eaa7312b2895cd41e2648bbe25d6fc99;hp=a361701f47e87d6d9d4c005df487fb58c64fc641;hb=6a9bd26564f5c34ba105b04cec4111523d294bec;hpb=42492df08f8a079da70931292aebb56e1252641d diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp index a361701..c143510 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -17,11 +17,17 @@ #include #include -#include +#include +#include +#include #include +#include #include +#include #include #include +#include +#include using namespace Dali; using namespace Toolkit; @@ -81,18 +87,57 @@ const char* const PROPERTY_NAME_INPUT_EMBOSS = "inputEmb const char* const PROPERTY_NAME_OUTLINE = "outline"; const char* const PROPERTY_NAME_INPUT_OUTLINE = "inputOutline"; +const char* const PROPERTY_NAME_SMOOTH_SCROLL = "smoothScroll"; +const char* const PROPERTY_NAME_SMOOTH_SCROLL_DURATION = "smoothScrollDuration"; +const char* const PROPERTY_NAME_ENABLE_SCROLL_BAR = "enableScrollBar"; +const char* const PROPERTY_NAME_SCROLL_BAR_SHOW_DURATION = "scrollBarShowDuration"; +const char* const PROPERTY_NAME_SCROLL_BAR_FADE_DURATION = "scrollBarFadeDuration"; +const char* const PROPERTY_NAME_PIXEL_SIZE = "pixelSize"; +const char* const PROPERTY_NAME_LINE_COUNT = "lineCount"; +const char* const PROPERTY_NAME_PLACEHOLDER_TEXT = "placeholderText"; +const char* const PROPERTY_NAME_PLACEHOLDER_TEXT_COLOR = "placeholderTextColor"; + const int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND; +const Vector4 PLACEHOLDER_TEXT_COLOR( 0.8f, 0.8f, 0.8f, 0.8f ); const Dali::Vector4 LIGHT_BLUE( 0.75f, 0.96f, 1.f, 1.f ); // The text highlight color. const unsigned int CURSOR_BLINK_INTERVAL = 500u; // Cursor blink interval const float TO_MILLISECONDS = 1000.f; const float TO_SECONDS = 1.f / TO_MILLISECONDS; +const float RENDER_FRAME_INTERVAL = 16.66f; const float SCROLL_THRESHOLD = 10.f; const float SCROLL_SPEED = 300.f; +const unsigned int DEFAULT_FONT_SIZE = 1152u; +const std::string DEFAULT_FONT_DIR( "/resources/fonts" ); + +const int KEY_A_CODE = 38; +const int KEY_D_CODE = 40; +const int KEY_WHITE_SPACE_CODE = 65; + +const char* HANDLE_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/insertpoint-icon.png"; + +const std::string DEFAULT_DEVICE_NAME("hwKeyboard"); + static bool gTextChangedCallBackCalled; +static bool gInputStyleChangedCallbackCalled; +static Dali::Toolkit::TextEditor::InputStyle::Mask gInputStyleMask; + +struct CallbackFunctor +{ + CallbackFunctor(bool* callbackFlag) + : mCallbackFlag( callbackFlag ) + { + } + + void operator()() + { + *mCallbackFlag = true; + } + bool* mCallbackFlag; +}; static void TestTextChangedCallback( TextEditor control ) { @@ -101,6 +146,14 @@ static void TestTextChangedCallback( TextEditor control ) gTextChangedCallBackCalled = true; } +static void TestInputStyleChangedCallback( TextEditor control, TextEditor::InputStyle::Mask mask ) +{ + tet_infoline(" TestInputStyleChangedCallback"); + + gInputStyleChangedCallbackCalled = true; + gInputStyleMask = mask; +} + // Generate a TapGestureEvent to send to Core. Integration::TapGestureEvent GenerateTap( Gesture::State state, @@ -117,22 +170,159 @@ Integration::TapGestureEvent GenerateTap( return tap; } +// Generate a PanGestureEvent to send to Core +Integration::PanGestureEvent GeneratePan( Gesture::State state, + const Vector2& previousPosition, + const Vector2& currentPosition, + unsigned long timeDelta, + unsigned int numberOfTouches = 1u ) +{ + Integration::PanGestureEvent pan(state); + + pan.previousPosition = previousPosition; + pan.currentPosition = currentPosition; + pan.timeDelta = timeDelta; + pan.numberOfTouches = numberOfTouches; + + return pan; +} + // Generate a KeyEvent to send to Core. Integration::KeyEvent GenerateKey( const std::string& keyName, const std::string& keyString, int keyCode, int keyModifier, unsigned long timeStamp, - const Integration::KeyEvent::State& keyState ) + const Integration::KeyEvent::State& keyState, + const std::string& deviceName, + const DevelKeyEvent::DeviceClass::Type& deviceClass ) { return Integration::KeyEvent( keyName, keyString, keyCode, keyModifier, timeStamp, - keyState ); + keyState, + deviceName, + deviceClass ); +} + +/** + * Helper to generate PanGestureEvent + * + * @param[in] application Application instance + * @param[in] state The Gesture State + * @param[in] pos The current position of touch. + */ +static void SendPan(ToolkitTestApplication& application, Gesture::State state, const Vector2& pos) +{ + static Vector2 last; + + if( (state == Gesture::Started) || + (state == Gesture::Possible) ) + { + last.x = pos.x; + last.y = pos.y; + } + + application.ProcessEvent( GeneratePan( state, last, pos, 16 ) ); + + last.x = pos.x; + last.y = pos.y; +} + +/* + * Simulate time passed by. + * + * @note this will always process at least 1 frame (1/60 sec) + * + * @param application Test application instance + * @param duration Time to pass in milliseconds. + * @return The actual time passed in milliseconds + */ +static int Wait(ToolkitTestApplication& application, int duration = 0) +{ + int time = 0; + + for(int i = 0; i <= ( duration / RENDER_FRAME_INTERVAL); i++) + { + application.SendNotification(); + application.Render(RENDER_FRAME_INTERVAL); + time += RENDER_FRAME_INTERVAL; + } + + return time; +} + +Dali::Integration::Point GetPointDownInside( Vector2& pos ) +{ + Dali::Integration::Point point; + point.SetState( PointState::DOWN ); + point.SetScreenPosition( pos ); + return point; +} + +Dali::Integration::Point GetPointUpInside( Vector2& pos ) +{ + Dali::Integration::Point point; + point.SetState( PointState::UP ); + point.SetScreenPosition( pos ); + return point; +} + +bool DaliTestCheckMaps( const Property::Map& fontStyleMapGet, const Property::Map& fontStyleMapSet ) +{ + if( fontStyleMapGet.Count() == fontStyleMapSet.Count() ) + { + for( unsigned int index = 0u; index < fontStyleMapGet.Count(); ++index ) + { + const KeyValuePair& valueGet = fontStyleMapGet.GetKeyValue( index ); + + Property::Value* valueSet = fontStyleMapSet.Find( valueGet.first.stringKey ); + if( NULL != valueSet ) + { + if( valueGet.second.Get() != valueSet->Get() ) + { + tet_printf( " Value got : [%s], expected : [%s]", valueGet.second.Get().c_str(), valueSet->Get().c_str() ); + return false; + } + } + else + { + tet_printf( " The key %s doesn't exist.", valueGet.first.stringKey.c_str() ); + return false; + } + } + } + + return true; } +class ScrollStateChangeCallback : public Dali::ConnectionTracker +{ +public: + ScrollStateChangeCallback(bool& startedCalled, bool& finishedCalled) + : mStartedCalled( startedCalled ), + mFinishedCalled( finishedCalled ) + { + } + + void Callback( TextEditor editor, DevelTextEditor::Scroll::Type type ) + { + if( type == DevelTextEditor::Scroll::STARTED ) + { + mStartedCalled = true; + } + else if( type == DevelTextEditor::Scroll::FINISHED ) + { + mFinishedCalled = true; + } + } + + bool& mStartedCalled; + bool& mFinishedCalled; +}; + } // namespace int UtcDaliToolkitTextEditorConstructorP(void) @@ -266,6 +456,15 @@ int UtcDaliTextEditorGetPropertyP(void) DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_EMBOSS ) == TextEditor::Property::INPUT_EMBOSS ); DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_OUTLINE ) == TextEditor::Property::OUTLINE ); DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_OUTLINE ) == TextEditor::Property::INPUT_OUTLINE ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SMOOTH_SCROLL ) == DevelTextEditor::Property::SMOOTH_SCROLL ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SMOOTH_SCROLL_DURATION ) == DevelTextEditor::Property::SMOOTH_SCROLL_DURATION ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_SCROLL_BAR ) == DevelTextEditor::Property::ENABLE_SCROLL_BAR ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SCROLL_BAR_SHOW_DURATION ) == DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SCROLL_BAR_FADE_DURATION ) == DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_PIXEL_SIZE ) == DevelTextEditor::Property::PIXEL_SIZE ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_LINE_COUNT) == DevelTextEditor::Property::LINE_COUNT ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT ) == DevelTextEditor::Property::PLACEHOLDER_TEXT ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT_COLOR ) == DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR ); END_TEST; } @@ -314,11 +513,56 @@ int UtcDaliTextEditorSetPropertyP(void) // Check font properties. editor.SetProperty( TextEditor::Property::FONT_FAMILY, "Setting font family" ); DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::FONT_FAMILY ), std::string("Setting font family"), TEST_LOCATION ); - editor.SetProperty( TextEditor::Property::FONT_STYLE, "Setting font style" ); - DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::FONT_STYLE ), std::string("Setting font style"), TEST_LOCATION ); + + Property::Map fontStyleMapSet; + Property::Map fontStyleMapGet; + Property::Value* slantValue = NULL; + + fontStyleMapSet.Insert( "weight", "bold" ); + fontStyleMapSet.Insert( "width", "condensed" ); + fontStyleMapSet.Insert( "slant", "italic" ); + + editor.SetProperty( TextEditor::Property::FONT_STYLE, fontStyleMapSet ); + fontStyleMapGet = editor.GetProperty( TextEditor::Property::FONT_STYLE ); + DALI_TEST_EQUALS( fontStyleMapGet.Count(), fontStyleMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( fontStyleMapGet, fontStyleMapSet ), true, TEST_LOCATION ); + editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f ); DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::POINT_SIZE ), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + // Reset font style. + fontStyleMapSet.Clear(); + fontStyleMapSet.Insert( "weight", "normal" ); + fontStyleMapSet.Insert( "slant", "oblique" ); + editor.SetProperty( TextEditor::Property::FONT_STYLE, fontStyleMapSet ); + fontStyleMapGet = editor.GetProperty( TextEditor::Property::FONT_STYLE ); + DALI_TEST_EQUALS( fontStyleMapGet.Count(), fontStyleMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( fontStyleMapGet, fontStyleMapSet ), true, TEST_LOCATION ); + + fontStyleMapSet.Clear(); + fontStyleMapSet.Insert( "slant", "roman" ); + editor.SetProperty( TextEditor::Property::FONT_STYLE, fontStyleMapSet ); + fontStyleMapGet = editor.GetProperty( TextEditor::Property::FONT_STYLE ); + + // Replace 'roman' for 'normal'. + slantValue = fontStyleMapGet.Find( "slant" ); + if( NULL != slantValue ) + { + if( "normal" == slantValue->Get() ) + { + fontStyleMapGet["slant"] = "roman"; + } + } + DALI_TEST_EQUALS( fontStyleMapGet.Count(), fontStyleMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( fontStyleMapGet, fontStyleMapSet ), true, TEST_LOCATION ); + + fontStyleMapSet.Clear(); + + editor.SetProperty( TextEditor::Property::FONT_STYLE, fontStyleMapSet ); + fontStyleMapGet = editor.GetProperty( TextEditor::Property::FONT_STYLE ); + DALI_TEST_EQUALS( fontStyleMapGet.Count(), fontStyleMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( fontStyleMapGet, fontStyleMapSet ), true, TEST_LOCATION ); + // Check that the Alignment properties can be correctly set editor.SetProperty( TextEditor::Property::HORIZONTAL_ALIGNMENT, "END" ); DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::HORIZONTAL_ALIGNMENT ), "END", TEST_LOCATION ); @@ -379,11 +623,55 @@ int UtcDaliTextEditorSetPropertyP(void) // Check input font properties. editor.SetProperty( TextEditor::Property::INPUT_FONT_FAMILY, "Setting input font family" ); DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::INPUT_FONT_FAMILY ), "Setting input font family", TEST_LOCATION ); - editor.SetProperty( TextEditor::Property::INPUT_FONT_STYLE, "Setting input font style" ); - DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::INPUT_FONT_STYLE ), "Setting input font style", TEST_LOCATION ); + + fontStyleMapSet.Clear(); + fontStyleMapSet.Insert( "weight", "bold" ); + fontStyleMapSet.Insert( "width", "condensed" ); + fontStyleMapSet.Insert( "slant", "italic" ); + + editor.SetProperty( TextEditor::Property::INPUT_FONT_STYLE, fontStyleMapSet ); + fontStyleMapGet = editor.GetProperty( TextEditor::Property::INPUT_FONT_STYLE ); + DALI_TEST_EQUALS( fontStyleMapGet.Count(), fontStyleMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( fontStyleMapGet, fontStyleMapSet ), true, TEST_LOCATION ); + editor.SetProperty( TextEditor::Property::INPUT_POINT_SIZE, 12.f ); DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::INPUT_POINT_SIZE ), 12.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + // Reset input font style. + fontStyleMapSet.Clear(); + fontStyleMapSet.Insert( "weight", "normal" ); + fontStyleMapSet.Insert( "slant", "oblique" ); + + editor.SetProperty( TextEditor::Property::INPUT_FONT_STYLE, fontStyleMapSet ); + fontStyleMapGet = editor.GetProperty( TextEditor::Property::INPUT_FONT_STYLE ); + DALI_TEST_EQUALS( fontStyleMapGet.Count(), fontStyleMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( fontStyleMapGet, fontStyleMapSet ), true, TEST_LOCATION ); + + fontStyleMapSet.Clear(); + fontStyleMapSet.Insert( "slant", "roman" ); + + editor.SetProperty( TextEditor::Property::INPUT_FONT_STYLE, fontStyleMapSet ); + fontStyleMapGet = editor.GetProperty( TextEditor::Property::INPUT_FONT_STYLE ); + + // Replace 'roman' for 'normal'. + slantValue = fontStyleMapGet.Find( "slant" ); + if( NULL != slantValue ) + { + if( "normal" == slantValue->Get() ) + { + fontStyleMapGet["slant"] = "roman"; + } + } + DALI_TEST_EQUALS( fontStyleMapGet.Count(), fontStyleMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( fontStyleMapGet, fontStyleMapSet ), true, TEST_LOCATION ); + + fontStyleMapSet.Clear(); + + editor.SetProperty( TextEditor::Property::INPUT_FONT_STYLE, fontStyleMapSet ); + fontStyleMapGet = editor.GetProperty( TextEditor::Property::INPUT_FONT_STYLE ); + DALI_TEST_EQUALS( fontStyleMapGet.Count(), fontStyleMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( fontStyleMapGet, fontStyleMapSet ), true, TEST_LOCATION ); + // Check the line spacing property DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::LINE_SPACING ), 0.0f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); editor.SetProperty( TextEditor::Property::LINE_SPACING, 10.f ); @@ -395,16 +683,36 @@ int UtcDaliTextEditorSetPropertyP(void) DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::INPUT_LINE_SPACING ), 20.0f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); // Check the underline property - editor.SetProperty( TextEditor::Property::UNDERLINE, "Underline properties" ); - DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::UNDERLINE ), std::string("Underline properties"), TEST_LOCATION ); + + Property::Map underlineMapSet; + Property::Map underlineMapGet; + + underlineMapSet.Insert( "enable", "true" ); + underlineMapSet.Insert( "color", "red" ); + underlineMapSet.Insert( "height", "1" ); + + editor.SetProperty( TextEditor::Property::UNDERLINE, underlineMapSet ); + + underlineMapGet = editor.GetProperty( TextEditor::Property::UNDERLINE ); + DALI_TEST_EQUALS( underlineMapGet.Count(), underlineMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( underlineMapGet, underlineMapSet ), true, TEST_LOCATION ); // Check the input underline property editor.SetProperty( TextEditor::Property::INPUT_UNDERLINE, "Underline input properties" ); DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::INPUT_UNDERLINE ), std::string("Underline input properties"), TEST_LOCATION ); // Check the shadow property - editor.SetProperty( TextEditor::Property::SHADOW, "Shadow properties" ); - DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::SHADOW ), std::string("Shadow properties"), TEST_LOCATION ); + Property::Map shadowMapSet; + Property::Map shadowMapGet; + + shadowMapSet.Insert( "color", "green" ); + shadowMapSet.Insert( "offset", "2 2" ); + + editor.SetProperty( TextEditor::Property::SHADOW, shadowMapSet ); + + shadowMapGet = editor.GetProperty( TextEditor::Property::SHADOW ); + DALI_TEST_EQUALS( shadowMapGet.Count(), shadowMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( shadowMapGet, shadowMapSet ), true, TEST_LOCATION ); // Check the input shadow property editor.SetProperty( TextEditor::Property::INPUT_SHADOW, "Shadow input properties" ); @@ -426,6 +734,43 @@ int UtcDaliTextEditorSetPropertyP(void) editor.SetProperty( TextEditor::Property::INPUT_OUTLINE, "Outline input properties" ); DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::INPUT_OUTLINE ), std::string("Outline input properties"), TEST_LOCATION ); + // Check the smooth scroll property + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SMOOTH_SCROLL ), false, TEST_LOCATION ); + editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL, true ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SMOOTH_SCROLL ), true, TEST_LOCATION ); + + // Check the smooth scroll duration property + editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL_DURATION, 0.2f ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SMOOTH_SCROLL_DURATION ), 0.2f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + + // Check the scroll bar property + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::ENABLE_SCROLL_BAR ), false, TEST_LOCATION ); + editor.SetProperty( DevelTextEditor::Property::ENABLE_SCROLL_BAR, true ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::ENABLE_SCROLL_BAR ), true, TEST_LOCATION ); + + editor.SetProperty( DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION, 0.3f ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION ), 0.3f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + editor.SetProperty( DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION, 0.2f ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION ), 0.2f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + + // Check the pixel size of font + editor.SetProperty( DevelTextEditor::Property::PIXEL_SIZE, 20.f ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::PIXEL_SIZE ), 20.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + + // Check placeholder text properties. + editor.SetProperty( DevelTextEditor::Property::PLACEHOLDER_TEXT, "Setting Placeholder Text" ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::PLACEHOLDER_TEXT ), std::string("Setting Placeholder Text"), TEST_LOCATION ); + + // Check placeholder text properties when focused. + editor.SetProperty( DevelControl::Property::STATE, "FOCUSED" ); + editor.SetProperty( DevelTextEditor::Property::PLACEHOLDER_TEXT, "Setting Focused Placeholder Text" ); + DALI_TEST_EQUALS( editor.GetProperty( DevelControl::Property::STATE ), (int)DevelControl::FOCUSED, TEST_LOCATION ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::PLACEHOLDER_TEXT ), std::string("Setting Focused Placeholder Text"), TEST_LOCATION ); + + // Check placeholder text's color property. + editor.SetProperty( DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR, Color::RED ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR ), Color::RED, TEST_LOCATION ); + END_TEST; } @@ -469,257 +814,738 @@ int utcDaliTextEditorTextChangedP(void) Stage::GetCurrent().Add( editor ); - editor.TextChangedSignal().Connect(&TestTextChangedCallback); + // connect to the text changed signal. + ConnectionTracker* testTracker = new ConnectionTracker(); + editor.TextChangedSignal().Connect( &TestTextChangedCallback ); + bool textChangedSignal = false; + editor.ConnectSignal( testTracker, "textChanged", CallbackFunctor(&textChangedSignal) ); gTextChangedCallBackCalled = false; editor.SetProperty( TextEditor::Property::TEXT, "ABC" ); DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_CHECK( textChangedSignal ); application.SendNotification(); editor.SetKeyInputFocus(); gTextChangedCallBackCalled = false; - application.ProcessEvent( GenerateKey( "D", "D", 0, 0, 0, Integration::KeyEvent::Down ) ); + application.ProcessEvent( GenerateKey( "D", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); DALI_TEST_CHECK( gTextChangedCallBackCalled ); END_TEST; } -int utcDaliTextEditorEvent01(void) +int utcDaliTextEditorInputStyleChanged01(void) { ToolkitTestApplication application; - tet_infoline(" utcDaliTextEditorEvent01"); + tet_infoline(" utcDaliTextEditorInputStyleChanged01"); - // Creates a tap event. After creating a tap event the text editor should - // have the focus and add text with key events should be possible. + // The text-editor emits signals when the input style changes. These changes of style are + // detected during the relayout process (size negotiation), i.e after the cursor has been moved. Signals + // can't be emitted during the size negotiation as the callbacks may update the UI. + // The text-editor adds an idle callback to the adaptor to emit the signals after the size negotiation. + // This creates an implementation of the adaptor stub and a queue of idle callbacks. + application.CreateAdaptor(); + + // Load some fonts. + + char* pathNamePtr = get_current_dir_name(); + const std::string pathName( pathNamePtr ); + free( pathNamePtr ); + + TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); + fontClient.SetDpi( 93u, 93u ); + + fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif.ttf", DEFAULT_FONT_SIZE ); + fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif-Bold.ttf", DEFAULT_FONT_SIZE ); TextEditor editor = TextEditor::New(); DALI_TEST_CHECK( editor ); - Stage::GetCurrent().Add( editor ); editor.SetSize( 300.f, 50.f ); editor.SetParentOrigin( ParentOrigin::TOP_LEFT ); editor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - // Avoid a crash when core load gl resources. - application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); + editor.SetProperty( TextEditor::Property::ENABLE_MARKUP, true ); + editor.SetProperty( TextEditor::Property::TEXT, "Hello world demo" ); + + // connect to the text changed signal. + ConnectionTracker* testTracker = new ConnectionTracker(); + editor.InputStyleChangedSignal().Connect( &TestInputStyleChangedCallback ); + bool inputStyleChangedSignal = false; + editor.ConnectSignal( testTracker, "inputStyleChanged", CallbackFunctor(&inputStyleChangedSignal) ); + + Stage::GetCurrent().Add( editor ); // Render and notify application.SendNotification(); application.Render(); - // Add a key event but as the text editor has not the focus it should do nothing. - application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) ); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); + + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; + + // Create a tap event to touch the text editor. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 18.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 18.f, 25.f ) ) ); // Render and notify application.SendNotification(); application.Render(); - DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string(""), TEST_LOCATION ); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); + + DALI_TEST_CHECK( gInputStyleChangedCallbackCalled ); + if( gInputStyleChangedCallbackCalled ) + { + DALI_TEST_EQUALS( static_cast( gInputStyleMask ), static_cast( TextEditor::InputStyle::FONT_FAMILY | TextEditor::InputStyle::POINT_SIZE ), TEST_LOCATION ); + + const std::string fontFamily = editor.GetProperty( TextEditor::Property::INPUT_FONT_FAMILY ).Get(); + DALI_TEST_EQUALS( fontFamily, "DejaVuSerif", TEST_LOCATION ); + + const float pointSize = editor.GetProperty( TextEditor::Property::INPUT_POINT_SIZE ).Get(); + DALI_TEST_EQUALS( pointSize, 18.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + } + DALI_TEST_CHECK( inputStyleChangedSignal ); + + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; // Create a tap event to touch the text editor. - application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) ); - application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 30.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 30.f, 25.f ) ) ); // Render and notify application.SendNotification(); application.Render(); - // Now the text editor has the focus, so it can handle the key events. - application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) ); - application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) ); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); + + DALI_TEST_CHECK( !gInputStyleChangedCallbackCalled ); + DALI_TEST_CHECK( !inputStyleChangedSignal ); + + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; + + // Create a tap event to touch the text editor. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 43.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 43.f, 25.f ) ) ); // Render and notify application.SendNotification(); application.Render(); - DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string("aa"), TEST_LOCATION ); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); - // Create a second text editor and send key events to it. - TextEditor editor2 = TextEditor::New(); + DALI_TEST_CHECK( gInputStyleChangedCallbackCalled ); + if( gInputStyleChangedCallbackCalled ) + { + DALI_TEST_EQUALS( static_cast( gInputStyleMask ), static_cast( TextEditor::InputStyle::COLOR ), TEST_LOCATION ); - editor2.SetParentOrigin( ParentOrigin::TOP_LEFT ); - editor2.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - editor2.SetSize( 100.f, 100.f ); - editor2.SetPosition( 100.f, 100.f ); + const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get(); + DALI_TEST_EQUALS( color, Color::GREEN, TEST_LOCATION ); + } + DALI_TEST_CHECK( inputStyleChangedSignal ); - Stage::GetCurrent().Add( editor2 ); + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; + + // Create a tap event to touch the text editor. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 88.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 88.f, 25.f ) ) ); // Render and notify application.SendNotification(); application.Render(); - // Create a tap event on the second text editor. - application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 125.0f ) ) ); - application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 125.0f ) ) ); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); + + DALI_TEST_CHECK( gInputStyleChangedCallbackCalled ); + if( gInputStyleChangedCallbackCalled ) + { + DALI_TEST_EQUALS( static_cast( gInputStyleMask ), static_cast( TextEditor::InputStyle::COLOR | TextEditor::InputStyle::FONT_STYLE ), TEST_LOCATION ); + + const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get(); + DALI_TEST_EQUALS( color, Color::BLACK, TEST_LOCATION ); + + Property::Map fontStyleMapSet; + Property::Map fontStyleMapGet; + + fontStyleMapSet.Insert( "weight", "bold" ); + + fontStyleMapGet = editor.GetProperty( TextEditor::Property::INPUT_FONT_STYLE ); + DALI_TEST_EQUALS( fontStyleMapGet.Count(), fontStyleMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( fontStyleMapGet, fontStyleMapSet ), true, TEST_LOCATION ); + } + DALI_TEST_CHECK( inputStyleChangedSignal ); + + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; + + // Create a tap event to touch the text editor. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 115.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 115.f, 25.f ) ) ); // Render and notify application.SendNotification(); application.Render(); - // The second text editor has the focus. It should handle the key events. - application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) ); - application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) ); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); + + DALI_TEST_CHECK( !gInputStyleChangedCallbackCalled ); + DALI_TEST_CHECK( !inputStyleChangedSignal ); + + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; + + // Create a tap event to touch the text editor. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 164.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 164.f, 25.f ) ) ); // Render and notify application.SendNotification(); application.Render(); - // Check the text has been added to the second text editor. - DALI_TEST_EQUALS( editor2.GetProperty( TextEditor::Property::TEXT ), std::string("aa"), TEST_LOCATION ); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); + + DALI_TEST_CHECK( gInputStyleChangedCallbackCalled ); + if( gInputStyleChangedCallbackCalled ) + { + DALI_TEST_EQUALS( static_cast( gInputStyleMask ), static_cast( TextEditor::InputStyle::FONT_STYLE ), TEST_LOCATION ); + + Property::Map fontStyleMapSet; + Property::Map fontStyleMapGet; + + fontStyleMapGet = editor.GetProperty( TextEditor::Property::INPUT_FONT_STYLE ); + DALI_TEST_EQUALS( fontStyleMapGet.Count(), fontStyleMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( fontStyleMapGet, fontStyleMapSet ), true, TEST_LOCATION ); + } + DALI_TEST_CHECK( inputStyleChangedSignal ); + + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; + + // Create a tap event to touch the text editor. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 191.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 191.f, 25.f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); + + DALI_TEST_CHECK( !gInputStyleChangedCallbackCalled ); + DALI_TEST_CHECK( !inputStyleChangedSignal ); END_TEST; } -int utcDaliTextEditorEvent02(void) +int utcDaliTextEditorInputStyleChanged02(void) { ToolkitTestApplication application; - tet_infoline(" utcDaliTextEditorEvent02"); + tet_infoline(" utcDaliTextEditorInputStyleChanged02"); - // Checks if the right number of actors are created. + // The text-editor emits signals when the input style changes. These changes of style are + // detected during the relayout process (size negotiation), i.e after the cursor has been moved. Signals + // can't be emitted during the size negotiation as the callbacks may update the UI. + // The text-editor adds an idle callback to the adaptor to emit the signals after the size negotiation. + // This creates an implementation of the adaptor stub and a queue of idle callbacks. + application.CreateAdaptor(); + + // Load some fonts. + + char* pathNamePtr = get_current_dir_name(); + const std::string pathName( pathNamePtr ); + free( pathNamePtr ); + + TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); + fontClient.SetDpi( 93u, 93u ); + + fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif.ttf", DEFAULT_FONT_SIZE ); + fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif-Bold.ttf", DEFAULT_FONT_SIZE ); TextEditor editor = TextEditor::New(); - editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f ); DALI_TEST_CHECK( editor ); - Stage::GetCurrent().Add( editor ); editor.SetSize( 300.f, 50.f ); editor.SetParentOrigin( ParentOrigin::TOP_LEFT ); editor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - // Avoid a crash when core load gl resources. - application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); + editor.SetProperty( TextEditor::Property::ENABLE_MARKUP, true ); + editor.SetProperty( TextEditor::Property::TEXT, "He llo world demo" ); + + // connect to the text changed signal. + ConnectionTracker* testTracker = new ConnectionTracker(); + editor.InputStyleChangedSignal().Connect( &TestInputStyleChangedCallback ); + bool inputStyleChangedSignal = false; + editor.ConnectSignal( testTracker, "inputStyleChanged", CallbackFunctor(&inputStyleChangedSignal) ); + + Stage::GetCurrent().Add( editor ); // Render and notify application.SendNotification(); application.Render(); - // Check there are the expected number of children ( active layer, offscreen root actor, and the offscreen image view - DALI_TEST_EQUALS( editor.GetChildCount(), 3u, TEST_LOCATION ); - - Actor layer = editor.GetChildAt( 0u ); - DALI_TEST_CHECK( layer.IsLayer() ); - - Actor offscreenRoot = editor.GetChildAt( 1u ); - DALI_TEST_CHECK( offscreenRoot.IsLayer() ); - DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor. + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); - Actor offscreenImage = editor.GetChildAt( 2u ); - DALI_TEST_CHECK( offscreenImage ); + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; // Create a tap event to touch the text editor. - application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) ); - application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 53.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 53.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Possible, 2u, 1u, Vector2( 53.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 2u, 1u, Vector2( 53.f, 25.f ) ) ); // Render and notify application.SendNotification(); application.Render(); - DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor. - DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor. + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); - // Now the text editor has the focus, so it can handle the key events. - application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) ); - application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) ); + DALI_TEST_CHECK( gInputStyleChangedCallbackCalled ); + if( gInputStyleChangedCallbackCalled ) + { + DALI_TEST_EQUALS( static_cast( gInputStyleMask ), + static_cast( TextEditor::InputStyle::FONT_FAMILY | + TextEditor::InputStyle::POINT_SIZE | + TextEditor::InputStyle::COLOR ), + TEST_LOCATION ); + + const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get(); + DALI_TEST_EQUALS( color, Color::GREEN, TEST_LOCATION ); + + const std::string fontFamily = editor.GetProperty( TextEditor::Property::INPUT_FONT_FAMILY ).Get(); + DALI_TEST_EQUALS( fontFamily, "DejaVuSerif", TEST_LOCATION ); + + const float pointSize = editor.GetProperty( TextEditor::Property::INPUT_POINT_SIZE ).Get(); + DALI_TEST_EQUALS( pointSize, 18.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + } + DALI_TEST_CHECK( inputStyleChangedSignal ); + + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; + + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); // Render and notify application.SendNotification(); application.Render(); - // Checks the cursor and the renderer have been created. - DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor. - DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 2u, TEST_LOCATION ); // The camera actor and the renderer - - Control cursor = Control::DownCast( layer.GetChildAt( 0u ) ); - DALI_TEST_CHECK( cursor ); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); - CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) ); - DALI_TEST_CHECK( camera ); + DALI_TEST_CHECK( gInputStyleChangedCallbackCalled ); + if( gInputStyleChangedCallbackCalled ) + { + DALI_TEST_EQUALS( static_cast( gInputStyleMask ), + static_cast( TextEditor::InputStyle::COLOR ), + TEST_LOCATION ); - Renderer renderer = offscreenRoot.GetChildAt( 1u ).GetRendererAt( 0u ); - DALI_TEST_CHECK( renderer ); + const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get(); + DALI_TEST_EQUALS( color, Color::BLUE, TEST_LOCATION ); + } + DALI_TEST_CHECK( inputStyleChangedSignal ); - // Move the cursor and check the position changes. - Vector3 position1 = cursor.GetCurrentPosition(); + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; - application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) ); - application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) ); + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); // Render and notify application.SendNotification(); application.Render(); - Vector3 position2 = cursor.GetCurrentPosition(); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); - DALI_TEST_CHECK( position2.x < position1.x ); + DALI_TEST_CHECK( !gInputStyleChangedCallbackCalled ); + DALI_TEST_CHECK( !inputStyleChangedSignal ); - application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) ); - application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) ); + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; + + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); // Render and notify application.SendNotification(); application.Render(); - Vector3 position3 = cursor.GetCurrentPosition(); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); - DALI_TEST_EQUALS( position1, position3, TEST_LOCATION ); // Should be in the same position1. + DALI_TEST_CHECK( gInputStyleChangedCallbackCalled ); + if( gInputStyleChangedCallbackCalled ) + { + DALI_TEST_EQUALS( static_cast( gInputStyleMask ), + static_cast( TextEditor::InputStyle::COLOR ), + TEST_LOCATION ); - // Send some taps and check the cursor positions. + const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get(); + DALI_TEST_EQUALS( color, Color::BLACK, TEST_LOCATION ); + } + DALI_TEST_CHECK( inputStyleChangedSignal ); - // Try to tap at the beginning. - application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 1.f, 25.0f ) ) ); - application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 1.f, 25.0f ) ) ); + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; - // Render and notify - application.SendNotification(); - application.Render(); + editor.SetProperty( TextEditor::Property::INPUT_COLOR, Color::YELLOW ); - // Cursor position should be the same than position1. - Vector3 position4 = cursor.GetCurrentPosition(); + Property::Map fontStyleMapSet; + fontStyleMapSet.Insert( "weight", "thin" ); + fontStyleMapSet.Insert( "width", "condensed" ); + fontStyleMapSet.Insert( "slant", "italic" ); - DALI_TEST_EQUALS( position2, position4, TEST_LOCATION ); // Should be in the same position2. + editor.SetProperty( TextEditor::Property::INPUT_FONT_STYLE, fontStyleMapSet ); + editor.SetProperty( TextEditor::Property::INPUT_POINT_SIZE, 20.f ); + editor.SetProperty( TextEditor::Property::INPUT_LINE_SPACING, 5.f ); - // Tap away from the start position. - application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 16.f, 25.0f ) ) ); - application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 16.0f, 25.0f ) ) ); + editor.SetProperty( TextEditor::Property::INPUT_UNDERLINE, "underline" ); + editor.SetProperty( TextEditor::Property::INPUT_SHADOW, "shadow" ); + editor.SetProperty( TextEditor::Property::INPUT_EMBOSS, "emboss" ); + editor.SetProperty( TextEditor::Property::INPUT_OUTLINE, "outline" ); + + application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); // Render and notify application.SendNotification(); application.Render(); - Vector3 position5 = cursor.GetCurrentPosition(); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); - DALI_TEST_CHECK( position5.x > position4.x ); + DALI_TEST_CHECK( !gInputStyleChangedCallbackCalled ); + DALI_TEST_CHECK( !inputStyleChangedSignal ); - // Remove all the text. - application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) ); - application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) ); - editor.SetProperty( TextEditor::Property::TEXT, "" ); + // Create a tap event to touch the text editor. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 63.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 63.f, 25.f ) ) ); // Render and notify application.SendNotification(); application.Render(); - // Cursor position should be the same than position2. - Vector3 position6 = cursor.GetCurrentPosition(); + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); - DALI_TEST_EQUALS( position2, position6, TEST_LOCATION );// Should be in the same position2. + DALI_TEST_CHECK( gInputStyleChangedCallbackCalled ); + if( gInputStyleChangedCallbackCalled ) + { + DALI_TEST_EQUALS( static_cast( gInputStyleMask ), + static_cast( TextEditor::InputStyle::COLOR | + TextEditor::InputStyle::POINT_SIZE | + TextEditor::InputStyle::FONT_STYLE | + TextEditor::InputStyle::LINE_SPACING | + TextEditor::InputStyle::UNDERLINE | + TextEditor::InputStyle::SHADOW | + TextEditor::InputStyle::EMBOSS | + TextEditor::InputStyle::OUTLINE ), + TEST_LOCATION ); + + const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get(); + DALI_TEST_EQUALS( color, Color::BLACK, TEST_LOCATION ); + } + DALI_TEST_CHECK( inputStyleChangedSignal ); - // Should not be a renderer. - DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor only. + gInputStyleChangedCallbackCalled = false; + gInputStyleMask = TextEditor::InputStyle::NONE; + inputStyleChangedSignal = false; - END_TEST; -} + editor.SetProperty( TextEditor::Property::FONT_FAMILY, "DejaVuSerif" ); -int utcDaliTextEditorEvent03(void) -{ - ToolkitTestApplication application; - tet_infoline(" utcDaliTextEditorEvent03"); + fontStyleMapSet.Clear(); + fontStyleMapSet.Insert( "weight", "black" ); + fontStyleMapSet.Insert( "width", "expanded" ); + fontStyleMapSet.Insert( "slant", "oblique" ); - // Checks if the highlight actor is created. + editor.SetProperty( TextEditor::Property::FONT_STYLE, fontStyleMapSet ); + + // Create a tap event to touch the text editor. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 30.f, 25.f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 30.f, 25.f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Executes the idle callbacks added by the text control on the change of input style. + application.RunIdles(); + + DALI_TEST_CHECK( gInputStyleChangedCallbackCalled ); + if( gInputStyleChangedCallbackCalled ) + { + DALI_TEST_EQUALS( static_cast( gInputStyleMask ), + static_cast( TextEditor::InputStyle::COLOR | + TextEditor::InputStyle::POINT_SIZE | + TextEditor::InputStyle::FONT_STYLE ), + TEST_LOCATION ); + + const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get(); + DALI_TEST_EQUALS( color, Color::YELLOW, TEST_LOCATION ); + } + DALI_TEST_CHECK( inputStyleChangedSignal ); + + END_TEST; +} + +int utcDaliTextEditorEvent01(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorEvent01"); + + // Creates a tap event. After creating a tap event the text editor should + // have the focus and add text with key events should be possible. + + TextEditor editor = TextEditor::New(); + DALI_TEST_CHECK( editor ); + + Stage::GetCurrent().Add( editor ); + + editor.SetSize( 300.f, 50.f ); + editor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + editor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + + // Avoid a crash when core load gl resources. + application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Add a key event but as the text editor has not the focus it should do nothing. + application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string(""), TEST_LOCATION ); + + // Create a tap event to touch the text editor. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Now the text editor has the focus, so it can handle the key events. + application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string("aa"), TEST_LOCATION ); + + // Create a second text editor and send key events to it. + TextEditor editor2 = TextEditor::New(); + + editor2.SetParentOrigin( ParentOrigin::TOP_LEFT ); + editor2.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + editor2.SetSize( 100.f, 100.f ); + editor2.SetPosition( 100.f, 100.f ); + + Stage::GetCurrent().Add( editor2 ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Create a tap event on the second text editor. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 125.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 125.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // The second text editor has the focus. It should handle the key events. + application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Check the text has been added to the second text editor. + DALI_TEST_EQUALS( editor2.GetProperty( TextEditor::Property::TEXT ), std::string("aa"), TEST_LOCATION ); + + END_TEST; +} + +int utcDaliTextEditorEvent02(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorEvent02"); + + // Checks if the right number of actors are created. + + TextEditor editor = TextEditor::New(); + editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f ); + DALI_TEST_CHECK( editor ); + + Stage::GetCurrent().Add( editor ); + + editor.SetSize( 300.f, 50.f ); + editor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + editor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + + // Avoid a crash when core load gl resources. + application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Check there are the expected number of children (the stencil). + DALI_TEST_EQUALS( editor.GetChildCount(), 1u, TEST_LOCATION ); + + Actor stencil = editor.GetChildAt( 0u ); + + // Create a tap event to touch the text editor. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + Actor layer = editor.GetChildAt( 1u ); + DALI_TEST_CHECK( layer.IsLayer() ); + + DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor. + DALI_TEST_EQUALS( stencil.GetChildCount(), 0u, TEST_LOCATION ); + + // Now the text editor has the focus, so it can handle the key events. + application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Checks the cursor and the renderer have been created. + DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor. + DALI_TEST_EQUALS( stencil.GetChildCount(), 1u, TEST_LOCATION ); // The renderer + + Control cursor = Control::DownCast( layer.GetChildAt( 0u ) ); + DALI_TEST_CHECK( cursor ); + + // The stencil actor has a container with all the actors which contain the text renderers. + Actor container = stencil.GetChildAt( 0u ); + for( unsigned int index = 0; index < container.GetChildCount(); ++index ) + { + Renderer renderer = container.GetChildAt( index ).GetRendererAt( 0u ); + DALI_TEST_CHECK( renderer ); + } + + // Move the cursor and check the position changes. + Vector3 position1 = cursor.GetCurrentPosition(); + + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + Vector3 position2 = cursor.GetCurrentPosition(); + + DALI_TEST_CHECK( position2.x < position1.x ); + + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + Vector3 position3 = cursor.GetCurrentPosition(); + + DALI_TEST_EQUALS( position1, position3, TEST_LOCATION ); // Should be in the same position1. + + // Send some taps and check the cursor positions. + + // Try to tap at the beginning. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 1.f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 1.f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Cursor position should be the same than position1. + Vector3 position4 = cursor.GetCurrentPosition(); + + DALI_TEST_EQUALS( position2, position4, TEST_LOCATION ); // Should be in the same position2. + + // Tap away from the start position. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 16.f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 16.0f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + Vector3 position5 = cursor.GetCurrentPosition(); + + DALI_TEST_CHECK( position5.x > position4.x ); + + // Remove all the text. + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + editor.SetProperty( TextEditor::Property::TEXT, "" ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Cursor position should be the same than position2. + Vector3 position6 = cursor.GetCurrentPosition(); + + DALI_TEST_EQUALS( position2, position6, TEST_LOCATION );// Should be in the same position2. + + // Should not be a renderer. + DALI_TEST_EQUALS( stencil.GetChildCount(), 0u, TEST_LOCATION ); + + END_TEST; +} + +int utcDaliTextEditorEvent03(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorEvent03"); + + // Checks if the highlight actor is created. TextEditor editor = TextEditor::New(); DALI_TEST_CHECK( editor ); @@ -739,6 +1565,17 @@ int utcDaliTextEditorEvent03(void) application.SendNotification(); application.Render(); + // Send some taps and check text controller with clipboard window + Dali::Clipboard clipboard = Clipboard::Get(); + clipboard.ShowClipboard(); + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + clipboard.HideClipboard(); + + // Render and notify + application.SendNotification(); + application.Render(); + // Tap first to get the focus. application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); @@ -755,18 +1592,459 @@ int utcDaliTextEditorEvent03(void) application.SendNotification(); application.Render(); - // The offscreen root actor should have three actors: the camera, a renderer and the highlight actor. - Actor offscreenRoot = editor.GetChildAt( 1u ); - DALI_TEST_CHECK( offscreenRoot.IsLayer() ); + // The stencil actor should have two actors: the renderer and the highlight actor. + Actor stencil = editor.GetChildAt( 0u ); - CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) ); - DALI_TEST_CHECK( camera ); - - Renderer renderer = offscreenRoot.GetChildAt( 1u ).GetRendererAt( 0u ); - DALI_TEST_CHECK( renderer ); + // The stencil actor has a container with all the actors which contain the text renderers. + Actor container = stencil.GetChildAt( 0u ); + for( unsigned int index = 0; index < container.GetChildCount(); ++index ) + { + Renderer renderer = container.GetChildAt( index ).GetRendererAt( 0u ); + DALI_TEST_CHECK( renderer ); + } - Renderer highlight = offscreenRoot.GetChildAt( 2u ).GetRendererAt( 0u ); + Renderer highlight = stencil.GetChildAt( 1u ).GetRendererAt( 0u ); DALI_TEST_CHECK( highlight ); + // Double tap out of bounds + application.ProcessEvent( GenerateTap( Gesture::Possible, 2u, 1u, Vector2( 29.f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 2u, 1u, Vector2( 29.f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // The stencil actor should have one actors: the renderer actor. + stencil = editor.GetChildAt( 0u ); + + // The stencil actor has a container with all the actors which contain the text renderers. + container = stencil.GetChildAt( 0u ); + for( unsigned int index = 0; index < container.GetChildCount(); ++index ) + { + Renderer renderer = container.GetChildAt( index ).GetRendererAt( 0u ); + DALI_TEST_CHECK( renderer ); + } + + END_TEST; +} + +int utcDaliTextEditorEvent04(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorEvent04"); + + // Checks if the highlight actor is created. + + TextEditor editor = TextEditor::New(); + DALI_TEST_CHECK( editor ); + + Stage::GetCurrent().Add( editor ); + + editor.SetProperty( TextEditor::Property::TEXT, "Hello\nworl" ); + editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f ); + editor.SetSize( 100.f, 50.f ); + editor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + editor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + + // Avoid a crash when core load gl resources. + application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Tap on the text editor + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Move at the end of the text. + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + for( unsigned int index = 0u; index < 10u; ++index ) + { + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + } + + // Add a character + application.ProcessEvent( GenerateKey( "d", "d", KEY_D_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( "Hello\nworld", editor.GetProperty( TextEditor::Property::TEXT ), TEST_LOCATION ); + + // Add some key events + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_UP, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_UP, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + for( unsigned int index = 0u; index < 10u; ++index ) + { + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + } + + // Add a character + application.ProcessEvent( GenerateKey( " ", " ", KEY_WHITE_SPACE_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( " Hello\nworld", editor.GetProperty( TextEditor::Property::TEXT ), TEST_LOCATION ); + + END_TEST; +} + +int utcDaliTextEditorEvent05(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorEvent05"); + + // Checks if the highlight actor is created. + + TextEditor editor = TextEditor::New(); + DALI_TEST_CHECK( editor ); + + Stage::GetCurrent().Add( editor ); + + editor.SetProperty( TextEditor::Property::TEXT, "Hello\nworl" ); + editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f ); + editor.SetSize( 50.f, 50.f ); + editor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + editor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL, true ); + editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL_DURATION, 0.2f ); + editor.SetProperty( DevelTextEditor::Property::ENABLE_SCROLL_BAR, true ); + editor.SetProperty( DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION, 0.3f ); + editor.SetProperty( DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION, 0.2f ); + + // Avoid a crash when core load gl resources. + application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Tap on the text editor + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Move at the end of the text. + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + for( unsigned int index = 0u; index < 10u; ++index ) + { + // Add a character + application.ProcessEvent( GenerateKey( "d", "d", KEY_D_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + } + // Modify duration after scroll is enabled + editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL_DURATION, 0.1f ); + + // Continuous scroll left to increase coverage + for( unsigned int index = 0u; index < 10u; ++index ) + { + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + } + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SMOOTH_SCROLL_DURATION ), 0.1f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SMOOTH_SCROLL ), true, TEST_LOCATION ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::ENABLE_SCROLL_BAR ), true, TEST_LOCATION ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION ), 0.3f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION ), 0.2f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + + // Press Escape to increase coverage + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_ESCAPE, 0, 0, Integration::KeyEvent::Up, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) ); + application.SendNotification(); + application.Render(); + + DALI_TEST_CHECK( !editor.HasKeyInputFocus() ); + + END_TEST; +} + +int utcDaliTextEditorHandles(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorHandles"); + + TextEditor editor = TextEditor::New(); + DALI_TEST_CHECK( editor ); + + Stage::GetCurrent().Add( editor ); + + editor.SetProperty( TextEditor::Property::TEXT, "This is a long text for the size of the text-editor." ); + editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f ); + editor.SetProperty( TextEditor::Property::GRAB_HANDLE_IMAGE, HANDLE_IMAGE_FILE_NAME ); + editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL, true ); + + editor.SetSize( 30.f, 500.f ); + editor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + editor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + + // Avoid a crash when core load gl resources. + application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Tap first to get the focus. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Tap to create the grab handle. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Get the active layer where the text's decoration is added. + Actor activeLayer = editor.GetChildAt( 1u ); + + // Get the handle's actor. + Actor handle = activeLayer.GetChildAt( 1u ); + handle.SetSize( 100.f, 100.f ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Touch the grab handle to set it as pressed. + Vector2 touchPos( 10.0f, 50.0f ); + Dali::Integration::TouchEvent event; + event = Dali::Integration::TouchEvent(); + event.AddPoint( GetPointDownInside( touchPos ) ); + application.ProcessEvent( event ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // drag grab handle right + SendPan(application, Gesture::Possible, touchPos); + SendPan(application, Gesture::Started, touchPos); + touchPos.x += 5.0f; + Wait(application, 100); + + for(int i = 0;i<20;i++) + { + SendPan(application, Gesture::Continuing, touchPos); + touchPos.x += 5.0f; + Wait(application); + } + + SendPan(application, Gesture::Finished, touchPos); + Wait(application); + + // Release the grab handle. + event = Dali::Integration::TouchEvent(); + event.AddPoint( GetPointUpInside( touchPos ) ); + application.ProcessEvent( event ); + + // Render and notify + application.SendNotification(); + application.Render(); + + END_TEST; +} + + +int utcDaliTextEditorUnderPropertyStringP(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorUnderPropertyStringP"); + TextEditor editor = TextEditor::New(); + DALI_TEST_CHECK( editor ); + + std::string underlineSettings1( "{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}" ); + + Stage::GetCurrent().Add( editor ); + + editor.SetProperty( TextEditor::Property::UNDERLINE, underlineSettings1 ); + DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::UNDERLINE ), underlineSettings1, TEST_LOCATION ); + + tet_infoline("Set underline settings with a map"); + // Check the input underline property + Property::Map underlineMapSet; + Property::Map underlineMapGet; + underlineMapSet.Insert( "enable", "true" ); + underlineMapSet.Insert( "color", "blue" ); + underlineMapSet.Insert( "height", "2" ); + + editor.SetProperty( TextEditor::Property::UNDERLINE, underlineMapSet ); + underlineMapGet = editor.GetProperty( TextEditor::Property::UNDERLINE ); + DALI_TEST_EQUALS( underlineMapGet.Count(), underlineMapSet.Count(), TEST_LOCATION ); + DALI_TEST_EQUALS( DaliTestCheckMaps( underlineMapSet, underlineMapGet ), true, TEST_LOCATION ); + + tet_infoline("Set underline settings with a string"); + editor.SetProperty( TextEditor::Property::UNDERLINE, underlineSettings1 ); + Property::Value value = editor.GetProperty( TextEditor::Property::UNDERLINE ); + std::string result; + value.Get(result); + DALI_TEST_EQUALS( result , underlineSettings1, TEST_LOCATION ); + + tet_infoline("Trying to set invalid underline settings, should not update and stay at previous settings"); + std::string underlineSettingsVoid( "{\"enable\":\"true\",\"coooolor\":\"blue\",\"heeeight\":\"4\"}" ); + editor.SetProperty( TextEditor::Property::UNDERLINE, underlineSettingsVoid ); + value = editor.GetProperty( TextEditor::Property::UNDERLINE ); + value.Get(result); + DALI_TEST_EQUALS( result , underlineSettings1, TEST_LOCATION ); + + END_TEST; +} + +int utcDaliTextEditorShadowPropertyStringP(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorUnderPropertyStringP Setting Shadow propeties by string"); + + TextEditor editor = TextEditor::New(); + + std::string shadowSettings( "{\"color\":\"green\",\"offset\":\"2 2\"}" ); + + Stage::GetCurrent().Add( editor ); + + editor.SetProperty( TextEditor::Property::SHADOW, "{\"color\":\"green\",\"offset\":\"2 2\"}" ); + + Property::Value value = editor.GetProperty( TextEditor::Property::SHADOW ); + std::string result; + value.Get(result); + + DALI_TEST_EQUALS( result, shadowSettings, TEST_LOCATION ); + + END_TEST; +} + +int utcDaliTextEditorFontStylePropertyStringP(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorFontStylePropertyStringP Setting FontStyle propeties by string"); + + TextEditor editor = TextEditor::New(); + + std::string fontStyleSettings( "{\"weight\":\"bold\",\"width\":\"condensed\",\"slant\":\"italic\"}" ); + + Stage::GetCurrent().Add( editor ); + + editor.SetProperty( TextEditor::Property::FONT_STYLE, "{\"weight\":\"bold\",\"width\":\"condensed\",\"slant\":\"italic\"}" ); + + Property::Value value = editor.GetProperty( TextEditor::Property::FONT_STYLE ); + std::string result; + value.Get(result); + + DALI_TEST_EQUALS( result, fontStyleSettings, TEST_LOCATION ); + + END_TEST; +} + +int utcDaliTextEditorGetPropertyLinecountP(void) +{ + ToolkitTestApplication application; + + tet_infoline(" utcDaliTextEditorGetPropertyLinecount getting line count property"); + + int lineCount =0 ; + + TextEditor editor = TextEditor::New(); + editor.SetProperty( TextEditor::Property::POINT_SIZE, 10) ; + editor.SetProperty( TextEditor::Property::TEXT, + "TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST "); + + Stage::GetCurrent().Add( editor ); + + editor.SetSize( 100.0f, 100.0f ); + lineCount = editor.GetProperty( DevelTextEditor::Property::LINE_COUNT ); + DALI_TEST_EQUALS( lineCount, 14, TEST_LOCATION ); + + editor.SetSize( 50.0f, 100.0f ); + lineCount = editor.GetProperty( DevelTextEditor::Property::LINE_COUNT ); + DALI_TEST_EQUALS( lineCount, 28, TEST_LOCATION ); + + END_TEST; +} + +int utcDaliTextEditorScrollStateChangedSignalTest(void) +{ + + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextEditorScrollStateChangedSignalTest"); + + TextEditor editor = TextEditor::New(); + DALI_TEST_CHECK( editor ); + + Stage::GetCurrent().Add( editor ); + + editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f ); + editor.SetSize( 50.f, 50.f ); + editor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + editor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + editor.SetProperty( DevelTextEditor::Property::ENABLE_SCROLL_BAR, true ); + editor.SetKeyboardFocusable(true); + + bool startedCalled = false; + bool finishedCalled = false; + + ScrollStateChangeCallback callback( startedCalled, finishedCalled ); + DevelTextEditor::ScrollStateChangedSignal( editor ).Connect( &callback, &ScrollStateChangeCallback::Callback ); + + KeyboardFocusManager::Get().SetCurrentFocusActor( editor ); + + // Render and notify + application.SendNotification(); + application.Render(); + + editor.SetProperty( TextEditor::Property::TEXT, "Long enough message for TextEditor!"); + application.SendNotification(); + application.Render(6000); + + application.SendNotification(); + DALI_TEST_EQUALS( startedCalled, true, TEST_LOCATION ); + DALI_TEST_EQUALS( finishedCalled, true, TEST_LOCATION ); + END_TEST; }