# Append list of test harness files (Won't get parsed for test cases)
LIST(APPEND TC_SOURCES
+ dali-toolkit-test-utils/toolkit-adaptor.cpp
dali-toolkit-test-utils/toolkit-accessibility-adaptor.cpp
dali-toolkit-test-utils/toolkit-application.cpp
dali-toolkit-test-utils/toolkit-bitmap-loader.cpp
--- /dev/null
+#ifndef __DALI_TOOLKIT_ADAPTOR_IMPL_H__
+#define __DALI_TOOLKIT_ADAPTOR_IMPL_H__
+
+/*
+ * Copyright (c) 2016 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 <dali/devel-api/adaptor-framework/render-surface.h>
+
+namespace Dali
+{
+class EglInterface;
+class DisplayConnection;
+class ThreadSynchronizationInterface;
+
+namespace Integration
+{
+
+class GlAbstraction;
+
+} // namespace Integration
+
+class TestRenderSurface : public RenderSurface
+{
+public:
+ virtual PositionSize GetPositionSize() const { PositionSize size; return size; }
+
+ virtual void InitializeEgl( EglInterface& egl ) {}
+
+ virtual void CreateEglSurface( EglInterface& egl ) {}
+
+ virtual void DestroyEglSurface( EglInterface& egl ) {}
+
+ virtual bool ReplaceEGLSurface( EglInterface& egl ) { return false; }
+
+ virtual void MoveResize( Dali::PositionSize positionSize ) {}
+
+ virtual void SetViewMode( ViewMode viewMode ) {}
+
+ virtual void StartRender() {}
+
+ virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ) { return false; }
+
+ virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ) {}
+
+ virtual void StopRender() {}
+
+ virtual void ReleaseLock() {}
+
+ virtual void SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization ) {}
+
+ virtual RenderSurface::Type GetSurfaceType() { return RenderSurface::ECORE_RENDER_SURFACE; }
+};
+
+namespace Internal
+{
+namespace Adaptor
+{
+
+class Adaptor: public BaseObject
+{
+public:
+ static Dali::Adaptor& Get();
+ Adaptor();
+ ~Adaptor();
+
+public:
+ static Dali::RenderSurface& GetSurface();
+ static Dali::Adaptor::AdaptorSignalType& AdaptorSignal();
+ static bool mAvailable;
+ static Vector<CallbackBase*> mCallbacks;
+};
+
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_ADAPTOR_IMPL_H__
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
#include <dali/integration-api/adaptors/adaptor.h>
#include <dali/public-api/object/base-object.h>
-#include <dali/devel-api/adaptor-framework/render-surface.h>
-namespace Dali
-{
-
-class EglInterface;
-class DisplayConnection;
-class ThreadSynchronizationInterface;
-
-namespace Integration
-{
+#include <toolkit-adaptor-impl.h>
-class GlAbstraction;
-
-} // namespace Integration
-
-class TestRenderSurface : public RenderSurface
+namespace Dali
{
-public:
- virtual PositionSize GetPositionSize() const { PositionSize size; return size; }
-
- virtual void InitializeEgl( EglInterface& egl ) {}
-
- virtual void CreateEglSurface( EglInterface& egl ) {}
-
- virtual void DestroyEglSurface( EglInterface& egl ) {}
-
- virtual bool ReplaceEGLSurface( EglInterface& egl ) { return false; }
-
- virtual void MoveResize( Dali::PositionSize positionSize ) {}
-
- virtual void SetViewMode( ViewMode viewMode ) {}
-
- virtual void StartRender() {}
-
- virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ) { return false; }
-
- virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ) {}
-
- virtual void StopRender() {}
-
- virtual void ReleaseLock() {}
-
- virtual void SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization ) {}
-
- virtual RenderSurface::Type GetSurfaceType() { return RenderSurface::ECORE_RENDER_SURFACE; }
-};
namespace Internal
{
namespace Adaptor
{
-class Adaptor: public BaseObject
-{
-public:
- static Dali::Adaptor& Get();
- Adaptor();
- ~Adaptor();
-
-public:
- static Dali::RenderSurface& GetSurface();
- static Dali::Adaptor::AdaptorSignalType& AdaptorSignal();
-};
+bool Adaptor::mAvailable = false;
+Vector<CallbackBase*> Adaptor::mCallbacks = Vector<CallbackBase*>();
Dali::Adaptor& Adaptor::Get()
{
Dali::Adaptor* adaptor = new Dali::Adaptor;
+ Adaptor::mAvailable = true;
return *adaptor;
}
return *signal;
}
-}
-}
-}
-
-namespace Dali
-{
+} // namespace Adaptor
+} // namespace Internal
Adaptor& Adaptor::New( Window window )
{
bool Adaptor::AddIdle( CallbackBase* callback )
{
- return false;
+ const bool isAvailable = IsAvailable();
+
+ if( isAvailable )
+ {
+ Internal::Adaptor::Adaptor::mCallbacks.PushBack( callback );
+ }
+
+ return isAvailable;
+}
+
+void Adaptor::RemoveIdle( CallbackBase* callback )
+{
+ const bool isAvailable = IsAvailable();
+
+ if( isAvailable )
+ {
+ for( Vector<CallbackBase*>::Iterator it = Internal::Adaptor::Adaptor::mCallbacks.Begin(),
+ endIt = Internal::Adaptor::Adaptor::mCallbacks.End();
+ it != endIt;
+ ++it )
+ {
+ if( callback == *it )
+ {
+ Internal::Adaptor::Adaptor::mCallbacks.Remove( it );
+ return;
+ }
+ }
+ }
}
void Adaptor::ReplaceSurface( Any nativeWindow, Dali::RenderSurface& surface )
bool Adaptor::IsAvailable()
{
- return false;
+ return Internal::Adaptor::Adaptor::mAvailable;
}
void Adaptor::NotifySceneCreated()
#define __DALI_TOOLKIT_TEST_APPLICATION_H__
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
// INTERNAL INCLUDES
#include <dali-test-suite-utils.h>
#include <dali/devel-api/text-abstraction/font-client.h>
+#include <dali/integration-api/adaptors/adaptor.h>
+#include <toolkit-adaptor-impl.h>
namespace Dali
{
//return mOrientation;
//}
+ /**
+ * @brief Creates an adaptor implementation for those controls like the
+ * text-field and the text-editor which connects a callback to the idle signal.
+ */
+ void CreateAdaptor()
+ {
+ Adaptor::Get();
+ }
+
+ /**
+ * @brief Executes the idle callbacks.
+ *
+ * Some controls like the text-field and the text-editor connect callbacks to the
+ * idle signal.
+ */
+ void RunIdles()
+ {
+ if( Adaptor::IsAvailable() )
+ {
+ for( Vector<CallbackBase*>::Iterator it = Internal::Adaptor::Adaptor::mCallbacks.Begin(),
+ endIt = Internal::Adaptor::Adaptor::mCallbacks.End();
+ it != endIt;
+ ++it )
+ {
+ CallbackBase* callback = *it;
+
+ CallbackBase::Execute( *callback );
+ }
+
+ Internal::Adaptor::Adaptor::mCallbacks.Clear();
+ }
+ }
+
private:
//ToolkitOrientation mOrientation;
};
#include <iostream>
#include <stdlib.h>
+#include <unistd.h>
+
#include <dali/public-api/rendering/renderer.h>
#include <dali/integration-api/events/key-event-integ.h>
#include <dali/integration-api/events/tap-gesture-event.h>
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" );
+
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 )
{
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,
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();
END_TEST;
}
+int utcDaliTextEditorInputStyleChanged01(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextEditorInputStyleChanged01");
+
+ // 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 );
+
+
+ editor.SetSize( 300.f, 50.f );
+ editor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ editor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ editor.SetProperty( TextEditor::Property::ENABLE_MARKUP, true );
+ editor.SetProperty( TextEditor::Property::TEXT, "<font family='DejaVuSerif' size='18'>He<color value='green'>llo</color> <font weight='bold'>world</font> demo</font>" );
+
+ // 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();
+
+ // 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();
+
+ // 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<unsigned int>( gInputStyleMask ), static_cast<unsigned int>( TextEditor::InputStyle::FONT_FAMILY | TextEditor::InputStyle::POINT_SIZE ), TEST_LOCATION );
+
+ const std::string fontFamily = editor.GetProperty( TextEditor::Property::INPUT_FONT_FAMILY ).Get<std::string>();
+ DALI_TEST_EQUALS( fontFamily, "DejaVuSerif", TEST_LOCATION );
+
+ const float pointSize = editor.GetProperty( TextEditor::Property::INPUT_POINT_SIZE ).Get<float>();
+ 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( 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 );
+ 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();
+
+ // 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<unsigned int>( gInputStyleMask ), static_cast<unsigned int>( TextEditor::InputStyle::COLOR ), TEST_LOCATION );
+
+ const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::GREEN, 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( 88.f, 25.f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 88.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<unsigned int>( gInputStyleMask ), static_cast<unsigned int>( TextEditor::InputStyle::COLOR | TextEditor::InputStyle::FONT_STYLE ), TEST_LOCATION );
+
+ const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::BLACK, TEST_LOCATION );
+
+ const std::string style = editor.GetProperty( TextEditor::Property::INPUT_FONT_STYLE ).Get<std::string>();
+ DALI_TEST_EQUALS( style, "{\"weight\":\"bold\"}", 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();
+
+ // 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();
+
+ // 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<unsigned int>( gInputStyleMask ), static_cast<unsigned int>( TextEditor::InputStyle::FONT_STYLE ), TEST_LOCATION );
+
+ const std::string style = editor.GetProperty( TextEditor::Property::INPUT_FONT_STYLE ).Get<std::string>();
+ DALI_TEST_CHECK( style.empty() );
+ }
+ 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 utcDaliTextEditorInputStyleChanged02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextEditorInputStyleChanged02");
+
+ // 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 );
+
+
+ editor.SetSize( 300.f, 50.f );
+ editor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ editor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ editor.SetProperty( TextEditor::Property::ENABLE_MARKUP, true );
+ editor.SetProperty( TextEditor::Property::TEXT, "<font family='DejaVuSerif' size='18'>He<color value='blue'> l</color><color value='green'>lo</color> <font weight='bold'>world</font> demo</font>" );
+
+ // 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();
+
+ // 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( 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();
+
+ // 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<unsigned int>( gInputStyleMask ),
+ static_cast<unsigned int>( TextEditor::InputStyle::FONT_FAMILY |
+ TextEditor::InputStyle::POINT_SIZE |
+ TextEditor::InputStyle::COLOR ),
+ TEST_LOCATION );
+
+ const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::GREEN, TEST_LOCATION );
+
+ const std::string fontFamily = editor.GetProperty( TextEditor::Property::INPUT_FONT_FAMILY ).Get<std::string>();
+ DALI_TEST_EQUALS( fontFamily, "DejaVuSerif", TEST_LOCATION );
+
+ const float pointSize = editor.GetProperty( TextEditor::Property::INPUT_POINT_SIZE ).Get<float>();
+ 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 ) );
+
+ // 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<unsigned int>( gInputStyleMask ),
+ static_cast<unsigned int>( TextEditor::InputStyle::COLOR ),
+ TEST_LOCATION );
+
+ const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::BLUE, 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 ) );
+
+ // 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 );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextEditor::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+
+ // 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<unsigned int>( gInputStyleMask ),
+ static_cast<unsigned int>( TextEditor::InputStyle::COLOR ),
+ TEST_LOCATION );
+
+ const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::BLACK, TEST_LOCATION );
+ }
+ DALI_TEST_CHECK( inputStyleChangedSignal );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextEditor::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ editor.SetProperty( TextEditor::Property::INPUT_COLOR, Color::YELLOW );
+
+ editor.SetProperty( TextEditor::Property::INPUT_FONT_STYLE, "{\"weight\":\"thin\",\"width\":\"condensed\",\"slant\":\"italic\"}" );
+ editor.SetProperty( TextEditor::Property::INPUT_POINT_SIZE, 20.f );
+ editor.SetProperty( TextEditor::Property::INPUT_LINE_SPACING, 5.f );
+
+ 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", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+ // 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 );
+
+ // 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();
+
+ // 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<unsigned int>( gInputStyleMask ),
+ static_cast<unsigned int>( 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<Vector4>();
+ DALI_TEST_EQUALS( color, Color::BLACK, TEST_LOCATION );
+ }
+ DALI_TEST_CHECK( inputStyleChangedSignal );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextEditor::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ editor.SetProperty( TextEditor::Property::FONT_FAMILY, "DejaVuSerif" );
+ editor.SetProperty( TextEditor::Property::FONT_STYLE, "{\"weight\":\"black\",\"width\":\"expanded\",\"slant\":\"oblique\"}" );
+
+ // 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<unsigned int>( gInputStyleMask ),
+ static_cast<unsigned int>( TextEditor::InputStyle::COLOR |
+ TextEditor::InputStyle::POINT_SIZE |
+ TextEditor::InputStyle::FONT_STYLE ),
+ TEST_LOCATION );
+
+ const Vector4 color = editor.GetProperty( TextEditor::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::YELLOW, TEST_LOCATION );
+ }
+ DALI_TEST_CHECK( inputStyleChangedSignal );
+
+ END_TEST;
+}
+
int utcDaliTextEditorEvent01(void)
{
ToolkitTestApplication application;
#include <iostream>
#include <stdlib.h>
+#include <unistd.h>
+
#include <dali/public-api/rendering/renderer.h>
#include <dali/integration-api/events/key-event-integ.h>
#include <dali/integration-api/events/tap-gesture-event.h>
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" );
+
static bool gTextChangedCallBackCalled;
static bool gMaxCharactersCallBackCalled;
+static bool gInputStyleChangedCallbackCalled;
+static Dali::Toolkit::TextField::InputStyle::Mask gInputStyleMask;
static void LoadBitmapResource(TestPlatformAbstraction& platform, int width, int height)
{
return time;
}
+struct CallbackFunctor
+{
+ CallbackFunctor(bool* callbackFlag)
+ : mCallbackFlag( callbackFlag )
+ {
+ }
+
+ void operator()()
+ {
+ *mCallbackFlag = true;
+ }
+ bool* mCallbackFlag;
+};
static void TestTextChangedCallback( TextField control )
{
gMaxCharactersCallBackCalled = true;
}
+static void TestInputStyleChangedCallback( TextField control, TextField::InputStyle::Mask mask )
+{
+ tet_infoline(" TestInputStyleChangedCallback");
+
+ gInputStyleChangedCallbackCalled = true;
+ gInputStyleMask = mask;
+}
+
// Generate a TapGestureEvent to send to Core.
Integration::TapGestureEvent GenerateTap(
Gesture::State state,
Stage::GetCurrent().Add( field );
+ // connect to the text changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
field.TextChangedSignal().Connect(&TestTextChangedCallback);
+ bool textChangedSignal = false;
+ field.ConnectSignal( testTracker, "textChanged", CallbackFunctor(&textChangedSignal) );
gTextChangedCallBackCalled = false;
field.SetProperty( TextField::Property::TEXT, "ABC" );
DALI_TEST_CHECK( gTextChangedCallBackCalled );
+ DALI_TEST_CHECK( textChangedSignal );
application.SendNotification();
Stage::GetCurrent().Add( field );
+ // connect to the text changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
field.TextChangedSignal().Connect(&TestTextChangedCallback);
+ bool textChangedSignal = false;
+ field.ConnectSignal( testTracker, "textChanged", CallbackFunctor(&textChangedSignal) );
gTextChangedCallBackCalled = false;
field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "ABC" ); // Setting placeholder, not TEXT
DALI_TEST_CHECK( !gTextChangedCallBackCalled );
+ DALI_TEST_CHECK( !textChangedSignal );
END_TEST;
}
field.SetKeyInputFocus();
- gMaxCharactersCallBackCalled = false;
+ // connect to the text changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
field.MaxLengthReachedSignal().Connect(&TestMaxLengthReachedCallback);
+ bool maxLengthReachedSignal = false;
+ field.ConnectSignal( testTracker, "maxLengthReached", CallbackFunctor(&maxLengthReachedSignal) );
+
+ gMaxCharactersCallBackCalled = false;
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( gMaxCharactersCallBackCalled );
+ DALI_TEST_CHECK( maxLengthReachedSignal );
END_TEST;
}
field.SetKeyInputFocus();
- gMaxCharactersCallBackCalled = false;
+ // connect to the text changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
field.MaxLengthReachedSignal().Connect(&TestMaxLengthReachedCallback);
+ bool maxLengthReachedSignal = false;
+ field.ConnectSignal( testTracker, "maxLengthReached", CallbackFunctor(&maxLengthReachedSignal) );
+
+ gMaxCharactersCallBackCalled = false;
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( !gMaxCharactersCallBackCalled );
+ DALI_TEST_CHECK( !maxLengthReachedSignal );
+
+ END_TEST;
+}
+
+int utcDaliTextFieldInputStyleChanged01(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextFieldInputStyleChanged01");
+
+ // The text-field 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-field 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 );
+
+ TextField field = TextField::New();
+ DALI_TEST_CHECK( field );
+
+
+ field.SetSize( 300.f, 50.f );
+ field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ field.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ field.SetProperty( TextField::Property::ENABLE_MARKUP, true );
+ field.SetProperty( TextField::Property::TEXT, "<font family='DejaVuSerif' size='18'>He<color value='green'>llo</color> <font weight='bold'>world</font> demo</font>" );
+
+ // connect to the text changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
+ field.InputStyleChangedSignal().Connect( &TestInputStyleChangedCallback );
+ bool inputStyleChangedSignal = false;
+ field.ConnectSignal( testTracker, "inputStyleChanged", CallbackFunctor(&inputStyleChangedSignal) );
+
+ Stage::GetCurrent().Add( field );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Executes the idle callbacks added by the text control on the change of input style.
+ application.RunIdles();
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ // Create a tap event to touch the text field.
+ 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();
+
+ // 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<unsigned int>( gInputStyleMask ), static_cast<unsigned int>( TextField::InputStyle::FONT_FAMILY | TextField::InputStyle::POINT_SIZE ), TEST_LOCATION );
+
+ const std::string fontFamily = field.GetProperty( TextField::Property::INPUT_FONT_FAMILY ).Get<std::string>();
+ DALI_TEST_EQUALS( fontFamily, "DejaVuSerif", TEST_LOCATION );
+
+ const float pointSize = field.GetProperty( TextField::Property::INPUT_POINT_SIZE ).Get<float>();
+ DALI_TEST_EQUALS( pointSize, 18.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ }
+ DALI_TEST_CHECK( inputStyleChangedSignal );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ // Create a tap event to touch the text field.
+ 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 );
+ DALI_TEST_CHECK( !inputStyleChangedSignal );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ // Create a tap event to touch the text field.
+ 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();
+
+ // 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<unsigned int>( gInputStyleMask ), static_cast<unsigned int>( TextField::InputStyle::COLOR ), TEST_LOCATION );
+
+ const Vector4 color = field.GetProperty( TextField::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::GREEN, TEST_LOCATION );
+ }
+ DALI_TEST_CHECK( inputStyleChangedSignal );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ // Create a tap event to touch the text field.
+ 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();
+
+ // 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<unsigned int>( gInputStyleMask ), static_cast<unsigned int>( TextField::InputStyle::COLOR | TextField::InputStyle::FONT_STYLE ), TEST_LOCATION );
+
+ const Vector4 color = field.GetProperty( TextField::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::BLACK, TEST_LOCATION );
+
+ const std::string style = field.GetProperty( TextField::Property::INPUT_FONT_STYLE ).Get<std::string>();
+ DALI_TEST_EQUALS( style, "{\"weight\":\"bold\"}", TEST_LOCATION );
+ }
+ DALI_TEST_CHECK( inputStyleChangedSignal );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ // Create a tap event to touch the text field.
+ 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();
+
+ // 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 = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ // Create a tap event to touch the text field.
+ 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();
+
+ // 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<unsigned int>( gInputStyleMask ), static_cast<unsigned int>( TextField::InputStyle::FONT_STYLE ), TEST_LOCATION );
+
+ const std::string style = field.GetProperty( TextField::Property::INPUT_FONT_STYLE ).Get<std::string>();
+ DALI_TEST_CHECK( style.empty() );
+ }
+ DALI_TEST_CHECK( inputStyleChangedSignal );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ // Create a tap event to touch the text field.
+ 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 utcDaliTextFieldInputStyleChanged02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextFieldInputStyleChanged02");
+
+ // The text-field 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-field 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 );
+
+ TextField field = TextField::New();
+ DALI_TEST_CHECK( field );
+
+
+ field.SetSize( 300.f, 50.f );
+ field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ field.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ field.SetProperty( TextField::Property::ENABLE_MARKUP, true );
+ field.SetProperty( TextField::Property::TEXT, "<font family='DejaVuSerif' size='18'>He<color value='blue'> l</color><color value='green'>lo</color> <font weight='bold'>world</font> demo</font>" );
+
+ // connect to the text changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
+ field.InputStyleChangedSignal().Connect( &TestInputStyleChangedCallback );
+ bool inputStyleChangedSignal = false;
+ field.ConnectSignal( testTracker, "inputStyleChanged", CallbackFunctor(&inputStyleChangedSignal) );
+
+ Stage::GetCurrent().Add( field );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Executes the idle callbacks added by the text control on the change of input style.
+ application.RunIdles();
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ // Create a tap event to touch the text field.
+ 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();
+
+ // 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<unsigned int>( gInputStyleMask ),
+ static_cast<unsigned int>( TextField::InputStyle::FONT_FAMILY |
+ TextField::InputStyle::POINT_SIZE |
+ TextField::InputStyle::COLOR ),
+ TEST_LOCATION );
+
+ const Vector4 color = field.GetProperty( TextField::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::GREEN, TEST_LOCATION );
+
+ const std::string fontFamily = field.GetProperty( TextField::Property::INPUT_FONT_FAMILY ).Get<std::string>();
+ DALI_TEST_EQUALS( fontFamily, "DejaVuSerif", TEST_LOCATION );
+
+ const float pointSize = field.GetProperty( TextField::Property::INPUT_POINT_SIZE ).Get<float>();
+ DALI_TEST_EQUALS( pointSize, 18.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ }
+ DALI_TEST_CHECK( inputStyleChangedSignal );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+
+ // 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<unsigned int>( gInputStyleMask ),
+ static_cast<unsigned int>( TextField::InputStyle::COLOR ),
+ TEST_LOCATION );
+
+ const Vector4 color = field.GetProperty( TextField::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::BLUE, TEST_LOCATION );
+ }
+ DALI_TEST_CHECK( inputStyleChangedSignal );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+
+ // 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 );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+
+ // 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<unsigned int>( gInputStyleMask ),
+ static_cast<unsigned int>( TextField::InputStyle::COLOR ),
+ TEST_LOCATION );
+
+ const Vector4 color = field.GetProperty( TextField::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::BLACK, TEST_LOCATION );
+ }
+ DALI_TEST_CHECK( inputStyleChangedSignal );
+
+ gInputStyleChangedCallbackCalled = false;
+ gInputStyleMask = TextField::InputStyle::NONE;
+ inputStyleChangedSignal = false;
+
+ field.SetProperty( TextField::Property::INPUT_COLOR, Color::YELLOW );
+
+ field.SetProperty( TextField::Property::INPUT_FONT_STYLE, "{\"weight\":\"thin\",\"width\":\"condensed\",\"slant\":\"italic\"}" );
+ field.SetProperty( TextField::Property::INPUT_POINT_SIZE, 20.f );
+
+ field.SetProperty( TextField::Property::INPUT_UNDERLINE, "underline" );
+ field.SetProperty( TextField::Property::INPUT_SHADOW, "shadow" );
+ field.SetProperty( TextField::Property::INPUT_EMBOSS, "emboss" );
+ field.SetProperty( TextField::Property::INPUT_OUTLINE, "outline" );
+
+ // 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 );
+
+ // Create a tap event to touch the text field.
+ 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();
+
+ // 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<unsigned int>( gInputStyleMask ),
+ static_cast<unsigned int>( TextField::InputStyle::COLOR |
+ TextField::InputStyle::POINT_SIZE |
+ TextField::InputStyle::FONT_STYLE |
+ TextField::InputStyle::UNDERLINE |
+ TextField::InputStyle::SHADOW |
+ TextField::InputStyle::EMBOSS |
+ TextField::InputStyle::OUTLINE ),
+ TEST_LOCATION );
+
+ const Vector4 color = field.GetProperty( TextField::Property::INPUT_COLOR ).Get<Vector4>();
+ DALI_TEST_EQUALS( color, Color::BLACK, TEST_LOCATION );
+ }
+ DALI_TEST_CHECK( inputStyleChangedSignal );
END_TEST;
}
#include <dali/public-api/images/resource-image.h>
#include <dali/devel-api/adaptor-framework/virtual-keyboard.h>
#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/integration-api/adaptors/adaptor.h>
#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputOutline", STRING, INPUT_OUTLINE )
DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED )
+DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED )
DALI_TYPE_REGISTRATION_END()
{
editor.TextChangedSignal().Connect( tracker, functor );
}
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_INPUT_STYLE_CHANGED ) )
+ {
+ editor.InputStyleChangedSignal().Connect( tracker, functor );
+ }
else
{
// signalName does not match any signal
return mTextChangedSignal;
}
+Toolkit::TextEditor::InputStyleChangedSignalType& TextEditor::InputStyleChangedSignal()
+{
+ return mInputStyleChangedSignal;
+}
+
void TextEditor::OnInitialize()
{
Actor self = Self();
EnableClipping( true, size );
RenderText( updateTextType );
}
+
+ // 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.
+ if( !mController->IsInputStyleChangedSignalsQueueEmpty() )
+ {
+ if( Adaptor::IsAvailable() )
+ {
+ Adaptor& adaptor = Adaptor::Get();
+
+ if( NULL == mIdleCallback )
+ {
+ // @note: The callback manager takes the ownership of the callback object.
+ mIdleCallback = MakeCallback( this, &TextEditor::OnIdleSignal );
+ adaptor.AddIdle( mIdleCallback );
+ }
+ }
+ }
}
void TextEditor::RenderText( Text::Controller::UpdateTextType updateTextType )
mTextChangedSignal.Emit( handle );
}
+void TextEditor::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
+{
+ Dali::Toolkit::TextEditor handle( GetOwner() );
+
+ Toolkit::TextEditor::InputStyle::Mask editorInputStyleMask = Toolkit::TextEditor::InputStyle::NONE;
+
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_COLOR ) )
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>( editorInputStyleMask | Toolkit::TextEditor::InputStyle::COLOR );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_FAMILY ) )
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>( editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_FAMILY );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_POINT_SIZE ) )
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>( editorInputStyleMask | Toolkit::TextEditor::InputStyle::POINT_SIZE );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_WEIGHT ) )
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>( editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_WIDTH ) )
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>( editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_SLANT ) )
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>( editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_LINE_SPACING ) )
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>( editorInputStyleMask | Toolkit::TextEditor::InputStyle::LINE_SPACING );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_UNDERLINE ) )
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>( editorInputStyleMask | Toolkit::TextEditor::InputStyle::UNDERLINE );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_SHADOW ) )
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>( editorInputStyleMask | Toolkit::TextEditor::InputStyle::SHADOW );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_EMBOSS ) )
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>( editorInputStyleMask | Toolkit::TextEditor::InputStyle::EMBOSS );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_OUTLINE ) )
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>( editorInputStyleMask | Toolkit::TextEditor::InputStyle::OUTLINE );
+ }
+
+ mInputStyleChangedSignal.Emit( handle, editorInputStyleMask );
+}
+
void TextEditor::MaxLengthReached()
{
// Nothing to do as TextEditor doesn't emit a max length reached signal.
return true;
}
+void TextEditor::OnIdleSignal()
+{
+ // Emits the change of input style signals.
+ mController->ProcessInputStyleChangedSignals();
+
+ // Set the pointer to null as the callback manager deletes the callback after execute it.
+ mIdleCallback = NULL;
+}
+
TextEditor::TextEditor()
: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
+ mIdleCallback( NULL ),
mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
mHasBeenStaged( false )
{
TextEditor::~TextEditor()
{
mClipper.Reset();
+
+ if( ( NULL != mIdleCallback ) && Adaptor::IsAvailable() )
+ {
+ // Removes the callback from the callback manager in case the text-editor is destroyed before the callback is executed.
+ Adaptor::Get().RemoveIdle( mIdleCallback );
+ }
}
} // namespace Internal
*/
Toolkit::TextEditor::TextChangedSignalType& TextChangedSignal();
+ /**
+ * @copydoc TextEditor::TextChangedSignal()
+ */
+ Toolkit::TextEditor::InputStyleChangedSignalType& InputStyleChangedSignal();
+
private: // From Control
/**
*/
virtual void MaxLengthReached();
+ /**
+ * @copydoc Text::ControlInterface::InputStyleChanged()
+ */
+ virtual void InputStyleChanged( Text::InputStyle::Mask inputStyleMask );
+
private: // Implementation
/**
bool OnTouched( Actor actor, const TouchData& touch );
/**
+ * @brief Callbacks called on idle.
+ *
+ * If there are notifications of change of input style on the queue, Toolkit::TextEditor::InputStyleChangedSignal() are emitted.
+ */
+ void OnIdleSignal();
+
+ /**
* Construct a new TextEditor.
*/
TextEditor();
// Signals
Toolkit::TextEditor::TextChangedSignalType mTextChangedSignal;
+ Toolkit::TextEditor::InputStyleChangedSignalType mInputStyleChangedSignal;
Text::ControllerPtr mController;
Text::RendererPtr mRenderer;
std::vector<Actor> mClippingDecorationActors; ///< Decoration actors which need clipping.
Actor mRenderableActor;
+ CallbackBase* mIdleCallback;
int mRenderingBackend;
bool mHasBeenStaged:1;
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
#include <dali/public-api/images/resource-image.h>
#include <dali/devel-api/adaptor-framework/virtual-keyboard.h>
#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/integration-api/adaptors/adaptor.h>
#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged", SIGNAL_TEXT_CHANGED )
DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED )
+DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED )
DALI_TYPE_REGISTRATION_END()
{
field.MaxLengthReachedSignal().Connect( tracker, functor );
}
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_INPUT_STYLE_CHANGED ) )
+ {
+ field.InputStyleChangedSignal().Connect( tracker, functor );
+ }
else
{
// signalName does not match any signal
return mMaxLengthReachedSignal;
}
+Toolkit::TextField::InputStyleChangedSignalType& TextField::InputStyleChangedSignal()
+{
+ return mInputStyleChangedSignal;
+}
+
void TextField::OnInitialize()
{
Actor self = Self();
EnableClipping( ( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy ), size );
RenderText( updateTextType );
}
+
+ // The text-field 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-field adds an idle callback to the adaptor to emit the signals after the size negotiation.
+ if( !mController->IsInputStyleChangedSignalsQueueEmpty() )
+ {
+ if( Adaptor::IsAvailable() )
+ {
+ Adaptor& adaptor = Adaptor::Get();
+
+ if( NULL == mIdleCallback )
+ {
+ // @note: The callback manager takes the ownership of the callback object.
+ mIdleCallback = MakeCallback( this, &TextField::OnIdleSignal );
+ adaptor.AddIdle( mIdleCallback );
+ }
+ }
+ }
}
-void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
+ void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
{
Actor self = Self();
Actor renderableActor;
mTextChangedSignal.Emit( handle );
}
+void TextField::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
+{
+ Dali::Toolkit::TextField handle( GetOwner() );
+
+ Toolkit::TextField::InputStyle::Mask fieldInputStyleMask = Toolkit::TextField::InputStyle::NONE;
+
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_COLOR ) )
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::COLOR );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_FAMILY ) )
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_FAMILY );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_POINT_SIZE ) )
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::POINT_SIZE );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_WEIGHT ) )
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_WIDTH ) )
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_SLANT ) )
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_UNDERLINE ) )
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::UNDERLINE );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_SHADOW ) )
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::SHADOW );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_EMBOSS ) )
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::EMBOSS );
+ }
+ if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_OUTLINE ) )
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::OUTLINE );
+ }
+
+ mInputStyleChangedSignal.Emit( handle, fieldInputStyleMask );
+}
+
void TextField::OnStageConnect( Dali::Actor actor )
{
if ( mHasBeenStaged )
return true;
}
+void TextField::OnIdleSignal()
+{
+ // Emits the change of input style signals.
+ mController->ProcessInputStyleChangedSignals();
+
+ // Set the pointer to null as the callback manager deletes the callback after execute it.
+ mIdleCallback = NULL;
+}
+
TextField::TextField()
: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
+ mIdleCallback( NULL ),
mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP ),
mHasBeenStaged( false )
TextField::~TextField()
{
mClipper.Reset();
+
+ if( ( NULL != mIdleCallback ) && Adaptor::IsAvailable() )
+ {
+ Adaptor::Get().RemoveIdle( mIdleCallback );
+ }
}
} // namespace Internal
#define __DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H__
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
*/
Toolkit::TextField::MaxLengthReachedSignalType& MaxLengthReachedSignal();
+ /**
+ * @copydoc TextField::TextChangedSignal()
+ */
+ Toolkit::TextField::InputStyleChangedSignalType& InputStyleChangedSignal();
+
private: // From Control
/**
*/
virtual void MaxLengthReached();
+ /**
+ * @copydoc Text::ControlInterface::InputStyleChanged()
+ */
+ virtual void InputStyleChanged( Text::InputStyle::Mask inputStyleMask );
+
private: // Implementation
/**
bool OnTouched( Actor actor, const TouchData& touch );
/**
+ * @brief Callbacks called on idle.
+ *
+ * If there are notifications of change of input style on the queue, Toolkit::TextField::InputStyleChangedSignal() are emitted.
+ */
+ void OnIdleSignal();
+
+ /**
* Construct a new TextField.
*/
TextField();
// Signals
Toolkit::TextField::TextChangedSignalType mTextChangedSignal;
Toolkit::TextField::MaxLengthReachedSignalType mMaxLengthReachedSignal;
+ Toolkit::TextField::InputStyleChangedSignalType mInputStyleChangedSignal;
Text::ControllerPtr mController;
Text::RendererPtr mRenderer;
std::vector<Actor> mClippingDecorationActors; ///< Decoration actors which need clipping.
Actor mRenderableActor;
+ CallbackBase* mIdleCallback;
int mRenderingBackend;
int mExceedPolicy;
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
void TextLabel::TextChanged()
{
- // TextLabel does not provide a signal for this
+ // TextLabel does not provide a signal for this.
}
void TextLabel::MaxLengthReached()
// Pure Virtual from TextController Interface, only needed when inputting text
}
+void TextLabel::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
+{
+ // TextLabel does not provide a signal for this.
+}
+
void TextLabel::ScrollingFinished()
{
// Pure Virtual from TextScroller Interface
#define __DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H__
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
*/
virtual void MaxLengthReached();
+ /**
+ * @copydoc Text::ControlInterface::InputStyleChanged()
+ */
+ virtual void InputStyleChanged( Text::InputStyle::Mask inputStyleMask );
+
private: // from TextScroller
/**
*/
// EXTERNAL INCLUDES
-#include <dali/public-api/math/vector4.h>
+#include <dali/public-api/common/constants.h>
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/text-definitions.h>
*/
struct InputStyle
{
+ enum Mask
+ {
+ NONE = 0x0000,
+ INPUT_COLOR = 0x0001,
+ INPUT_FONT_FAMILY = 0x0002,
+ INPUT_POINT_SIZE = 0x0004,
+ INPUT_FONT_WEIGHT = 0x0008,
+ INPUT_FONT_WIDTH = 0x0010,
+ INPUT_FONT_SLANT = 0x0020,
+ INPUT_LINE_SPACING = 0x0040,
+ INPUT_UNDERLINE = 0x0080,
+ INPUT_SHADOW = 0x0100,
+ INPUT_EMBOSS = 0x0200,
+ INPUT_OUTLINE = 0x0400
+ };
+
InputStyle()
: textColor( Color::BLACK ),
familyName(),
embossProperties(),
outlineProperties(),
isDefaultColor( true ),
- familyDefined( false ),
- weightDefined( false ),
- widthDefined( false ),
- slantDefined( false ),
- sizeDefined( false ),
- lineSpacingDefined( false )
- {}
+ isFamilyDefined( false ),
+ isWeightDefined( false ),
+ isWidthDefined( false ),
+ isSlantDefined( false ),
+ isSizeDefined( false ),
+ isLineSpacingDefined( false ),
+ isUnderlineDefined( false ),
+ isShadowDefined( false ),
+ isEmbossDefined( false ),
+ isOutlineDefined( false )
+ {}
~InputStyle()
{};
+ /**
+ * @brief
+ *
+ * Does not copy the font-style, underline, shadow, emboss and outline property strings.
+ */
+ void Copy( const InputStyle& inputStyle )
+ {
+ isDefaultColor = inputStyle.isDefaultColor;
+ textColor = inputStyle.textColor;
+
+ isFamilyDefined = inputStyle.isFamilyDefined;
+ familyName = inputStyle.familyName;
+
+ isWeightDefined = inputStyle.isWeightDefined;
+ weight = inputStyle.weight;
+
+ isWidthDefined = inputStyle.isWidthDefined;
+ width = inputStyle.width;
+
+ isSlantDefined = inputStyle.isSlantDefined;
+ slant = inputStyle.slant;
+
+ isSizeDefined = inputStyle.isSizeDefined;
+ size = inputStyle.size;
+
+ isLineSpacingDefined = inputStyle.isLineSpacingDefined;
+ lineSpacing = inputStyle.lineSpacing;
+
+ isUnderlineDefined = inputStyle.isUnderlineDefined;
+ underlineProperties = inputStyle.underlineProperties;
+
+ isShadowDefined = inputStyle.isShadowDefined;
+ shadowProperties = inputStyle.shadowProperties;
+
+ isEmbossDefined = inputStyle.isEmbossDefined;
+ embossProperties = inputStyle.embossProperties;
+
+ isOutlineDefined = inputStyle.isOutlineDefined;
+ outlineProperties = inputStyle.outlineProperties;
+ }
+
+ /**
+ * @brief
+ *
+ * Does not compare the font-style, underline, shadow, emboss and outline property strings.
+ */
+ bool Equal( const InputStyle& inputStyle ) const
+ {
+ if( ( isDefaultColor != inputStyle.isDefaultColor ) ||
+ ( isFamilyDefined != inputStyle.isFamilyDefined ) ||
+ ( isWeightDefined != inputStyle.isWeightDefined ) ||
+ ( isWidthDefined != inputStyle.isWidthDefined ) ||
+ ( isSlantDefined != inputStyle.isSlantDefined ) ||
+ ( isSizeDefined != inputStyle.isSizeDefined ) ||
+ ( isLineSpacingDefined != inputStyle.isLineSpacingDefined ) ||
+ ( isUnderlineDefined != inputStyle.isUnderlineDefined ) ||
+ ( isShadowDefined != inputStyle.isShadowDefined ) ||
+ ( isEmbossDefined != inputStyle.isEmbossDefined ) ||
+ ( isOutlineDefined != inputStyle.isOutlineDefined ) ||
+ ( textColor != inputStyle.textColor ) ||
+ ( familyName != inputStyle.familyName ) ||
+ ( weight != inputStyle.weight ) ||
+ ( width != inputStyle.width ) ||
+ ( slant != inputStyle.slant ) ||
+ ( size != inputStyle.size ) ||
+ ( lineSpacing != inputStyle.lineSpacing ) ||
+ ( underlineProperties != inputStyle.underlineProperties ) ||
+ ( shadowProperties != inputStyle.shadowProperties ) ||
+ ( embossProperties != inputStyle.embossProperties ) ||
+ ( outlineProperties != inputStyle.outlineProperties ) )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ Mask GetInputStyleChangeMask( const InputStyle& inputStyle ) const
+ {
+ Mask mask = NONE;
+
+ if( textColor != inputStyle.textColor )
+ {
+ mask = static_cast<Mask>( mask | INPUT_COLOR );
+ }
+ if( familyName != inputStyle.familyName )
+ {
+ mask = static_cast<Mask>( mask | INPUT_FONT_FAMILY );
+ }
+ if( weight != inputStyle.weight )
+ {
+ mask = static_cast<Mask>( mask | INPUT_FONT_WEIGHT );
+ }
+ if( width != inputStyle.width )
+ {
+ mask = static_cast<Mask>( mask | INPUT_FONT_WIDTH );
+ }
+ if( slant != inputStyle.slant )
+ {
+ mask = static_cast<Mask>( mask | INPUT_FONT_SLANT );
+ }
+ if( size != inputStyle.size )
+ {
+ mask = static_cast<Mask>( mask | INPUT_POINT_SIZE );
+ }
+ if( lineSpacing != inputStyle.lineSpacing )
+ {
+ mask = static_cast<Mask>( mask | INPUT_LINE_SPACING );
+ }
+ if( underlineProperties != inputStyle.underlineProperties )
+ {
+ mask = static_cast<Mask>( mask | INPUT_UNDERLINE );
+ }
+ if( shadowProperties != inputStyle.shadowProperties )
+ {
+ mask = static_cast<Mask>( mask | INPUT_SHADOW );
+ }
+ if( embossProperties != inputStyle.embossProperties )
+ {
+ mask = static_cast<Mask>( mask | INPUT_EMBOSS );
+ }
+ if( outlineProperties != inputStyle.outlineProperties )
+ {
+ mask = static_cast<Mask>( mask | INPUT_OUTLINE );
+ }
+
+ return mask;
+ }
+
Vector4 textColor; ///< The text's color.
std::string familyName; ///< The font's family name.
FontWeight weight; ///< The font's weight.
float size; ///< The font's size.
float lineSpacing; ///< The line's spacing.
+
std::string underlineProperties; ///< The underline properties string.
std::string shadowProperties; ///< The shadow properties string.
std::string embossProperties; ///< The emboss properties string.
std::string outlineProperties; ///< The outline properties string.
- bool isDefaultColor : 1; ///< Whether the text's color is the default.
- bool familyDefined : 1; ///< Whether the font's family is defined.
- bool weightDefined : 1; ///< Whether the font's weight is defined.
- bool widthDefined : 1; ///< Whether the font's width is defined.
- bool slantDefined : 1; ///< Whether the font's slant is defined.
- bool sizeDefined : 1; ///< Whether the font's size is defined.
-
- bool lineSpacingDefined : 1; ///< Whether the line spacing is defined.
+ bool isDefaultColor : 1; ///< Whether the text's color is the default.
+ bool isFamilyDefined : 1; ///< Whether the font's family is defined.
+ bool isWeightDefined : 1; ///< Whether the font's weight is defined.
+ bool isWidthDefined : 1; ///< Whether the font's width is defined.
+ bool isSlantDefined : 1; ///< Whether the font's slant is defined.
+ bool isSizeDefined : 1; ///< Whether the font's size is defined.
+
+ bool isLineSpacingDefined : 1; ///< Whether the line spacing is defined.
+ bool isUnderlineDefined : 1; ///< Whether the underline parameters are defined.
+ bool isShadowDefined : 1; ///< Whether the shadow parameters are defined.
+ bool isEmbossDefined : 1; ///< Whether the emboss parameters are defined.
+ bool isOutlineDefined : 1; ///< Whether the outline parameters are defined.
};
} // namespace Text
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + nameIndex );
style.familyName = std::string( fontDescriptionRun.familyName, fontDescriptionRun.familyLength );
- style.familyDefined = true;
+ style.isFamilyDefined = true;
}
// Set the font's weight if it's overriden.
const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + weightIndex );
style.weight = fontDescriptionRun.weight;
- style.weightDefined = true;
+ style.isWeightDefined = true;
}
// Set the font's width if it's overriden.
const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + widthIndex );
style.width = fontDescriptionRun.width;
- style.widthDefined = true;
+ style.isWidthDefined = true;
}
// Set the font's slant if it's overriden.
const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + slantIndex );
style.slant = fontDescriptionRun.slant;
- style.slantDefined = true;
+ style.isSlantDefined = true;
}
// Set the font's size if it's overriden.
const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + sizeIndex );
style.size = static_cast<float>( fontDescriptionRun.size ) / 64.f;
- style.sizeDefined = true;
+ style.isSizeDefined = true;
}
}
#define __DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H__
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
*
*/
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/input-style.h>
+
namespace Dali
{
* @brief Called when the number of characters to be inserted exceeds the maximum limit
*/
virtual void MaxLengthReached() = 0;
+
+ /**
+ * @brief Called to signal that input style has been changed.
+ *
+ * @param[in] inputStyleMask Mask with the bits of the input style that has changed.
+ */
+ virtual void InputStyleChanged( InputStyle::Mask inputStyleMask ) = 0;
};
} // namespace Text
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
mPlaceholderTextInactive(),
mPlaceholderTextColor( 0.8f, 0.8f, 0.8f, 0.8f ),
mEventQueue(),
+ mInputStyleChangedQueue(),
mState( INACTIVE ),
mPrimaryCursorPosition( 0u ),
mLeftSelectionPosition( 0u ),
if( mEventData->mUpdateInputStyle )
{
+ // Keep a copy of the current input style.
+ InputStyle currentInputStyle;
+ currentInputStyle.Copy( mEventData->mInputStyle );
+
// Set the default style first.
RetrieveDefaultInputStyle( mEventData->mInputStyle );
// Retrieve the style from the style runs stored in the logical model.
mLogicalModel->RetrieveStyle( styleIndex, mEventData->mInputStyle );
+ // Compare if the input style has changed.
+ const bool hasInputStyleChanged = !currentInputStyle.Equal( mEventData->mInputStyle );
+
+ if( hasInputStyleChanged )
+ {
+ const InputStyle::Mask styleChangedMask = currentInputStyle.GetInputStyleChangeMask( mEventData->mInputStyle );
+ // Queue the input style changed signal.
+ mEventData->mInputStyleChangedQueue.PushBack( styleChangedMask );
+ }
+
mEventData->mUpdateInputStyle = false;
}
inputStyle.slant = TextAbstraction::FontSlant::NORMAL;
inputStyle.size = 0.f;
- inputStyle.familyDefined = false;
- inputStyle.weightDefined = false;
- inputStyle.widthDefined = false;
- inputStyle.slantDefined = false;
- inputStyle.sizeDefined = false;
+ inputStyle.lineSpacing = 0.f;
+
+ inputStyle.underlineProperties.clear();
+ inputStyle.shadowProperties.clear();
+ inputStyle.embossProperties.clear();
+ inputStyle.outlineProperties.clear();
+
+ inputStyle.isFamilyDefined = false;
+ inputStyle.isWeightDefined = false;
+ inputStyle.isWidthDefined = false;
+ inputStyle.isSlantDefined = false;
+ inputStyle.isSizeDefined = false;
+
+ inputStyle.isLineSpacingDefined = false;
+
+ inputStyle.isUnderlineDefined = false;
+ inputStyle.isShadowDefined = false;
+ inputStyle.isEmbossDefined = false;
+ inputStyle.isOutlineDefined = false;
// Sets the default font's family name, weight, width, slant and size.
if( mFontDefaults )
if( mFontDefaults->familyDefined )
{
inputStyle.familyName = mFontDefaults->mFontDescription.family;
- inputStyle.familyDefined = true;
+ inputStyle.isFamilyDefined = true;
}
if( mFontDefaults->weightDefined )
{
inputStyle.weight = mFontDefaults->mFontDescription.weight;
- inputStyle.weightDefined = true;
+ inputStyle.isWeightDefined = true;
}
if( mFontDefaults->widthDefined )
{
inputStyle.width = mFontDefaults->mFontDescription.width;
- inputStyle.widthDefined = true;
+ inputStyle.isWidthDefined = true;
}
if( mFontDefaults->slantDefined )
{
inputStyle.slant = mFontDefaults->mFontDescription.slant;
- inputStyle.slantDefined = true;
+ inputStyle.isSlantDefined = true;
}
if( mFontDefaults->sizeDefined )
{
inputStyle.size = mFontDefaults->mDefaultPointSize;
- inputStyle.sizeDefined = true;
+ inputStyle.isSizeDefined = true;
}
}
}
if( deleteAfterRetrieval ) // Only delete text if copied successfully
{
+ // Keep a copy of the current input style.
+ InputStyle currentInputStyle;
+ currentInputStyle.Copy( mEventData->mInputStyle );
+
// Set as input style the style of the first deleted character.
mLogicalModel->RetrieveStyle( startOfSelectedText, mEventData->mInputStyle );
+ // Compare if the input style has changed.
+ const bool hasInputStyleChanged = !currentInputStyle.Equal( mEventData->mInputStyle );
+
+ if( hasInputStyleChanged )
+ {
+ const InputStyle::Mask styleChangedMask = currentInputStyle.GetInputStyleChangeMask( mEventData->mInputStyle );
+ // Queue the input style changed signal.
+ mEventData->mInputStyleChangedQueue.PushBack( styleChangedMask );
+ }
+
mLogicalModel->UpdateTextStyleRuns( startOfSelectedText, -static_cast<int>( lengthOfSelectedText ) );
// Mark the paragraphs to be updated.
*/
std::vector<Event> mEventQueue; ///< The queue of touch events etc.
+ Vector<InputStyle::Mask> mInputStyleChangedQueue; ///< Queue of changes in the input style. Used to emit the signal in the iddle callback.
+
InputStyle mInputStyle; ///< The style to be set to the new inputed text.
State mPreviousState; ///< Stores the current state before it's updated with the new one.
if( UPDATE_INPUT_STYLE == type )
{
+ // Keep a copy of the current input style.
+ InputStyle currentInputStyle;
+ currentInputStyle.Copy( mImpl->mEventData->mInputStyle );
+
// Set first the default input style.
mImpl->RetrieveDefaultInputStyle( mImpl->mEventData->mInputStyle );
// Update the input style.
mImpl->mLogicalModel->RetrieveStyle( cursorIndex, mImpl->mEventData->mInputStyle );
+
+ // Compare if the input style has changed.
+ const bool hasInputStyleChanged = !currentInputStyle.Equal( mImpl->mEventData->mInputStyle );
+
+ if( hasInputStyleChanged )
+ {
+ const InputStyle::Mask styleChangedMask = currentInputStyle.GetInputStyleChangeMask( mImpl->mEventData->mInputStyle );
+ // Queue the input style changed signal.
+ mImpl->mEventData->mInputStyleChangedQueue.PushBack( styleChangedMask );
+ }
}
// Updates the text style runs by removing characters. Runs with no characters are removed.
if( NULL != mImpl->mEventData )
{
mImpl->mEventData->mInputStyle.familyName = fontFamily;
- mImpl->mEventData->mInputStyle.familyDefined = true;
+ mImpl->mEventData->mInputStyle.isFamilyDefined = true;
if( EventData::SELECTING == mImpl->mEventData->mState )
{
if( NULL != mImpl->mEventData )
{
mImpl->mEventData->mInputStyle.weight = weight;
- mImpl->mEventData->mInputStyle.weightDefined = true;
+ mImpl->mEventData->mInputStyle.isWeightDefined = true;
if( EventData::SELECTING == mImpl->mEventData->mState )
{
if( NULL != mImpl->mEventData )
{
- defined = mImpl->mEventData->mInputStyle.weightDefined;
+ defined = mImpl->mEventData->mInputStyle.isWeightDefined;
}
return defined;
if( NULL != mImpl->mEventData )
{
mImpl->mEventData->mInputStyle.width = width;
- mImpl->mEventData->mInputStyle.widthDefined = true;
+ mImpl->mEventData->mInputStyle.isWidthDefined = true;
if( EventData::SELECTING == mImpl->mEventData->mState )
{
if( NULL != mImpl->mEventData )
{
- defined = mImpl->mEventData->mInputStyle.widthDefined;
+ defined = mImpl->mEventData->mInputStyle.isWidthDefined;
}
return defined;
if( NULL != mImpl->mEventData )
{
mImpl->mEventData->mInputStyle.slant = slant;
- mImpl->mEventData->mInputStyle.slantDefined = true;
+ mImpl->mEventData->mInputStyle.isSlantDefined = true;
if( EventData::SELECTING == mImpl->mEventData->mState )
{
if( NULL != mImpl->mEventData )
{
- defined = mImpl->mEventData->mInputStyle.slantDefined;
+ defined = mImpl->mEventData->mInputStyle.isSlantDefined;
}
return defined;
if( NULL != mImpl->mEventData )
{
mImpl->mEventData->mInputStyle.size = size;
+ mImpl->mEventData->mInputStyle.isSizeDefined = true;
if( EventData::SELECTING == mImpl->mEventData->mState )
{
if( NULL != mImpl->mEventData )
{
mImpl->mEventData->mInputStyle.lineSpacing = lineSpacing;
+ mImpl->mEventData->mInputStyle.isLineSpacingDefined = true;
}
}
events.Clear();
}
+bool Controller::IsInputStyleChangedSignalsQueueEmpty()
+{
+ return ( NULL == mImpl->mEventData ) || ( 0u == mImpl->mEventData->mInputStyleChangedQueue.Count() );
+}
+
+void Controller::ProcessInputStyleChangedSignals()
+{
+ if( NULL == mImpl->mEventData )
+ {
+ // Nothing to do.
+ return;
+ }
+
+ for( Vector<InputStyle::Mask>::ConstIterator it = mImpl->mEventData->mInputStyleChangedQueue.Begin(),
+ endIt = mImpl->mEventData->mInputStyleChangedQueue.End();
+ it != endIt;
+ ++it )
+ {
+ const InputStyle::Mask mask = *it;
+
+ // Emit the input style changed signal.
+ mImpl->mControlInterface.InputStyleChanged( mask );
+ }
+
+ mImpl->mEventData->mInputStyleChangedQueue.Clear();
+}
+
void Controller::ResetText()
{
// Reset buffers.
{
mImpl->mOperationsPending = ALL_OPERATIONS;
mImpl->RequestRelayout();
-
- // Do this last since it provides callbacks into application code
- mImpl->mControlInterface.TextChanged();
}
std::string text;
ImfManager::ImfCallbackData callbackData( ( retrieveText || retrieveCursor ), cursorPosition, text, false );
+ if( requestRelayout )
+ {
+ // Do this last since it provides callbacks into application code
+ mImpl->mControlInterface.TextChanged();
+ }
+
return callbackData;
}
void ProcessModifyEvents();
/**
+ * @return Whether the queue of input style changed signals is empty.
+ */
+ bool IsInputStyleChangedSignalsQueueEmpty();
+
+ /**
+ * @brief Process all pending input style changed signals.
+ *
+ * Calls the Text::ControlInterface::InputStyleChanged() method which is overriden by the
+ * text controls. Text controls may send signals to state the input style has changed.
+ */
+ void ProcessInputStyleChangedSignals();
+
+ /**
* @brief Used to remove placeholder text.
*/
void ResetText();
return Dali::Toolkit::GetImpl( *this ).TextChangedSignal();
}
+TextEditor::InputStyleChangedSignalType& TextEditor::InputStyleChangedSignal()
+{
+ return Dali::Toolkit::GetImpl( *this ).InputStyleChangedSignal();
+}
+
TextEditor::TextEditor( Internal::TextEditor& implementation )
: Control( implementation )
{
* @brief A control which provides a multi-line editable text editor.
*
* * Signals
- * | %Signal Name | Method |
- * |----------------------|-----------------------------------------------------|
- * | textChanged | @ref TextChangedSignal() |
+ * | %Signal Name | Method | |
+ * |----------------------|--------------------------------|--------------------|
+ * | textChanged | @ref TextChangedSignal() | @SINCE_1_1.37 |
+ * | inputStyleChanged | @ref InputStyleChangedSignal() | @SINCE_1_2.2 |
*
*/
class DALI_IMPORT_API TextEditor : public Control
/**
* @brief The start and end property ranges for this control.
+ * @SINCE_1_1.37
*/
enum PropertyRange
{
/**
* @brief An enumeration of properties belonging to the TextEditor class.
+ * @SINCE_1_1.37
*/
struct Property
{
};
};
+ /**
+ * @brief Mask used by the signal InputStyleChangedSignal(). Notifies which parameters of the input style have changed.
+ *
+ * @SINCE_1_2.2
+ */
+ struct InputStyle
+ {
+ enum Mask
+ {
+ NONE = 0x0000, ///< @SINCE_1_2.2
+ COLOR = 0x0001, ///< @SINCE_1_2.2
+ FONT_FAMILY = 0x0002, ///< @SINCE_1_2.2
+ POINT_SIZE = 0x0004, ///< @SINCE_1_2.2
+ FONT_STYLE = 0x0008, ///< @SINCE_1_2.2
+ LINE_SPACING = 0x0010, ///< @SINCE_1_2.2
+ UNDERLINE = 0x0020, ///< @SINCE_1_2.2
+ SHADOW = 0x0040, ///< @SINCE_1_2.2
+ EMBOSS = 0x0080, ///< @SINCE_1_2.2
+ OUTLINE = 0x0100 ///< @SINCE_1_2.2
+ };
+ };
+
// Type Defs
- /// @brief Text changed signal type.
+ /**
+ * @brief Text changed signal type.
+ * @SINCE_1_1.37
+ */
typedef Signal<void ( TextEditor ) > TextChangedSignalType;
/**
+ * @brief Input Style changed signal type.
+ * @SINCE_1_2.2
+ */
+ typedef Signal<void ( TextEditor, InputStyle::Mask ) > InputStyleChangedSignalType;
+
+ /**
* @brief Create the TextEditor control.
+ *
+ * @SINCE_1_1.37
* @return A handle to the TextEditor control.
*/
static TextEditor New();
/**
* @brief Creates an empty handle.
+ *
+ * @SINCE_1_1.37
*/
TextEditor();
/**
* @brief Copy constructor.
*
+ * @SINCE_1_1.37
* @param[in] handle The handle to copy from.
*/
TextEditor( const TextEditor& handle );
/**
* @brief Assignment operator.
*
+ * @SINCE_1_1.37
* @param[in] handle The handle to copy from.
* @return A reference to this.
*/
* @brief Destructor.
*
* This is non-virtual since derived Handle types must not contain data or virtual methods.
+ * @SINCE_1_1.37
*/
~TextEditor();
* If the BaseHandle points is a TextEditor the downcast returns a valid handle.
* If not the returned handle is left empty.
*
+ * @SINCE_1_1.37
* @param[in] handle Handle to an object.
* @return handle to a TextEditor or an empty handle.
*/
* @code
* void YourCallbackName( TextEditor textEditor );
* @endcode
+ *
+ * @SINCE_1_1.37
* @return The signal to connect to.
*/
TextChangedSignalType& TextChangedSignal();
+ /**
+ * @brief This signal is emitted when the input style is updated as a consequence of a change in the cursor position.
+ * i.e. The signal is not emitted when the input style is updated through the property system.
+ *
+ * A callback of the following type may be connected. The @p mask parameter notifies which parts of the style have changed.
+ * @code
+ * void YourCallbackName( TextEditor textEditor, TextEditor::InputStyle::Mask mask );
+ * @endcode
+ *
+ * @SINCE_1_2.2
+ * @return The signal to connect to.
+ */
+ InputStyleChangedSignalType& InputStyleChangedSignal();
+
public: // Not intended for application developers
/// @cond internal
/**
* @brief Creates a handle using the Toolkit::Internal implementation.
*
+ * @SINCE_1_1.37
* @param[in] implementation The Control implementation.
*/
DALI_INTERNAL TextEditor( Internal::TextEditor& implementation );
/**
* @brief Allows the creation of this Control from an Internal::CustomActor pointer.
*
+ * @SINCE_1_1.37
* @param[in] internal A pointer to the internal CustomActor.
*/
explicit DALI_INTERNAL TextEditor( Dali::Internal::CustomActor* internal );
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
return Dali::Toolkit::GetImpl( *this ).MaxLengthReachedSignal();
}
+TextField::InputStyleChangedSignalType& TextField::InputStyleChangedSignal()
+{
+ return Dali::Toolkit::GetImpl( *this ).InputStyleChangedSignal();
+}
+
TextField::TextField( Internal::TextField& implementation )
: Control(implementation)
{
#define __DALI_TOOLKIT_TEXT_FIELD_H__
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
* @brief A control which provides a single-line editable text field.
*
* * Signals
- * | %Signal Name | Method |
- * |----------------------|-----------------------------------------------------|
- * | textChanged | @ref TextChangedSignal() |
- * | maxLengthReached | @ref MaxLengthReachedSignal() |
- *
- * @SINCE_1_0.0
+ * | %Signal Name | Method | |
+ * |----------------------|--------------------------------|--------------------|
+ * | textChanged | @ref TextChangedSignal() | @SINCE_1_0.0 |
+ * | maxLengthReached | @ref MaxLengthReachedSignal() | @SINCE_1_0.0 |
+ * | inputStyleChanged | @ref InputStyleChangedSignal() | @SINCE_1_2.2 |
*/
class DALI_IMPORT_API TextField : public Control
{
EXCEED_POLICY_CLIP ///< The end of text will be clipped to fit within the TextField. @SINCE_1_0.0
};
+ /**
+ * @brief Mask used by the signal InputStyleChangedSignal(). Notifies which parameters of the input style have changed.
+ *
+ * @SINCE_1_2.2
+ */
+ struct InputStyle
+ {
+ enum Mask
+ {
+ NONE = 0x0000, ///< @SINCE_1_2.2
+ COLOR = 0x0001, ///< @SINCE_1_2.2
+ FONT_FAMILY = 0x0002, ///< @SINCE_1_2.2
+ POINT_SIZE = 0x0004, ///< @SINCE_1_2.2
+ FONT_STYLE = 0x0008, ///< @SINCE_1_2.2
+ UNDERLINE = 0x0010, ///< @SINCE_1_2.2
+ SHADOW = 0x0020, ///< @SINCE_1_2.2
+ EMBOSS = 0x0040, ///< @SINCE_1_2.2
+ OUTLINE = 0x0080 ///< @SINCE_1_2.2
+ };
+ };
+
// Type Defs
- /// @brief Text changed signal type.
+ /**
+ * @brief Text changed signal type.
+ * @SINCE_1_0.0
+ */
typedef Signal<void ( TextField ) > TextChangedSignalType;
- /// @brief Max Characters Exceed signal type.
+
+ /**
+ * @brief Max Characters Exceed signal type.
+ * @SINCE_1_0.0
+ */
typedef Signal<void ( TextField ) > MaxLengthReachedSignalType;
/**
+ * @brief Input Style changed signal type.
+ * @SINCE_1_2.2
+ */
+ typedef Signal<void ( TextField, InputStyle::Mask ) > InputStyleChangedSignalType;
+
+ /**
* @brief Create the TextField control.
* @SINCE_1_0.0
* @return A handle to the TextField control.
*/
MaxLengthReachedSignalType& MaxLengthReachedSignal();
+ /**
+ * @brief This signal is emitted when the input style is updated as a consequence of a change in the cursor position.
+ * i.e. The signal is not emitted when the input style is updated through the property system.
+ *
+ * A callback of the following type may be connected. The @p mask parameter notifies which parts of the style have changed.
+ * @code
+ * void YourCallbackName( TextField textField, TextField::InputStyle::Mask mask );
+ * @endcode
+ *
+ * @SINCE_1_2.2
+ * @return The signal to connect to.
+ */
+ InputStyleChangedSignalType& InputStyleChangedSignal();
+
public: // Not intended for application developers
/**