[dali_2.0.33] Merge branch 'devel/master' 96/260796/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 2 Jul 2021 16:41:51 +0000 (17:41 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 2 Jul 2021 16:41:51 +0000 (17:41 +0100)
Change-Id: I09bb61f68ab74b065ec8bf0ab62e4c712c3cae18

93 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
dali-toolkit/dali-toolkit.h
dali-toolkit/devel-api/controls/accessible-impl.cpp
dali-toolkit/devel-api/controls/accessible-impl.h
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.cpp
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h
dali-toolkit/devel-api/controls/text-controls/text-field-devel.cpp
dali-toolkit/devel-api/controls/text-controls/text-field-devel.h
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/file.list
dali-toolkit/internal/text/input-filter.cpp [new file with mode: 0644]
dali-toolkit/internal/text/input-filter.h [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor-color.cpp
dali-toolkit/internal/text/markup-processor-color.h
dali-toolkit/internal/text/markup-processor-font.cpp
dali-toolkit/internal/text/markup-processor-font.h
dali-toolkit/internal/text/markup-processor-span.cpp [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor-span.h [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor.cpp
dali-toolkit/internal/text/text-controller-event-handler.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller-relayouter.cpp
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-editable-control-interface.h
dali-toolkit/internal/transition/fade-impl.cpp
dali-toolkit/internal/transition/transition-lifecycle-controller.cpp
dali-toolkit/internal/transition/transition-lifecycle-controller.h
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/internal/visuals/visual-url.cpp
dali-toolkit/internal/visuals/visual-url.h
dali-toolkit/po/ar.po
dali-toolkit/po/az.po
dali-toolkit/po/bg.po
dali-toolkit/po/bn_BD.po
dali-toolkit/po/ca.po
dali-toolkit/po/cs.po
dali-toolkit/po/da.po
dali-toolkit/po/de.po
dali-toolkit/po/el_GR.po
dali-toolkit/po/en.po
dali-toolkit/po/en_US.po
dali-toolkit/po/es_ES.po
dali-toolkit/po/es_US.po
dali-toolkit/po/et.po
dali-toolkit/po/eu.po
dali-toolkit/po/fa.po
dali-toolkit/po/fi.po
dali-toolkit/po/fr.po
dali-toolkit/po/fr_CA.po
dali-toolkit/po/gl.po
dali-toolkit/po/hr.po
dali-toolkit/po/hu.po
dali-toolkit/po/hy.po
dali-toolkit/po/is.po
dali-toolkit/po/it_IT.po
dali-toolkit/po/ka.po
dali-toolkit/po/kk.po
dali-toolkit/po/ko_KR.po
dali-toolkit/po/lt.po
dali-toolkit/po/lv.po
dali-toolkit/po/mn_MN.po
dali-toolkit/po/nb.po
dali-toolkit/po/nl.po
dali-toolkit/po/pl.po
dali-toolkit/po/pt_BR.po
dali-toolkit/po/pt_PT.po
dali-toolkit/po/ro.po
dali-toolkit/po/ru_RU.po
dali-toolkit/po/sk.po
dali-toolkit/po/sl.po
dali-toolkit/po/sr.po
dali-toolkit/po/sv.po
dali-toolkit/po/tr_TR.po
dali-toolkit/po/uk.po
dali-toolkit/po/ur.po
dali-toolkit/po/uz.po
dali-toolkit/po/vi.po
dali-toolkit/po/zh_CN.po
dali-toolkit/public-api/controls/text-controls/input-filter-properties.h [new file with mode: 0644]
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/public-api/file.list
packaging/dali-toolkit.spec

index 73d9e12..09c5078 100755 (executable)
@@ -198,4 +198,68 @@ int UtcDaliTextEditorBackgroundTag(void)
   DALI_TEST_EQUALS( backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
 
   END_TEST;
+}
+
+int UtcDaliTextEditorTextWithSpan(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextEditorTextWithSpan\n");
+
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK( editor );
+
+  editor.SetProperty( TextEditor ::Property::ENABLE_MARKUP,  true );
+  editor.SetProperty( TextEditor::Property::TEXT, "Hello Span" );
+  application.GetScene().Add( editor );
+
+  application.SendNotification();
+  application.Render();
+
+  Vector3 originalSize = editor.GetNaturalSize();
+  editor.SetProperty( TextEditor::Property::TEXT, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> Span" );
+
+  application.SendNotification();
+  application.Render();
+
+  Vector3 spanSize = editor.GetNaturalSize();
+
+  DALI_TEST_GREATER(spanSize.width, originalSize.width, TEST_LOCATION);
+
+  Toolkit::Internal::TextEditor& editorImpl = GetImpl( editor );
+  const ColorIndex* const colorIndicesBuffer1 = editorImpl.getController()->GetTextModel()->GetColorIndices();
+
+  DALI_TEST_CHECK( colorIndicesBuffer1 );
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer1[0], 0u, TEST_LOCATION);
+
+  //span color
+  DALI_TEST_EQUALS( colorIndicesBuffer1[1], 1u, TEST_LOCATION);
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer1[6], 0u, TEST_LOCATION);
+
+
+  editor.SetProperty( TextEditor::Property::TEXT, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan" );
+
+  application.SendNotification();
+  application.Render();
+
+  const ColorIndex* const colorIndicesBuffer2 = editorImpl.getController()->GetTextModel()->GetColorIndices();
+
+  DALI_TEST_CHECK( colorIndicesBuffer2 );
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[0], 0u, TEST_LOCATION);
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[1], 0u, TEST_LOCATION);
+
+  //span color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[6], 1u, TEST_LOCATION);
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[7], 0u, TEST_LOCATION);
+
+  END_TEST;
 }
\ No newline at end of file
index 73fe7e2..1fbc13e 100755 (executable)
@@ -282,4 +282,68 @@ int UtcDaliTextFieldBackgroundTag(void)
   DALI_TEST_EQUALS( backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
 
   END_TEST;
+}
+
+int UtcDaliTextFieldTextWithSpan(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextFieldTextWithSpan\n");
+
+  TextField field = TextField::New();
+  DALI_TEST_CHECK( field );
+
+  field.SetProperty( TextField ::Property::ENABLE_MARKUP,  true );
+  field.SetProperty( TextField::Property::TEXT, "Hello Span" );
+  application.GetScene().Add( field );
+
+  application.SendNotification();
+  application.Render();
+
+  Vector3 originalSize = field.GetNaturalSize();
+  field.SetProperty( TextField::Property::TEXT, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> Span" );
+
+  application.SendNotification();
+  application.Render();
+
+  Vector3 spanSize = field.GetNaturalSize();
+
+  DALI_TEST_GREATER(spanSize.width, originalSize.width, TEST_LOCATION);
+
+  Toolkit::Internal::TextField& fieldImpl = GetImpl( field );
+  const ColorIndex* const colorIndicesBuffer1 = fieldImpl.getController()->GetTextModel()->GetColorIndices();
+
+  DALI_TEST_CHECK( colorIndicesBuffer1 );
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer1[0], 0u, TEST_LOCATION);
+
+  //span color
+  DALI_TEST_EQUALS( colorIndicesBuffer1[1], 1u, TEST_LOCATION);
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer1[6], 0u, TEST_LOCATION);
+
+
+  field.SetProperty( TextField::Property::TEXT, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan" );
+
+  application.SendNotification();
+  application.Render();
+
+  const ColorIndex* const colorIndicesBuffer2 = fieldImpl.getController()->GetTextModel()->GetColorIndices();
+
+  DALI_TEST_CHECK( colorIndicesBuffer2 );
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[0], 0u, TEST_LOCATION);
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[1], 0u, TEST_LOCATION);
+
+  //span color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[6], 1u, TEST_LOCATION);
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[7], 0u, TEST_LOCATION);
+
+  END_TEST;
 }
\ No newline at end of file
index f67d88a..e03fec1 100755 (executable)
@@ -97,4 +97,68 @@ int UtcDaliTextLabelBackgroundTag(void)
   DALI_TEST_EQUALS( backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
 
   END_TEST;
+}
+
+int UtcDaliTextLabelTextWithSpan(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextLabelTextWithSpan\n");
+
+  TextLabel label = TextLabel::New();
+  DALI_TEST_CHECK( label );
+
+  label.SetProperty( TextLabel ::Property::ENABLE_MARKUP,  true );
+  label.SetProperty( TextLabel::Property::TEXT, "Hello Span" );
+  application.GetScene().Add( label );
+
+  application.SendNotification();
+  application.Render();
+
+  Vector3 originalSize = label.GetNaturalSize();
+  label.SetProperty( TextLabel::Property::TEXT, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> Span" );
+
+  application.SendNotification();
+  application.Render();
+
+  Vector3 spanSize = label.GetNaturalSize();
+
+  DALI_TEST_GREATER(spanSize.width, originalSize.width, TEST_LOCATION);
+
+  Toolkit::Internal::TextLabel& labelImpl = GetImpl( label );
+  const ColorIndex* const colorIndicesBuffer1 = labelImpl.getController()->GetTextModel()->GetColorIndices();
+
+  DALI_TEST_CHECK( colorIndicesBuffer1 );
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer1[0], 0u, TEST_LOCATION);
+
+  //span color
+  DALI_TEST_EQUALS( colorIndicesBuffer1[1], 1u, TEST_LOCATION);
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer1[6], 0u, TEST_LOCATION);
+
+
+  label.SetProperty( TextLabel::Property::TEXT, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan" );
+
+  application.SendNotification();
+  application.Render();
+
+  const ColorIndex* const colorIndicesBuffer2 = labelImpl.getController()->GetTextModel()->GetColorIndices();
+
+  DALI_TEST_CHECK( colorIndicesBuffer2 );
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[0], 0u, TEST_LOCATION);
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[1], 0u, TEST_LOCATION);
+
+  //span color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[6], 1u, TEST_LOCATION);
+
+  //default color
+  DALI_TEST_EQUALS( colorIndicesBuffer2[7], 0u, TEST_LOCATION);
+
+  END_TEST;
 }
\ No newline at end of file
index 474706f..2ccf2c1 100755 (executable)
@@ -52,6 +52,7 @@ public:
     mDelayTime(0),
     mDroppedFrames(0),
     mFrameRate( 60.0f ),
+    mTestFrameDrop(false),
     mNeedDroppedFrames(false),
     mEventThreadCallback( new EventThreadCallback( MakeCallback( this, &VectorAnimationRenderer::OnTriggered ) ) )
   {
@@ -71,7 +72,7 @@ public:
   bool Load(const std::string& url)
   {
     mUrl = url;
-    if(mUrl == "invalid.json" || mUrl == "invalid.riv")
+    if(mUrl == "invalid.json")
     {
       return false;
     }
@@ -79,6 +80,7 @@ public:
     {
       // Change total frame number for test
       mTotalFrameNumber = 200;
+      mTestFrameDrop = true;
     }
     return true;
   }
@@ -112,10 +114,10 @@ public:
 
   bool Render( uint32_t frameNumber )
   {
-    if(mDelayTime != 0)
+    if(mTestFrameDrop)
     {
       std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int32_t>(mDelayTime)));
-      mDelayTime = 0;
+      mTestFrameDrop = false;
       mNeedDroppedFrames = true;
     }
     else if(mNeedDroppedFrames)
@@ -199,6 +201,7 @@ public:
   uint32_t mDelayTime;
   uint32_t mDroppedFrames;
   float mFrameRate;
+  bool mTestFrameDrop;
   bool mNeedDroppedFrames;
   Dali::VectorAnimationRenderer::UploadCompletedSignalType mUploadCompletedSignal;
   std::unique_ptr< EventThreadCallback > mEventThreadCallback;
index 6159e71..4c5bdad 100644 (file)
@@ -53,9 +53,6 @@ const char* TEST_VECTOR_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR  "/insta_camera.jso
 const char* TEST_VECTOR_IMAGE_FILE_NAME_FRAME_DROP = "framedrop.json";
 const char* TEST_VECTOR_IMAGE_INVALID_FILE_NAME =  "invalid.json";
 
-const char* TEST_VECTOR_IMAGE_RIVE_FILE_NAME =  TEST_RESOURCE_DIR  "/shape.riv";
-const char* TEST_VECTOR_IMAGE_INVALID_RIVE_FILE_NAME = "invalid.riv";
-
 bool gAnimationFinishedSignalFired = false;
 
 void VisualEventSignal( Control control, Dali::Property::Index visualIndex, Dali::Property::Index signalId )
@@ -1599,216 +1596,21 @@ int UtcDaliAnimatedVectorImageVisualFrameDrops(void)
   Property::Map attributes;
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes);
 
+  // Make delay to drop frames
+  Test::VectorAnimationRenderer::DelayRendering(170); // longer than 16.6 * 10frames
+
   application.SendNotification();
   application.Render();
 
   // Trigger count is 1 - render the first frame
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
-  // Make delay to drop frames
-  Test::VectorAnimationRenderer::DelayRendering(170); // longer than 16.6 * 10frames
-
-  // Check dropped frame
+  // Wait for calculating frame drops
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
+  // Check dropped frame
   uint32_t frames = Test::VectorAnimationRenderer::GetDroppedFrames();
   DALI_TEST_CHECK(frames >= 9);
 
   END_TEST;
 }
-
-int UtcDaliAnimatedVectorImageVisualLoadRiveFileP(void)
-{
-  ToolkitTestApplication application;
-  tet_infoline( "UtcDaliAnimatedVectorImageVisualLoadRiveFile: Request animated vector image visual with a rive url" );
-
-  VisualFactory factory = VisualFactory::Get();
-  Visual::Base visual = factory.CreateVisual( TEST_VECTOR_IMAGE_RIVE_FILE_NAME, ImageDimensions() );
-  DALI_TEST_CHECK( visual );
-
-  DummyControl actor = DummyControl::New( true );
-  DummyControlImpl& dummyImpl = static_cast< DummyControlImpl& >( actor.GetImplementation() );
-  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
-  actor.SetProperty( Actor::Property::SIZE, Vector2( 200.0f, 200.0f ) );
-  application.GetScene().Add( actor );
-
-  application.SendNotification();
-  application.Render();
-
-  // renderer is added to actor
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-  Renderer renderer = actor.GetRendererAt( 0u );
-  DALI_TEST_CHECK( renderer );
-
-  // Test SetOffScene().
-  actor.Unparent();
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
-
-  END_TEST;
-}
-
-int UtcDaliAnimatedVectorImageVisualLoadRiveFileN(void)
-{
-  ToolkitTestApplication application;
-  tet_infoline("Request loading with invalid rive file - should draw broken image");
-
-  TestGlAbstraction& gl = application.GetGlAbstraction();
-  TraceCallStack& textureTrace = gl.GetTextureTrace();
-  textureTrace.Enable(true);
-
-  Property::Map propertyMap;
-  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
-             .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_INVALID_RIVE_FILE_NAME);
-
-  Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
-  DALI_TEST_CHECK(visual);
-
-  DummyControl actor = DummyControl::New(true);
-  DummyControlImpl& dummyImpl = static_cast< DummyControlImpl& >(actor.GetImplementation());
-  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
-
-  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
-
-  application.GetScene().Add(actor);
-
-  application.SendNotification();
-  application.Render();
-
-  // Check resource status
-  Visual::ResourceStatus status = actor.GetVisualResourceStatus(DummyControl::Property::TEST_VISUAL);
-  DALI_TEST_EQUALS(status, Visual::ResourceStatus::FAILED, TEST_LOCATION);
-
-  // The broken image should be shown.
-  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
-  DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
-
-  END_TEST;
-}
-
-int UtcDaliAnimatedVectorImageVisualPlaybackRiveFile(void)
-{
-  ToolkitTestApplication application;
-
-  tet_infoline( "UtcDaliAnimatedVectorImageVisualPlaybackRiveFile" );
-
-  {
-    // request AnimatedVectorImageVisual for Rive with a property map
-    VisualFactory factory = VisualFactory::Get();
-    Visual::Base visual = factory.CreateVisual(
-      Property::Map()
-      .Add( Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE )
-      .Add( ImageVisual::Property::URL, TEST_VECTOR_IMAGE_RIVE_FILE_NAME ) );
-
-    DummyControl dummyControl = DummyControl::New( true );
-    Impl::DummyControl& dummyImpl = static_cast< Impl::DummyControl& >( dummyControl.GetImplementation() );
-    dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
-    dummyControl.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
-
-    Property::Map attributes;
-    tet_infoline( "Test Play action" );
-    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
-
-    application.GetScene().Add( dummyControl );
-    application.SendNotification();
-    application.Render( 16 );
-
-    Property::Map map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
-    Property::Value* value = map.Find( DevelImageVisual::Property::PLAY_STATE );
-    DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::PLAYING );
-
-    tet_infoline( "Test Pause action" );
-    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PAUSE, attributes );
-
-    application.SendNotification();
-    application.Render(16);
-
-    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
-    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
-    DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::PAUSED );
-
-    tet_infoline( "Test Play action" );
-    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
-
-    application.SendNotification();
-    application.Render(16);
-
-    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
-    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
-    DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::PLAYING );
-
-    tet_infoline( "Test Stop action" );
-    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::STOP, attributes );
-
-    application.SendNotification();
-    application.Render(16);
-
-    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
-    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
-    DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::STOPPED );
-
-    tet_infoline( "Test Stop action again" );
-    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::STOP, attributes );
-
-    application.SendNotification();
-    application.Render(16);
-
-    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
-    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
-    DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::STOPPED );
-
-    tet_infoline( "Test Play action" );
-    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
-
-    application.SendNotification();
-    application.Render(16);
-
-    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
-    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
-    DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::PLAYING );
-
-    tet_infoline( "Off stage" );
-    dummyControl.Unparent();
-
-    application.SendNotification();
-    application.Render(16);
-
-    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
-    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
-    DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::STOPPED );
-
-    tet_infoline( "On stage again" );
-    application.GetScene().Add( dummyControl );
-
-    application.SendNotification();
-    application.Render(16);
-
-    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
-    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
-    DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::STOPPED );
-
-    tet_infoline( "Test Play action" );
-    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
-
-    application.SendNotification();
-    application.Render(16);
-
-    map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
-    value = map.Find( DevelImageVisual::Property::PLAY_STATE );
-    DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::PLAYING );
-
-    // Change Size
-    Vector3 newSize( 100.0f, 100.0f, 0.0f );
-    dummyControl.SetProperty( Actor::Property::SIZE, newSize );
-
-    application.SendNotification();
-    application.Render(16);
-
-    // Size should be changed
-    Vector3 naturalSize = dummyControl.GetNaturalSize();
-    DALI_TEST_CHECK( naturalSize == newSize );
-
-    dummyControl.Unparent();
-  }
-
-  END_TEST;
-}
index 31d1762..ba8e3d8 100644 (file)
@@ -107,6 +107,7 @@ const char* const PROPERTY_NAME_FONT_SIZE_SCALE                      = "fontSize
 const char* const PROPERTY_NAME_GRAB_HANDLE_COLOR                    = "grabHandleColor";
 const char* const PROPERTY_NAME_ENABLE_GRAB_HANDLE_POPUP             = "enableGrabHandlePopup";
 const char* const PROPERTY_NAME_INPUT_METHOD_SETTINGS                = "inputMethodSettings";
+const char* const PROPERTY_NAME_INPUT_FILTER                         = "inputFilter";
 
 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.
@@ -135,6 +136,8 @@ const std::string DEFAULT_DEVICE_NAME("hwKeyboard");
 static bool gAnchorClickedCallBackCalled;
 static bool gAnchorClickedCallBackNotCalled;
 static bool gTextChangedCallBackCalled;
+static bool gInputFilteredAcceptedCallbackCalled;
+static bool gInputFilteredRejectedCallbackCalled;
 static bool gInputStyleChangedCallbackCalled;
 static bool gMaxCharactersCallBackCalled;
 static Dali::Toolkit::TextEditor::InputStyle::Mask gInputStyleMask;
@@ -187,6 +190,20 @@ static void TestMaxLengthReachedCallback( TextEditor control )
   gMaxCharactersCallBackCalled = true;
 }
 
+static void TestInputFilteredCallback(TextEditor control, Toolkit::InputFilter::Property::Type type)
+{
+  tet_infoline(" TestInputFilteredCallback");
+
+  if(type == Toolkit::InputFilter::Property::ACCEPTED)
+  {
+    gInputFilteredAcceptedCallbackCalled = true;
+  }
+  else if(type == Toolkit::InputFilter::Property::REJECTED)
+  {
+    gInputFilteredRejectedCallbackCalled = true;
+  }
+}
+
 // Generate a KeyEvent to send to Core.
 Integration::KeyEvent GenerateKey( const std::string& keyName,
                                    const std::string& logicalKey,
@@ -515,6 +532,7 @@ int UtcDaliTextEditorGetPropertyP(void)
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_COLOR ) == DevelTextEditor::Property::GRAB_HANDLE_COLOR );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_GRAB_HANDLE_POPUP ) == DevelTextEditor::Property::ENABLE_GRAB_HANDLE_POPUP );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_METHOD_SETTINGS ) == DevelTextEditor::Property::INPUT_METHOD_SETTINGS );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_FILTER ) == DevelTextEditor::Property::INPUT_FILTER );
 
   END_TEST;
 }
@@ -969,6 +987,21 @@ int UtcDaliTextEditorSetPropertyP(void)
   DALI_TEST_CHECK( map[ "VARIATION" ].Get( variation ) );
   DALI_TEST_EQUALS( inputVariation, variation, TEST_LOCATION );
 
+  // Check the input filter property
+  Property::Map inputFilterMapSet;
+  Property::Map inputFilterMapGet;
+  inputFilterMapSet[InputFilter::Property::ACCEPTED] = "[\\w]";
+  inputFilterMapSet[InputFilter::Property::REJECTED] = "[\\d]";
+
+  editor.SetProperty(DevelTextEditor::Property::INPUT_FILTER, inputFilterMapSet);
+
+  inputFilterMapGet = editor.GetProperty<Property::Map>(DevelTextEditor::Property::INPUT_FILTER);
+  DALI_TEST_EQUALS(inputFilterMapGet.Count(), inputFilterMapSet.Count(), TEST_LOCATION);
+
+  // Clear
+  inputFilterMapSet.Clear();
+  editor.SetProperty(DevelTextEditor::Property::INPUT_FILTER, inputFilterMapSet);
+
   application.SendNotification();
   application.Render();
 
@@ -3105,6 +3138,58 @@ int utcDaliTextEditorMaxCharactersReached(void)
   END_TEST;
 }
 
+int utcDaliTextEditorInputFiltered(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorInputFiltered");
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK(editor);
+
+  application.GetScene().Add(editor);
+
+  Property::Map inputFilter;
+
+  // Only digit is accepted.
+  inputFilter[InputFilter::Property::ACCEPTED] = "[\\d]";
+
+  // Set input filter to TextEditor.
+  editor.SetProperty(DevelTextEditor::Property::INPUT_FILTER, inputFilter);
+
+  editor.SetKeyInputFocus();
+
+  // connect to the input filtered signal.
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  DevelTextEditor::InputFilteredSignal(editor).Connect(&TestInputFilteredCallback);
+  bool inputFilteredSignal = false;
+  editor.ConnectSignal(testTracker, "inputFiltered", CallbackFunctor(&inputFilteredSignal));
+
+  gInputFilteredAcceptedCallbackCalled = false;
+
+  application.ProcessEvent(GenerateKey( "a", "", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::DOWN, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ));
+
+  DALI_TEST_CHECK(gInputFilteredAcceptedCallbackCalled);
+  DALI_TEST_CHECK(inputFilteredSignal);
+
+  // Word is rejected.
+  inputFilter[InputFilter::Property::ACCEPTED] = "";
+  inputFilter[InputFilter::Property::REJECTED] = "[\\w]";
+
+  // Set input filter to TextEditor.
+  editor.SetProperty(DevelTextEditor::Property::INPUT_FILTER, inputFilter);
+
+  editor.SetKeyInputFocus();
+
+  inputFilteredSignal = false;
+  gInputFilteredRejectedCallbackCalled = false;
+
+  application.ProcessEvent(GenerateKey( "a", "", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::DOWN, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+
+  DALI_TEST_CHECK(gInputFilteredAcceptedCallbackCalled);
+  DALI_TEST_CHECK(inputFilteredSignal);
+
+  END_TEST;
+}
+
 int UtcDaliTextEditorSelectWholeText(void)
 {
   ToolkitTestApplication application;
index 2044ea3..3f78b20 100644 (file)
@@ -106,6 +106,7 @@ const char* const PROPERTY_NAME_ENABLE_GRAB_HANDLE_POPUP             = "enableGr
 const char* const PROPERTY_NAME_BACKGROUND                           = "textBackground";
 const char* const PROPERTY_NAME_FONT_SIZE_SCALE                      = "fontSizeScale";
 const char* const PROPERTY_NAME_GRAB_HANDLE_COLOR                    = "grabHandleColor";
+const char* const PROPERTY_NAME_INPUT_FILTER                         = "inputFilter";
 
 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.
@@ -125,6 +126,8 @@ static bool gAnchorClickedCallBackCalled;
 static bool gAnchorClickedCallBackNotCalled;
 static bool gTextChangedCallBackCalled;
 static bool gMaxCharactersCallBackCalled;
+static bool gInputFilteredAcceptedCallbackCalled;
+static bool gInputFilteredRejectedCallbackCalled;
 static bool gInputStyleChangedCallbackCalled;
 static Dali::Toolkit::TextField::InputStyle::Mask gInputStyleMask;
 
@@ -234,6 +237,20 @@ static void TestMaxLengthReachedCallback( TextField control )
   gMaxCharactersCallBackCalled = true;
 }
 
+static void TestInputFilteredCallback(TextField control, Toolkit::InputFilter::Property::Type type)
+{
+  tet_infoline(" TestInputFilteredCallback");
+
+  if(type == Toolkit::InputFilter::Property::ACCEPTED)
+  {
+    gInputFilteredAcceptedCallbackCalled = true;
+  }
+  else if(type == Toolkit::InputFilter::Property::REJECTED)
+  {
+    gInputFilteredRejectedCallbackCalled = true;
+  }
+}
+
 static void TestInputStyleChangedCallback( TextField control, TextField::InputStyle::Mask mask )
 {
   tet_infoline(" TestInputStyleChangedCallback");
@@ -526,6 +543,7 @@ int UtcDaliTextFieldGetPropertyP(void)
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_GRAB_HANDLE_POPUP ) == DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_BACKGROUND ) == DevelTextField::Property::BACKGROUND );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_COLOR ) == DevelTextField::Property::GRAB_HANDLE_COLOR );
+  DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_FILTER ) == DevelTextField::Property::INPUT_FILTER );
 
   END_TEST;
 }
@@ -1000,6 +1018,21 @@ int UtcDaliTextFieldSetPropertyP(void)
   field.SetProperty( DevelTextField::Property::GRAB_HANDLE_COLOR, Color::GREEN );
   DALI_TEST_EQUALS( field.GetProperty<Vector4>( DevelTextField::Property::GRAB_HANDLE_COLOR ), Color::GREEN, TEST_LOCATION );
 
+  // Check the input filter property
+  Property::Map inputFilterMapSet;
+  Property::Map inputFilterMapGet;
+  inputFilterMapSet[InputFilter::Property::ACCEPTED] = "[\\w]";
+  inputFilterMapSet[InputFilter::Property::REJECTED] = "[\\d]";
+
+  field.SetProperty(DevelTextField::Property::INPUT_FILTER, inputFilterMapSet);
+
+  inputFilterMapGet = field.GetProperty<Property::Map>(DevelTextField::Property::INPUT_FILTER);
+  DALI_TEST_EQUALS(inputFilterMapGet.Count(), inputFilterMapSet.Count(), TEST_LOCATION);
+
+  // Clear
+  inputFilterMapSet.Clear();
+  field.SetProperty(DevelTextField::Property::INPUT_FILTER, inputFilterMapSet);
+
   application.SendNotification();
   application.Render();
 
@@ -1544,6 +1577,135 @@ int utcDaliTextFieldMaxCharactersReachedN(void)
   END_TEST;
 }
 
+// Positive test for Input Filtered signal.
+int utcDaliTextFieldInputFilteredP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextFieldInputFilteredP");
+  TextField field = TextField::New();
+  DALI_TEST_CHECK(field);
+
+  application.GetScene().Add(field);
+
+  Property::Map inputFilter;
+
+  // Only digit is accepted.
+  inputFilter[InputFilter::Property::ACCEPTED] = "[\\d]";
+
+  // Set input filter to TextField.
+  field.SetProperty(DevelTextField::Property::INPUT_FILTER, inputFilter);
+
+  field.SetKeyInputFocus();
+
+  // connect to the input filtered signal.
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  DevelTextField::InputFilteredSignal(field).Connect(&TestInputFilteredCallback);
+  bool inputFilteredSignal = false;
+  field.ConnectSignal(testTracker, "inputFiltered", CallbackFunctor(&inputFilteredSignal));
+
+  gInputFilteredAcceptedCallbackCalled = false;
+
+  application.ProcessEvent(GenerateKey( "a", "", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::DOWN, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ));
+
+  DALI_TEST_CHECK(gInputFilteredAcceptedCallbackCalled);
+  DALI_TEST_CHECK(inputFilteredSignal);
+
+  // Word is rejected.
+  inputFilter[InputFilter::Property::ACCEPTED] = "";
+  inputFilter[InputFilter::Property::REJECTED] = "[\\w]";
+
+  // Set input filter to TextField.
+  field.SetProperty(DevelTextField::Property::INPUT_FILTER, inputFilter);
+
+  field.SetKeyInputFocus();
+
+  inputFilteredSignal = false;
+  gInputFilteredRejectedCallbackCalled = false;
+
+  application.ProcessEvent(GenerateKey( "a", "", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::DOWN, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+
+  DALI_TEST_CHECK(gInputFilteredAcceptedCallbackCalled);
+  DALI_TEST_CHECK(inputFilteredSignal);
+
+  END_TEST;
+}
+
+// Negative test for Input Filtered signal.
+int utcDaliTextFieldInputFilteredN(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextFieldInputFilteredP");
+  TextField field = TextField::New();
+  DALI_TEST_CHECK(field);
+
+  application.GetScene().Add(field);
+
+  Property::Map inputFilter;
+
+  // Only word is accepted.
+  inputFilter[InputFilter::Property::ACCEPTED] = "[\\w]";
+
+  // Set input filter to TextField.
+  field.SetProperty(DevelTextField::Property::INPUT_FILTER, inputFilter);
+
+  field.SetKeyInputFocus();
+
+  // connect to the input filtered signal.
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  DevelTextField::InputFilteredSignal(field).Connect(&TestInputFilteredCallback);
+  bool inputFilteredSignal = false;
+  field.ConnectSignal(testTracker, "inputFiltered", CallbackFunctor(&inputFilteredSignal));
+
+  gInputFilteredAcceptedCallbackCalled = false;
+
+  // Key a, d should not be filtered.
+  application.ProcessEvent(GenerateKey("a", "", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::DOWN, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey("a", "", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::UP, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey("d", "", "d", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "d", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey("d", "", "d", KEY_D_CODE, 0, 0, Integration::KeyEvent::UP, "d", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+
+  // Backspace, Delete should not be filtered.
+  application.ProcessEvent(GenerateKey( "", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey( "Delete", "", "Delete", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(!gInputFilteredAcceptedCallbackCalled);
+  DALI_TEST_CHECK(!inputFilteredSignal);
+
+  // Digit is rejected.
+  inputFilter[InputFilter::Property::ACCEPTED] = "";
+  inputFilter[InputFilter::Property::REJECTED] = "[\\d]";
+
+  field.SetProperty(DevelTextField::Property::INPUT_FILTER, inputFilter);
+
+  field.SetKeyInputFocus();
+
+  inputFilteredSignal = false;
+  gInputFilteredRejectedCallbackCalled = false;
+
+  // Key a, d should not be filtered.
+  application.ProcessEvent(GenerateKey("a", "", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::DOWN, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey("a", "", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::UP, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey("d", "", "d", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "d", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey("d", "", "d", KEY_D_CODE, 0, 0, Integration::KeyEvent::UP, "d", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+
+  // Backspace, Delete should not be filtered.
+  application.ProcessEvent(GenerateKey( "", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey( "Delete", "", "Delete", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(!gInputFilteredAcceptedCallbackCalled);
+  DALI_TEST_CHECK(!inputFilteredSignal);
+
+  END_TEST;
+}
+
 int utcDaliTextFieldInputStyleChanged01(void)
 {
   // The text-field emits signals when the input style changes. These changes of style are
index 1cf4adc..839e96d 100644 (file)
@@ -44,6 +44,7 @@
 #include <dali-toolkit/public-api/controls/scrollable/scrollable.h>
 #include <dali-toolkit/public-api/controls/slider/slider.h>
 #include <dali-toolkit/public-api/controls/text-controls/hidden-input-properties.h>
+#include <dali-toolkit/public-api/controls/text-controls/input-filter-properties.h>
 #include <dali-toolkit/public-api/controls/text-controls/placeholder-properties.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-editor.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-field.h>
index fd3e72e..5f2a157 100644 (file)
 #include "accessible-impl.h"
 
 // EXTERNAL INCLUDES
+#ifdef DGETTEXT_ENABLED
+#include <libintl.h>
+#endif
+
 #include <dali/devel-api/actors/actor-devel.h>
 
 // INTERNAL INCLUDES
 
 namespace Dali::Toolkit::DevelControl {
 
+static std::string GetLocaleText(std::string string, const char *domain = "dali-toolkit")
+{
+#ifdef DGETTEXT_ENABLED
+    /*TODO: currently non-localized string is used as a key for translation lookup. In case the lookup key formatting is forced
+          consider calling utility function for converting non-localized string into well-formatted key before lookup. */
+    return dgettext(domain, string.c_str());
+#else
+    return string;
+#endif
+}
+
 AccessibleImpl::AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, bool modal)
 : self(self),
   modal(modal)
@@ -72,21 +87,31 @@ std::string AccessibleImpl::GetName()
 
   Internal::Control&       internalControl = Toolkit::Internal::GetImplementation(control);
   Internal::Control::Impl& controlImpl     = Internal::Control::Impl::Get(internalControl);
+  std::string name;
 
   if(!controlImpl.mAccessibilityGetNameSignal.Empty())
   {
-    std::string ret;
-    controlImpl.mAccessibilityGetNameSignal.Emit(ret);
-    return ret;
+    controlImpl.mAccessibilityGetNameSignal.Emit(name);
+  }
+  else if(controlImpl.mAccessibilityNameSet)
+  {
+    name = controlImpl.mAccessibilityName;
+  }
+  else if(auto raw = GetNameRaw(); !raw.empty())
+  {
+    name = raw;
+  }
+  else
+  {
+    name = Self().GetProperty<std::string>(Actor::Property::NAME);
   }
 
-  if(controlImpl.mAccessibilityNameSet)
-    return controlImpl.mAccessibilityName;
-
-  if(auto raw = GetNameRaw(); !raw.empty())
-    return raw;
+  if(controlImpl.mAccessibilityTranslationDomainSet)
+  {
+    return GetLocaleText(name, controlImpl.mAccessibilityTranslationDomain.c_str());
+  }
 
-  return Self().GetProperty<std::string>(Actor::Property::NAME);
+  return GetLocaleText(name);
 }
 
 std::string AccessibleImpl::GetNameRaw()
@@ -100,23 +125,31 @@ std::string AccessibleImpl::GetDescription()
 
   Internal::Control&       internalControl = Toolkit::Internal::GetImplementation(control);
   Internal::Control::Impl& controlImpl     = Internal::Control::Impl::Get(internalControl);
+  std::string description;
 
   if(!controlImpl.mAccessibilityGetDescriptionSignal.Empty())
   {
-    std::string ret;
-    controlImpl.mAccessibilityGetDescriptionSignal.Emit(ret);
-    return ret;
+    controlImpl.mAccessibilityGetDescriptionSignal.Emit(description);
+  }
+  else if(controlImpl.mAccessibilityDescriptionSet)
+  {
+    description = controlImpl.mAccessibilityDescription;
+  }
+  else
+  {
+    description = GetDescriptionRaw();
+  }
+  if(controlImpl.mAccessibilityTranslationDomainSet)
+  {
+    return GetLocaleText(description, controlImpl.mAccessibilityTranslationDomain.c_str());
   }
 
-  if(controlImpl.mAccessibilityDescriptionSet)
-    return controlImpl.mAccessibilityDescription;
-
-  return GetDescriptionRaw();
+  return GetLocaleText(description);
 }
 
 std::string AccessibleImpl::GetDescriptionRaw()
 {
-  return "";
+  return {};
 }
 
 Dali::Accessibility::Accessible* AccessibleImpl::GetParent()
@@ -155,6 +188,11 @@ Dali::Accessibility::Role AccessibleImpl::GetRole()
   return Self().GetProperty<Dali::Accessibility::Role>(Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE);
 }
 
+std::string AccessibleImpl::GetLocalizedRoleName()
+{
+  return GetLocaleText(GetRoleName());
+}
+
 Dali::Accessibility::States AccessibleImpl::CalculateStates()
 {
   Dali::Actor self = Self();
@@ -260,7 +298,7 @@ static Dali::Actor CreateHighlightIndicatorActor()
   // keyboard focusable actors
   auto actor = Toolkit::ImageView::New(focusBorderImagePath);
   actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
-  DevelControl::AppendAccessibilityAttribute(actor, "highlight", "");
+  DevelControl::AppendAccessibilityAttribute(actor, "highlight", std::string());
   actor.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, false);
 
   return actor;
@@ -339,7 +377,7 @@ bool AccessibleImpl::ClearHighlight()
 
 std::string AccessibleImpl::GetActionName(size_t index)
 {
-  if(index >= GetActionCount()) return "";
+  if(index >= GetActionCount()) return {};
   Dali::TypeInfo type;
   Self().GetTypeInfo(type);
   DALI_ASSERT_ALWAYS(type && "no TypeInfo object");
@@ -348,13 +386,12 @@ std::string AccessibleImpl::GetActionName(size_t index)
 
 std::string AccessibleImpl::GetLocalizedActionName(size_t index)
 {
-  // TODO: add localization
-  return GetActionName(index);
+  return GetLocaleText(GetActionName(index));
 }
 
 std::string AccessibleImpl::GetActionDescription(size_t index)
 {
-  return "";
+  return {};
 }
 
 size_t AccessibleImpl::GetActionCount()
@@ -367,7 +404,7 @@ size_t AccessibleImpl::GetActionCount()
 
 std::string AccessibleImpl::GetActionKeyBinding(size_t index)
 {
-  return "";
+  return {};
 }
 
 bool AccessibleImpl::DoAction(size_t index)
index ab168c6..2a8ca3c 100644 (file)
@@ -113,6 +113,11 @@ public:
   Dali::Accessibility::Role GetRole() override;
 
   /**
+   * @copydoc Dali::Accessibility::Accessible::GetLocalizedRoleName()
+   */
+  std::string GetLocalizedRoleName() override;
+
+  /**
    * @copydoc Dali::Accessibility::Accessible::GetStates()
    */
   Dali::Accessibility::States GetStates() override;
index 37678d8..a685aee 100644 (file)
@@ -40,6 +40,11 @@ AnchorClickedSignalType& AnchorClickedSignal(TextEditor textEditor)
   return GetImpl(textEditor).AnchorClickedSignal();
 }
 
+InputFilteredSignalType& InputFilteredSignal(TextEditor textEditor)
+{
+  return GetImpl(textEditor).InputFilteredSignal();
+}
+
 void SelectWholeText(TextEditor textEditor)
 {
   GetImpl(textEditor).SelectWholeText();
index 665af7a..baa872f 100644 (file)
@@ -21,6 +21,7 @@
 #include <dali/devel-api/adaptor-framework/input-method-context.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/text-controls/input-filter-properties.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-editor.h>
 
 namespace Dali
@@ -220,6 +221,38 @@ enum Type
    * @endcode
    */
   INPUT_METHOD_SETTINGS,
+
+  /**
+   * @brief The input filter
+   * @details Name "inputFilter", type Property::MAP.
+   *
+   * The inputFilter map contains the following keys:
+   *
+   * | %Property Name       | Type     | Required | Description                                                                                                         |
+   * |----------------------|----------|----------|---------------------------------------------------------------------------------------------------------------------|
+   * | accepted             | STRING   | No       | A regular expression in the set of characters to be accepted by the inputFilter (the default value is empty string) |
+   * | rejected             | STRING   | No       | A regular expression in the set of characters to be rejected by the inputFilter (the default value is empty string) |
+   *
+   * @note Optional.
+   * The character set must follow the regular expression rules.
+   * Behaviour can not be guaranteed for incorrect grammars.
+   * Refer the link below for detailed rules.
+   * The functions in std::regex library use the ECMAScript grammar:
+   * http://cplusplus.com/reference/regex/ECMAScript/
+   *
+   * You can use enums instead of "accepted" and "rejected" strings.
+   * @see Dali::Toolkit::InputFilter::Property::Type
+   *
+   * Example Usage:
+   * @code
+   *   Property::Map filter;
+   *   filter[InputFilter::Property::ACCEPTED] = "[\\d]"; // accept whole digits
+   *   filter[InputFilter::Property::REJECTED] = "[0-5]"; // reject 0, 1, 2, 3, 4, 5
+   *
+   *   editor.SetProperty(DevelTextEditor::Property::INPUT_FILTER, filter); // acceptable inputs are 6, 7, 8, 9
+   * @endcode
+   */
+  INPUT_FILTER,
 };
 
 } // namespace Property
@@ -271,6 +304,37 @@ using AnchorClickedSignalType = Signal<void(TextEditor, const char*, uint32_t)>;
 DALI_TOOLKIT_API AnchorClickedSignalType& AnchorClickedSignal(TextEditor textEditor);
 
 /**
+ * @brief Input filtered signal type.
+ */
+using InputFilteredSignalType = Signal<void(TextEditor, Toolkit::InputFilter::Property::Type)>;
+
+/**
+ * @brief This signal is emitted when the character to be inserted is filtered by the input filter.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ *   void YourCallbackName(TextEditor textEditor, Toolkit::InputFilter::Property::Type type);
+ *
+ *   DevelTextEditor::InputFilteredSignal(textEditor).Connect(this, &OnInputFiltered);
+ *
+ *   void OnInputFiltered(TextEditor textEditor, InputFilter::Property::Type type)
+ *   {
+ *     if (type == InputFilter::Property::ACCEPTED)
+ *     {
+ *       // If the input has been filtered with an accepted filter, the type is ACCEPTED.
+ *     }
+ *     else if (type == InputFilter::Property::REJECTED)
+ *     {
+ *       // If the input has been filtered with an rejected filter, the type is REJECTED.
+ *     }
+ *   }
+ * @endcode
+ * @param[in] textEditor The instance of TextEditor.
+ * @return The signal to connect to.
+ */
+DALI_TOOLKIT_API InputFilteredSignalType& InputFilteredSignal(TextEditor textEditor);
+
+/**
  * @brief Select the whole text of TextEditor.
  *
  * @param[in] textEditor The instance of TextEditor.
index fdfac30..727b42a 100644 (file)
@@ -35,6 +35,11 @@ AnchorClickedSignalType& AnchorClickedSignal(TextField textField)
   return GetImpl(textField).AnchorClickedSignal();
 }
 
+InputFilteredSignalType& InputFilteredSignal(TextField textField)
+{
+  return GetImpl(textField).InputFilteredSignal();
+}
+
 void SelectWholeText(TextField textField)
 {
   GetImpl(textField).SelectWholeText();
index 3367bec..e1c18f0 100644 (file)
@@ -21,6 +21,7 @@
 #include <dali/devel-api/adaptor-framework/input-method-context.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/text-controls/input-filter-properties.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-field.h>
 
 namespace Dali
@@ -172,6 +173,38 @@ enum
    * @details Name "grabHandleColor", type Property::VECTOR4.
    */
   GRAB_HANDLE_COLOR,
+
+  /**
+   * @brief The input filter
+   * @details Name "inputFilter", type Property::MAP.
+   *
+   * The inputFilter map contains the following keys:
+   *
+   * | %Property Name       | Type     | Required | Description                                                                                                         |
+   * |----------------------|----------|----------|---------------------------------------------------------------------------------------------------------------------|
+   * | accepted             | STRING   | No       | A regular expression in the set of characters to be accepted by the inputFilter (the default value is empty string) |
+   * | rejected             | STRING   | No       | A regular expression in the set of characters to be rejected by the inputFilter (the default value is empty string) |
+   *
+   * @note Optional.
+   * The character set must follow the regular expression rules.
+   * Behaviour can not be guaranteed for incorrect grammars.
+   * Refer the link below for detailed rules.
+   * The functions in std::regex library use the ECMAScript grammar:
+   * http://cplusplus.com/reference/regex/ECMAScript/
+   *
+   * You can use enums instead of "accepted" and "rejected" strings.
+   * @see Dali::Toolkit::InputFilter::Property::Type
+   *
+   * Example Usage:
+   * @code
+   *   Property::Map filter;
+   *   filter[InputFilter::Property::ACCEPTED] = "[\\d]"; // accept whole digits
+   *   filter[InputFilter::Property::REJECTED] = "[0-5]"; // reject 0, 1, 2, 3, 4, 5
+   *
+   *   field.SetProperty(DevelTextField::Property::INPUT_FILTER, filter); // acceptable inputs are 6, 7, 8, 9
+   * @endcode
+   */
+  INPUT_FILTER,
 };
 
 } // namespace Property
@@ -206,6 +239,37 @@ using AnchorClickedSignalType = Signal<void(TextField, const char*, uint32_t)>;
 DALI_TOOLKIT_API AnchorClickedSignalType& AnchorClickedSignal(TextField textField);
 
 /**
+ * @brief Input filtered signal type.
+ */
+using InputFilteredSignalType = Signal<void(TextField, Toolkit::InputFilter::Property::Type)>;
+
+/**
+ * @brief This signal is emitted when the character to be inserted is filtered by the input filter.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ *   void YourCallbackName(TextField textField, Toolkit::InputFilter::Property::Type type);
+ *
+ *   DevelTextField::InputFilteredSignal(textField).Connect(this, &OnInputFiltered);
+ *
+ *   void OnInputFiltered(TextField textField, InputFilter::Property::Type type)
+ *   {
+ *     if (type == InputFilter::Property::ACCEPTED)
+ *     {
+ *       // If the input has been filtered with an accepted filter, the type is ACCEPTED.
+ *     }
+ *     else if (type == InputFilter::Property::REJECTED)
+ *     {
+ *       // If the input has been filtered with an rejected filter, the type is REJECTED.
+ *     }
+ *   }
+ * @endcode
+ * @param[in] textField The instance of TextField.
+ * @return The signal to connect to.
+ */
+DALI_TOOLKIT_API InputFilteredSignalType& InputFilteredSignal(TextField textField);
+
+/**
  * @brief Select the whole text of TextField.
  *
  * @param[in] textField The instance of TextField.
index 556711f..f49f82d 100644 (file)
@@ -97,9 +97,6 @@ void ImageView::OnInitialize()
     return std::unique_ptr<Dali::Accessibility::Accessible>(
       new DevelControl::AccessibleImpl(actor, Dali::Accessibility::Role::IMAGE));
   });
-
-  //Enable highightability
-  Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
 }
 
 void ImageView::SetImage(const Property::Map& map)
index db7096a..56f43ff 100644 (file)
@@ -149,11 +149,14 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "primaryCursorPo
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "grabHandleColor",                      VECTOR4,   GRAB_HANDLE_COLOR                   )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "enableGrabHandlePopup",                BOOLEAN,   ENABLE_GRAB_HANDLE_POPUP            )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "inputMethodSettings",                  MAP,       INPUT_METHOD_SETTINGS               )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "inputFilter",                          MAP,       INPUT_FILTER                        )
 
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged",        SIGNAL_TEXT_CHANGED       )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged",  SIGNAL_INPUT_STYLE_CHANGED)
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "anchorClicked",      SIGNAL_ANCHOR_CLICKED     )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputFiltered",      SIGNAL_INPUT_FILTERED     )
+
 
 DALI_TYPE_REGISTRATION_END()
 // clang-format on
@@ -801,6 +804,15 @@ void TextEditor::SetProperty(BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
+      case Toolkit::DevelTextEditor::Property::INPUT_FILTER:
+      {
+        const Property::Map* map = value.GetMap();
+        if(map)
+        {
+          impl.mController->SetInputFilterOption(*map);
+        }
+        break;
+      }
     } // switch
   }   // texteditor
 }
@@ -1174,6 +1186,13 @@ Property::Value TextEditor::GetProperty(BaseObject* object, Property::Index inde
         value = map;
         break;
       }
+      case Toolkit::DevelTextEditor::Property::INPUT_FILTER:
+      {
+        Property::Map map;
+        impl.mController->GetInputFilterOption(map);
+        value = map;
+        break;
+      }
     } //switch
   }
 
@@ -1248,6 +1267,11 @@ DevelTextEditor::AnchorClickedSignalType& TextEditor::AnchorClickedSignal()
   return mAnchorClickedSignal;
 }
 
+DevelTextEditor::InputFilteredSignalType& TextEditor::InputFilteredSignal()
+{
+  return mInputFilteredSignal;
+}
+
 Text::ControllerPtr TextEditor::getController()
 {
   return mController;
@@ -1284,6 +1308,14 @@ bool TextEditor::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface*
       editorImpl.AnchorClickedSignal().Connect(tracker, functor);
     }
   }
+  else if(0 == strcmp(signalName.c_str(), SIGNAL_INPUT_FILTERED))
+  {
+    if(editor)
+    {
+      Internal::TextEditor& editorImpl(GetImpl(editor));
+      editorImpl.InputFilteredSignal().Connect(tracker, functor);
+    }
+  }
   else
   {
     // signalName does not match any signal
@@ -1874,6 +1906,12 @@ void TextEditor::AnchorClicked(const std::string& href)
   mAnchorClickedSignal.Emit(handle, href.c_str(), href.length());
 }
 
+void TextEditor::InputFiltered(Toolkit::InputFilter::Property::Type type)
+{
+  Dali::Toolkit::TextEditor handle(GetOwner());
+  mInputFilteredSignal.Emit(handle, type);
+}
+
 void TextEditor::AddDecoration(Actor& actor, bool needsClipping)
 {
   if(actor)
index 0286da2..424cda5 100644 (file)
@@ -93,6 +93,11 @@ public:
   DevelTextEditor::AnchorClickedSignalType& AnchorClickedSignal();
 
   /**
+   * @copydoc Dali::Toollkit::TextEditor::InputFilteredSignal()
+   */
+  DevelTextEditor::InputFilteredSignalType& InputFilteredSignal();
+
+  /**
    * Connects a callback function with the object's signals.
    * @param[in] object The object providing the signal.
    * @param[in] tracker Used to disconnect the signal.
@@ -228,6 +233,11 @@ private: // From Control
    */
   void AddDecoration(Actor& actor, bool needsClipping) override;
 
+  /**
+   * @copydoc Text::EditableControlInterface::InputFiltered()
+   */
+  void InputFiltered(Toolkit::InputFilter::Property::Type type) override;
+
   // From SelectableControlInterface
 public:
   /**
@@ -398,6 +408,7 @@ private: // Data
   Toolkit::TextEditor::ScrollStateChangedSignalType    mScrollStateChangedSignal;
   Toolkit::DevelTextEditor::MaxLengthReachedSignalType mMaxLengthReachedSignal;
   Toolkit::DevelTextEditor::AnchorClickedSignalType    mAnchorClickedSignal;
+  Toolkit::DevelTextEditor::InputFilteredSignalType    mInputFilteredSignal;
 
   InputMethodContext            mInputMethodContext;
   Text::ControllerPtr           mController;
index 4e5cd9c..dbf5624 100644 (file)
@@ -138,11 +138,13 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "enableEditing",
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "fontSizeScale",                    FLOAT,     FONT_SIZE_SCALE                     )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "primaryCursorPosition",            INTEGER,   PRIMARY_CURSOR_POSITION             )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "grabHandleColor",                  VECTOR4,   GRAB_HANDLE_COLOR                   )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "inputFilter",                      MAP,       INPUT_FILTER                        )
 
 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_SIGNAL_REGISTRATION(Toolkit, TextField, "anchorClicked",     SIGNAL_ANCHOR_CLICKED     )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "inputFiltered",     SIGNAL_INPUT_FILTERED     )
 
 DALI_TYPE_REGISTRATION_END()
 // clang-format on
@@ -765,6 +767,15 @@ void TextField::SetProperty(BaseObject* object, Property::Index index, const Pro
         impl.RequestTextRelayout();
         break;
       }
+      case Toolkit::DevelTextField::Property::INPUT_FILTER:
+      {
+        const Property::Map* map = value.GetMap();
+        if(map)
+        {
+          impl.mController->SetInputFilterOption(*map);
+        }
+        break;
+      }
     } // switch
   }   // textfield
 }
@@ -1120,6 +1131,13 @@ Property::Value TextField::GetProperty(BaseObject* object, Property::Index index
         value = impl.mDecorator->GetHandleColor();
         break;
       }
+      case Toolkit::DevelTextField::Property::INPUT_FILTER:
+      {
+        Property::Map map;
+        impl.mController->GetInputFilterOption(map);
+        value = map;
+        break;
+      }
     } //switch
   }
 
@@ -1204,6 +1222,14 @@ bool TextField::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface*
       fieldImpl.AnchorClickedSignal().Connect(tracker, functor);
     }
   }
+  else if(0 == strcmp(signalName.c_str(), SIGNAL_INPUT_FILTERED))
+  {
+    if(field)
+    {
+      Internal::TextField& fieldImpl(GetImpl(field));
+      fieldImpl.InputFilteredSignal().Connect(tracker, functor);
+    }
+  }
   else
   {
     // signalName does not match any signal
@@ -1233,6 +1259,11 @@ DevelTextField::AnchorClickedSignalType& TextField::AnchorClickedSignal()
   return mAnchorClickedSignal;
 }
 
+DevelTextField::InputFilteredSignalType& TextField::InputFilteredSignal()
+{
+  return mInputFilteredSignal;
+}
+
 void TextField::OnInitialize()
 {
   Actor self = Self();
@@ -1804,6 +1835,12 @@ void TextField::AnchorClicked(const std::string& href)
   mAnchorClickedSignal.Emit(handle, href.c_str(), href.length());
 }
 
+void TextField::InputFiltered(Toolkit::InputFilter::Property::Type type)
+{
+  Dali::Toolkit::TextField handle(GetOwner());
+  mInputFilteredSignal.Emit(handle, type);
+}
+
 void TextField::AddDecoration(Actor& actor, bool needsClipping)
 {
   if(actor)
index c76f05a..d1a2671 100644 (file)
@@ -109,6 +109,11 @@ public:
    */
   DevelTextField::AnchorClickedSignalType& AnchorClickedSignal();
 
+  /**
+   * @copydoc TextField::InputFilteredSignal()
+   */
+  DevelTextField::InputFilteredSignalType& InputFilteredSignal();
+
   Text::ControllerPtr getController();
 
 private: // From Control
@@ -221,6 +226,11 @@ private: // From Control
    */
   void AddDecoration(Actor& actor, bool needsClipping) override;
 
+  /**
+   * @copydoc Text::EditableControlInterface::InputFiltered()
+   */
+  void InputFiltered(Toolkit::InputFilter::Property::Type type) override;
+
   // From SelectableControlInterface
 public:
   /**
@@ -359,6 +369,7 @@ private: // Data
   Toolkit::TextField::MaxLengthReachedSignalType   mMaxLengthReachedSignal;
   Toolkit::TextField::InputStyleChangedSignalType  mInputStyleChangedSignal;
   Toolkit::DevelTextField::AnchorClickedSignalType mAnchorClickedSignal;
+  Toolkit::DevelTextField::InputFilteredSignalType mInputFilteredSignal;
 
   InputMethodContext       mInputMethodContext;
   Text::ControllerPtr      mController;
index f712e9f..9cab1a6 100644 (file)
@@ -137,9 +137,11 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/text/markup-processor-anchor.cpp
    ${toolkit_src_dir}/text/markup-processor-font.cpp
    ${toolkit_src_dir}/text/markup-processor-background.cpp
+   ${toolkit_src_dir}/text/markup-processor-span.cpp
    ${toolkit_src_dir}/text/markup-processor-helper-functions.cpp
    ${toolkit_src_dir}/text/multi-language-support.cpp
    ${toolkit_src_dir}/text/hidden-text.cpp
+   ${toolkit_src_dir}/text/input-filter.cpp
    ${toolkit_src_dir}/text/property-string-parser.cpp
    ${toolkit_src_dir}/text/segmentation.cpp
    ${toolkit_src_dir}/text/shaper.cpp
diff --git a/dali-toolkit/internal/text/input-filter.cpp b/dali-toolkit/internal/text/input-filter.cpp
new file mode 100644 (file)
index 0000000..eafcfe7
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/text/hidden-text.h>
+#include <dali-toolkit/internal/text/input-filter.h>
+
+// INTERNAL INCLUDES
+
+using namespace Dali::Toolkit;
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+const char* const PROPERTY_ACCEPTED = "accepted";
+const char* const PROPERTY_REJECTED = "rejected";
+
+InputFilter::InputFilter()
+: mAccepted(""),
+  mRejected("")
+{
+}
+
+void InputFilter::SetProperties(const Property::Map& map)
+{
+  const Property::Map::SizeType count = map.Count();
+
+  for(Property::Map::SizeType position = 0; position < count; ++position)
+  {
+    KeyValuePair     keyValue = map.GetKeyValue(position);
+    Property::Key&   key      = keyValue.first;
+    Property::Value& value    = keyValue.second;
+
+    if(key == Toolkit::InputFilter::Property::ACCEPTED || key == PROPERTY_ACCEPTED)
+    {
+      value.Get(mAccepted);
+    }
+    else if(key == Toolkit::InputFilter::Property::REJECTED || key == PROPERTY_REJECTED)
+    {
+      value.Get(mRejected);
+    }
+  }
+}
+
+void InputFilter::GetProperties(Property::Map& map)
+{
+  map[Toolkit::InputFilter::Property::ACCEPTED] = mAccepted.c_str();
+  map[Toolkit::InputFilter::Property::REJECTED] = mRejected.c_str();
+}
+
+bool InputFilter::Contains(Toolkit::InputFilter::Property::Type type, std::string source)
+{
+  bool       match = false;
+  std::regex pattern;
+
+  if(type == Toolkit::InputFilter::Property::ACCEPTED)
+  {
+    if(mAccepted.empty())
+    {
+      return true;
+    }
+    pattern = mAccepted;
+  }
+  else if(type == Toolkit::InputFilter::Property::REJECTED)
+  {
+    if(mRejected.empty())
+    {
+      return false;
+    }
+    pattern = mRejected;
+  }
+
+  match = std::regex_match(source, pattern);
+
+  return match;
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/input-filter.h b/dali-toolkit/internal/text/input-filter.h
new file mode 100644 (file)
index 0000000..6de0132
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef DALI_INPUT_FILTER_H
+#define DALI_INPUT_FILTER_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/property-map.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/text-controls/input-filter-properties.h>
+#include <regex>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+/**
+ * Class to handle the input text filtering
+ */
+class InputFilter : public ConnectionTracker
+{
+public:
+  /**
+   * @brief Constructor
+   */
+  InputFilter();
+
+public: // Intended for internal use
+  /**
+   * @brief Used to set options of input filter.
+   * @param[in] map The property map describing the option.
+   */
+  void SetProperties(const Property::Map& map);
+
+  /**
+   * @brief Retrieve property map of input filter options.
+   * @param[out] map The input filter option.
+   */
+  void GetProperties(Property::Map& map);
+
+  /**
+   * @brief Check if the source is contained in regex.
+   * @param[in] type ACCEPTED or REJECTED
+   * @param[in] source The original text.
+   * @return @e true if the source is contained in regex, otherwise returns @e false.
+   */
+  bool Contains(Toolkit::InputFilter::Property::Type type, std::string source);
+
+private:
+  std::string mAccepted;
+  std::string mRejected;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_INPUT_FILTER_H
index b66e37a..d5fce04 100644 (file)
@@ -36,6 +36,11 @@ namespace
 const std::string XHTML_VALUE_ATTRIBUTE("value");
 }
 
+void ProcessColor(const Attribute& attribute, ColorRun& colorRun)
+{
+  ColorStringToVector4(attribute.valueBuffer, attribute.valueLength, colorRun.color);
+}
+
 void ProcessColorTag(const Tag& tag, ColorRun& colorRun)
 {
   for(Vector<Attribute>::ConstIterator it    = tag.attributes.Begin(),
@@ -46,7 +51,7 @@ void ProcessColorTag(const Tag& tag, ColorRun& colorRun)
     const Attribute& attribute(*it);
     if(TokenComparison(XHTML_VALUE_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
     {
-      ColorStringToVector4(attribute.valueBuffer, attribute.valueLength, colorRun.color);
+      ProcessColor(attribute, colorRun);
     }
   }
 }
index 89e9d2a..02210fb 100644 (file)
@@ -25,11 +25,20 @@ namespace Toolkit
 namespace Text
 {
 struct Tag;
+struct Attribute;
 struct ColorRun;
 
 /**
  * @brief Retrieves the color value from the tag and sets it to the color run.
  *
+ * @param[in] attribute the color attribute.
+ * @param[in,out] colorRun The color run.
+ */
+void ProcessColor(const Attribute& attribute, ColorRun& colorRun);
+
+/**
+ * @brief Retrieves the color value from the tag and sets it to the color run.
+ *
  * @param[in] tag The color tag and its attributes.
  * @param[in,out] colorRun The color run.
  */
index 4ddcd61..df8b6ec 100644 (file)
@@ -41,9 +41,64 @@ const std::string XHTML_WEIGHT_ATTRIBUTE("weight");
 const std::string XHTML_WIDTH_ATTRIBUTE("width");
 const std::string XHTML_SLANT_ATTRIBUTE("slant");
 
-const unsigned int MAX_FONT_ATTRIBUTE_SIZE = 15u; ///< The maximum length of any of the possible 'weight', 'width' or 'slant' values.
+const std::string  FONT_PREFIX("font-");
+const unsigned int FONT_PREFIX_LENGTH      = 5u;
+const unsigned int MIN_FONT_ATTRIBUTE_SIZE = 4u;   ///< The minimum length of any of the possible 'weight', 'width' , 'slant' or 'size' values.
+const unsigned int MAX_FONT_ATTRIBUTE_SIZE = 15u;  ///< The maximum length of any of the possible 'weight', 'width' or 'slant' values.
+const float        PIXEL_FORMAT_64_FACTOR  = 64.f; ///< 64.f is used to convert from point size to 26.6 pixel format.
 } // namespace
 
+void processFontAttributeValue(char value[], const Attribute& attribute)
+{
+  // The StringToWeight() uses the Scripting::GetEnumeration() function which requires the input string to end with a '\0' char.
+  const Length length = attribute.valueLength > MAX_FONT_ATTRIBUTE_SIZE ? MAX_FONT_ATTRIBUTE_SIZE : attribute.valueLength;
+  memcpy(value, attribute.valueBuffer, length);
+  value[length] = 0;
+}
+
+void ProcessFontFamily(const Attribute& attribute, FontDescriptionRun& fontRun)
+{
+  fontRun.familyDefined = true;
+  fontRun.familyLength  = attribute.valueLength;
+  fontRun.familyName    = new char[fontRun.familyLength];
+  memcpy(fontRun.familyName, attribute.valueBuffer, fontRun.familyLength);
+  // The memory is freed when the font run is removed from the logical model.
+}
+
+void ProcessFontSize(const Attribute& attribute, FontDescriptionRun& fontRun)
+{
+  // 64.f is used to convert from point size to 26.6 pixel format.
+  fontRun.size        = static_cast<PointSize26Dot6>(StringToFloat(attribute.valueBuffer) * PIXEL_FORMAT_64_FACTOR);
+  fontRun.sizeDefined = true;
+}
+
+void ProcessFontWeight(const Attribute& attribute, FontDescriptionRun& fontRun)
+{
+  char value[MAX_FONT_ATTRIBUTE_SIZE + 1u];
+  processFontAttributeValue(value, attribute);
+
+  fontRun.weight        = StringToWeight(value);
+  fontRun.weightDefined = true;
+}
+
+void ProcessFontWidth(const Attribute& attribute, FontDescriptionRun& fontRun)
+{
+  char value[MAX_FONT_ATTRIBUTE_SIZE + 1u];
+  processFontAttributeValue(value, attribute);
+
+  fontRun.width        = StringToWidth(value);
+  fontRun.widthDefined = true;
+}
+
+void ProcessFontSlant(const Attribute& attribute, FontDescriptionRun& fontRun)
+{
+  char value[MAX_FONT_ATTRIBUTE_SIZE + 1u];
+  processFontAttributeValue(value, attribute);
+
+  fontRun.slant        = StringToSlant(value);
+  fontRun.slantDefined = true;
+}
+
 void ProcessFontTag(const Tag& tag, FontDescriptionRun& fontRun)
 {
   for(Vector<Attribute>::ConstIterator it    = tag.attributes.Begin(),
@@ -52,52 +107,26 @@ void ProcessFontTag(const Tag& tag, FontDescriptionRun& fontRun)
       ++it)
   {
     const Attribute& attribute(*it);
+
     if(TokenComparison(XHTML_FAMILY_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
     {
-      fontRun.familyDefined = true;
-      fontRun.familyLength  = attribute.valueLength;
-      fontRun.familyName    = new char[fontRun.familyLength];
-      memcpy(fontRun.familyName, attribute.valueBuffer, fontRun.familyLength);
-      // The memory is freed when the font run is removed from the logical model.
+      ProcessFontFamily(attribute, fontRun);
     }
     else if(TokenComparison(XHTML_SIZE_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
     {
-      // 64.f is used to convert from point size to 26.6 pixel format.
-      fontRun.size        = static_cast<PointSize26Dot6>(StringToFloat(attribute.valueBuffer) * 64.f);
-      fontRun.sizeDefined = true;
+      ProcessFontSize(attribute, fontRun);
     }
     else if(TokenComparison(XHTML_WEIGHT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
     {
-      // The StringToWeight() uses the Scripting::GetEnumeration() function which requires the input string to end with a '\0' char.
-      char         value[MAX_FONT_ATTRIBUTE_SIZE + 1u];
-      const Length length = attribute.valueLength > MAX_FONT_ATTRIBUTE_SIZE ? MAX_FONT_ATTRIBUTE_SIZE : attribute.valueLength;
-      memcpy(value, attribute.valueBuffer, length);
-      value[length] = 0;
-
-      fontRun.weight        = StringToWeight(value);
-      fontRun.weightDefined = true;
+      ProcessFontWeight(attribute, fontRun);
     }
     else if(TokenComparison(XHTML_WIDTH_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
     {
-      // The StringToWidth() uses the Scripting::GetEnumeration() function which requires the input string to end with a '\0' char.
-      char         value[MAX_FONT_ATTRIBUTE_SIZE + 1u];
-      const Length length = attribute.valueLength > MAX_FONT_ATTRIBUTE_SIZE ? MAX_FONT_ATTRIBUTE_SIZE : attribute.valueLength;
-      memcpy(value, attribute.valueBuffer, length);
-      value[length] = 0;
-
-      fontRun.width        = StringToWidth(value);
-      fontRun.widthDefined = true;
+      ProcessFontWidth(attribute, fontRun);
     }
     else if(TokenComparison(XHTML_SLANT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
     {
-      // The StringToSlant() uses the Scripting::GetEnumeration() function which requires the input string to end with a '\0' char.
-      char         value[MAX_FONT_ATTRIBUTE_SIZE + 1u];
-      const Length length = attribute.valueLength > MAX_FONT_ATTRIBUTE_SIZE ? MAX_FONT_ATTRIBUTE_SIZE : attribute.valueLength;
-      memcpy(value, attribute.valueBuffer, length);
-      value[length] = 0;
-
-      fontRun.slant        = StringToSlant(value);
-      fontRun.slantDefined = true;
+      ProcessFontSlant(attribute, fontRun);
     }
   }
 }
index 8b075bf..6461451 100644 (file)
@@ -25,6 +25,7 @@ namespace Toolkit
 namespace Text
 {
 struct Tag;
+struct Attribute;
 struct FontDescriptionRun;
 
 /**
@@ -35,6 +36,46 @@ struct FontDescriptionRun;
  */
 void ProcessFontTag(const Tag& tag, FontDescriptionRun& fontRun);
 
+/**
+ * @brief Fill the font run with the font slant attribute value.
+ *
+ * @param[in] attribute the font slant attribute.
+ * @param[out] fontRun The font description run.
+ */
+void ProcessFontSlant(const Attribute& attribute, FontDescriptionRun& fontRun);
+
+/**
+ * @brief Fill the font run with the font width attribute value.
+ *
+ * @param[in] attribute the font width attribute.
+ * @param[out] fontRun The font description run.
+ */
+void ProcessFontWidth(const Attribute& attribute, FontDescriptionRun& fontRun);
+
+/**
+ * @brief Fill the font run with the font weight attribute value.
+ *
+ * @param[in] attribute the font weight attribute.
+ * @param[out] fontRun The font description run.
+ */
+void ProcessFontWeight(const Attribute& attribute, FontDescriptionRun& fontRun);
+
+/**
+ * @brief Fill the font run with the font size attribute value.
+ *
+ * @param[in] attribute the font size attribute.
+ * @param[out] fontRun The font description run.
+ */
+void ProcessFontSize(const Attribute& attribute, FontDescriptionRun& fontRun);
+
+/**
+ * @brief Fill the font run with the font family attribute value.
+ *
+ * @param[in] attribute the font family attribute.
+ * @param[out] fontRun The font description run.
+ */
+void ProcessFontFamily(const Attribute& attribute, FontDescriptionRun& fontRun);
+
 } // namespace Text
 
 } // namespace Toolkit
diff --git a/dali-toolkit/internal/text/markup-processor-span.cpp b/dali-toolkit/internal/text/markup-processor-span.cpp
new file mode 100644 (file)
index 0000000..40a508d
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/text/markup-processor-color.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/markup-processor-font.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace
+{
+const std::string XHTML_FAMILY_ATTRIBUTE("font-family");
+const std::string XHTML_SIZE_ATTRIBUTE("font-size");
+const std::string XHTML_WEIGHT_ATTRIBUTE("font-weight");
+const std::string XHTML_WIDTH_ATTRIBUTE("font-width");
+const std::string XHTML_SLANT_ATTRIBUTE("font-slant");
+
+const std::string XHTML_COLOR_ATTRIBUTE("text-color");
+} // namespace
+
+void ProcessSpanTag(const Tag& tag, ColorRun& colorRun, FontDescriptionRun& fontRun, bool& isColorDefined, bool& isFontDefined)
+{
+  for(Vector<Attribute>::ConstIterator it    = tag.attributes.Begin(),
+                                       endIt = tag.attributes.End();
+      it != endIt;
+      ++it)
+  {
+    const Attribute& attribute(*it);
+
+    if(TokenComparison(XHTML_COLOR_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+    {
+      isColorDefined = true;
+      ProcessColor(attribute, colorRun);
+    }
+    else if(TokenComparison(XHTML_FAMILY_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+    {
+      isFontDefined = true;
+      ProcessFontFamily(attribute, fontRun);
+    }
+    else if(TokenComparison(XHTML_SIZE_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+    {
+      isFontDefined = true;
+      ProcessFontSize(attribute, fontRun);
+    }
+    else if(TokenComparison(XHTML_WEIGHT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+    {
+      isFontDefined = true;
+      ProcessFontWeight(attribute, fontRun);
+    }
+    else if(TokenComparison(XHTML_WIDTH_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+    {
+      isFontDefined = true;
+      ProcessFontWidth(attribute, fontRun);
+    }
+    else if(TokenComparison(XHTML_SLANT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+    {
+      isFontDefined = true;
+      ProcessFontSlant(attribute, fontRun);
+    }
+  }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/markup-processor-span.h b/dali-toolkit/internal/text/markup-processor-span.h
new file mode 100644 (file)
index 0000000..330caf1
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_SPAN_H
+#define DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_SPAN_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+struct Tag;
+struct MarkupProcessData;
+
+/**
+ * @brief process the span from the tag and process all styles in it.
+ *
+ * @param[in] tag The span tag and its attributes.
+ * @param[out] colorRun the color run to be filled.
+ * @param[out] fontRun the font run to be filled.
+ * @param[out] isColorDefined if the span has color defined.
+ * @param[out] isFontDefined if the span has font defined.
+ */
+void ProcessSpanTag(const Tag& tag, ColorRun& colorRun, FontDescriptionRun& fontRun, bool& isColorDefined, bool& isFontDefined);
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_SPAN_H
index 6fef092..b656aa4 100644 (file)
@@ -31,6 +31,7 @@
 #include <dali-toolkit/internal/text/markup-processor-embedded-item.h>
 #include <dali-toolkit/internal/text/markup-processor-font.h>
 #include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+#include <dali-toolkit/internal/text/markup-processor-span.h>
 #include <dali-toolkit/internal/text/xhtml-entities.h>
 
 namespace Dali
@@ -55,6 +56,7 @@ const std::string XHTML_OUTLINE_TAG("outline");
 const std::string XHTML_ITEM_TAG("item");
 const std::string XHTML_ANCHOR_TAG("a");
 const std::string XHTML_BACKGROUND_TAG("background");
+const std::string XHTML_SPAN_TAG("span");
 
 const char LESS_THAN      = '<';
 const char GREATER_THAN   = '>';
@@ -82,15 +84,16 @@ const unsigned int DEFAULT_VECTOR_SIZE   = 16u; ///< Default size of run vectors
 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_MARKUP_PROCESSOR");
 #endif
 
+typedef VectorBase::SizeType RunIndex;
+
 /**
  * @brief Struct used to retrieve the style runs from the mark-up string.
  */
+template<typename StyleStackType>
 struct StyleStack
 {
-  typedef VectorBase::SizeType RunIndex;
-
-  Vector<RunIndex> stack;    ///< Use a vector as a style stack. Stores the indices pointing where the run is stored inside the logical model.
-  unsigned int     topIndex; ///< Points the top of the stack.
+  Vector<StyleStackType> stack;    ///< Use a vector as a style stack.
+  unsigned int           topIndex; ///< Points the top of the stack.
 
   StyleStack()
   : stack(),
@@ -99,7 +102,7 @@ struct StyleStack
     stack.Resize(DEFAULT_VECTOR_SIZE);
   }
 
-  void Push(RunIndex index)
+  void Push(StyleStackType item)
   {
     // Check if there is space inside the style stack.
     const VectorBase::SizeType size = stack.Count();
@@ -109,14 +112,14 @@ struct StyleStack
       stack.Resize(2u * size);
     }
 
-    // Set the run index in the top of the stack.
-    *(stack.Begin() + topIndex) = index;
+    // Set the item in the top of the stack.
+    *(stack.Begin() + topIndex) = item;
 
     // Reposition the pointer to the top of the stack.
     ++topIndex;
   }
 
-  RunIndex Pop()
+  StyleStackType Pop()
   {
     // Pop the top of the stack.
     --topIndex;
@@ -125,6 +128,17 @@ struct StyleStack
 };
 
 /**
+ * @brief Struct used to retrieve spans from the mark-up string.
+ */
+struct Span
+{
+  RunIndex colorRunIndex;
+  RunIndex fontRunIndex;
+  bool     isColorDefined;
+  bool     isFontDefined;
+};
+
+/**
  * @brief Initializes a font run description to its defaults.
  *
  * @param[in,out] fontRun The font description run to initialize.
@@ -169,6 +183,19 @@ void Initialize(UnderlinedCharacterRun& underlinedCharacterRun)
 }
 
 /**
+ * @brief Initializes a span to its defaults.
+ *
+ * @param[in,out] span The span to be initialized.
+ */
+void Initialize(Span& span)
+{
+  span.colorRunIndex  = 0u;
+  span.isColorDefined = false;
+  span.fontRunIndex   = 0u;
+  span.isFontDefined  = false;
+}
+
+/**
  * @brief Splits the tag string into the tag name and its attributes.
  *
  * The attributes are stored in a vector in the tag.
@@ -526,10 +553,10 @@ bool XHTMLNumericEntityToUtf8(const char* markupText, char* utf8)
 template<typename RunType>
 void ProcessTagForRun(
   Vector<RunType>&                          runsContainer,
-  StyleStack&                               styleStack,
+  StyleStack<RunIndex>&                     styleStack,
   const Tag&                                tag,
   const CharacterIndex                      characterIndex,
-  StyleStack::RunIndex&                     runIndex,
+  RunIndex&                                 runIndex,
   int&                                      tagReference,
   std::function<void(const Tag&, RunType&)> parameterSettingFunction)
 {
@@ -627,6 +654,94 @@ void ProcessAnchorTag(
 }
 
 /**
+ * @brief Processes span tag for the color-run & font-run.
+ *
+ * @param[in] spanTag The tag we are currently processing
+ * @param[in/out] spanStack The spans stack
+ * @param[int/out] colorRuns The container containing all the color runs
+ * @param[int/out] fontRuns The container containing all the font description runs
+ * @param[in/out] colorRunIndex The color run index
+ * @param[in/out] fontRunIndex The font run index
+ * @param[in] characterIndex The current character index
+ * @param[in] tagReference The tagReference we should increment/decrement
+ */
+void ProcessSpanForRun(
+  const Tag&                  spanTag,
+  StyleStack<Span>&           spanStack,
+  Vector<ColorRun>&           colorRuns,
+  Vector<FontDescriptionRun>& fontRuns,
+  RunIndex&                   colorRunIndex,
+  RunIndex&                   fontRunIndex,
+  const CharacterIndex        characterIndex,
+  int&                        tagReference)
+{
+  if(!spanTag.isEndTag)
+  {
+    // Create a new run.
+    ColorRun colorRun;
+    Initialize(colorRun);
+
+    FontDescriptionRun fontRun;
+    Initialize(fontRun);
+
+    Span span;
+    Initialize(span);
+
+    // Fill the run with the parameters.
+    colorRun.characterRun.characterIndex = characterIndex;
+    fontRun.characterRun.characterIndex  = characterIndex;
+
+    span.colorRunIndex = colorRunIndex;
+    span.fontRunIndex  = fontRunIndex;
+
+    ProcessSpanTag(spanTag, colorRun, fontRun, span.isColorDefined, span.isFontDefined);
+
+    // Push the span into the stack.
+    spanStack.Push(span);
+
+    // Point the next free run.
+    if(span.isColorDefined)
+    {
+      // Push the run in the logical model.
+      colorRuns.PushBack(colorRun);
+      ++colorRunIndex;
+    }
+
+    if(span.isFontDefined)
+    {
+      // Push the run in the logical model.
+      fontRuns.PushBack(fontRun);
+      ++fontRunIndex;
+    }
+
+    // Increase reference
+    ++tagReference;
+  }
+  else
+  {
+    if(tagReference > 0)
+    {
+      // Pop the top of the stack and set the number of characters of the run.
+      Span span = spanStack.Pop();
+
+      if(span.isColorDefined)
+      {
+        ColorRun& colorRun                       = *(colorRuns.Begin() + span.colorRunIndex);
+        colorRun.characterRun.numberOfCharacters = characterIndex - colorRun.characterRun.characterIndex;
+      }
+
+      if(span.isFontDefined)
+      {
+        FontDescriptionRun& fontRun             = *(fontRuns.Begin() + span.fontRunIndex);
+        fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
+      }
+
+      --tagReference;
+    }
+  }
+}
+
+/**
  * @brief Resizes the model's vectors
  *
  * @param[in/out] markupProcessData The markup process data
@@ -635,7 +750,7 @@ void ProcessAnchorTag(
  * @param[in] underlinedCharacterRunIndex The underlined character run index
  * @param[in] backgroundRunIndex The background run index
  */
-void ResizeModelVectors(MarkupProcessData& markupProcessData, const StyleStack::RunIndex fontRunIndex, const StyleStack::RunIndex colorRunIndex, const StyleStack::RunIndex underlinedCharacterRunIndex, const StyleStack::RunIndex backgroundRunIndex)
+void ResizeModelVectors(MarkupProcessData& markupProcessData, const RunIndex fontRunIndex, const RunIndex colorRunIndex, const RunIndex underlinedCharacterRunIndex, const RunIndex backgroundRunIndex)
 {
   markupProcessData.fontRuns.Resize(fontRunIndex);
   markupProcessData.colorRuns.Resize(colorRunIndex);
@@ -754,13 +869,16 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar
   markupProcessData.markupProcessedText.reserve(markupStringSize);
 
   // Stores a struct with the index to the first character of the run, the type of run and its parameters.
-  StyleStack styleStack;
+  StyleStack<RunIndex> styleStack;
+
+  // Stores a struct with the index to the first character of the color run & color font for the span.
+  StyleStack<Span> spanStack;
 
   // Points the next free position in the vector of runs.
-  StyleStack::RunIndex colorRunIndex               = 0u;
-  StyleStack::RunIndex fontRunIndex                = 0u;
-  StyleStack::RunIndex underlinedCharacterRunIndex = 0u;
-  StyleStack::RunIndex backgroundRunIndex          = 0u;
+  RunIndex colorRunIndex               = 0u;
+  RunIndex fontRunIndex                = 0u;
+  RunIndex underlinedCharacterRunIndex = 0u;
+  RunIndex backgroundRunIndex          = 0u;
 
   // check tag reference
   int colorTagReference      = 0u;
@@ -769,6 +887,7 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar
   int bTagReference          = 0u;
   int uTagReference          = 0u;
   int backgroundTagReference = 0u;
+  int spanTagReference       = 0u;
 
   // Give an initial default value to the model's vectors.
   markupProcessData.colorRuns.Reserve(DEFAULT_VECTOR_SIZE);
@@ -856,6 +975,10 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar
         ProcessTagForRun<ColorRun>(
           markupProcessData.backgroundColorRuns, styleStack, tag, characterIndex, backgroundRunIndex, backgroundTagReference, [](const Tag& tag, ColorRun& run) { ProcessBackground(tag, run); });
       }
+      else if(TokenComparison(XHTML_SPAN_TAG, tag.buffer, tag.length))
+      {
+        ProcessSpanForRun(tag, spanStack, markupProcessData.colorRuns, markupProcessData.fontRuns, colorRunIndex, fontRunIndex, characterIndex, spanTagReference);
+      }
     } // end if( IsTag() )
     else if(markupStringBuffer < markupStringEndBuffer)
     {
index c17c820..15805c8 100644 (file)
@@ -247,12 +247,36 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE
       DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::KeyEvent %p keyString %s\n", &controller, keyString.c_str());
       if(!controller.IsEditable()) return false;
 
-      if(!keyString.empty())
+      std::string refinedKey = keyString;
+      if(controller.mImpl->mInputFilter != NULL && !refinedKey.empty())
+      {
+        bool accepted = false;
+        bool rejected = false;
+        accepted      = controller.mImpl->mInputFilter->Contains(Toolkit::InputFilter::Property::ACCEPTED, keyString);
+        rejected      = controller.mImpl->mInputFilter->Contains(Toolkit::InputFilter::Property::REJECTED, keyString);
+
+        if(!accepted)
+        {
+          // The filtered key is set to empty.
+          refinedKey = "";
+          // Signal emits when the character to be inserted is filtered by the accepted filter.
+          controller.mImpl->mEditableControlInterface->InputFiltered(Toolkit::InputFilter::Property::ACCEPTED);
+        }
+        if(rejected)
+        {
+          // The filtered key is set to empty.
+          refinedKey = "";
+          // Signal emits when the character to be inserted is filtered by the rejected filter.
+          controller.mImpl->mEditableControlInterface->InputFiltered(Toolkit::InputFilter::Property::REJECTED);
+        }
+      }
+
+      if(!refinedKey.empty())
       {
         // InputMethodContext is no longer handling key-events
         controller.mImpl->ClearPreEditFlag();
 
-        controller.InsertText(keyString, COMMIT);
+        controller.InsertText(refinedKey, COMMIT);
 
         textChanged = true;
 
index 9f637d3..55184ef 100644 (file)
@@ -338,6 +338,7 @@ struct Controller::Impl
     mOperationsPending(NO_OPERATION),
     mMaximumNumberOfCharacters(50u),
     mHiddenInput(NULL),
+    mInputFilter(nullptr),
     mRecalculateNaturalSize(true),
     mMarkupProcessorEnabled(false),
     mClipboardHideEnabled(true),
@@ -386,7 +387,6 @@ struct Controller::Impl
   ~Impl()
   {
     delete mHiddenInput;
-
     delete mFontDefaults;
     delete mUnderlineDefaults;
     delete mShadowDefaults;
@@ -793,29 +793,30 @@ private:
   void CopyUnderlinedFromLogicalToVisualModels(bool shouldClearPreUnderlineRuns);
 
 public:
-  ControlInterface*           mControlInterface;           ///< Reference to the text controller.
-  EditableControlInterface*   mEditableControlInterface;   ///< Reference to the editable text controller.
-  SelectableControlInterface* mSelectableControlInterface; ///< Reference to the selectable text controller.
-  AnchorControlInterface*     mAnchorControlInterface;     ///< Reference to the anchor controller.
-  ModelPtr                    mModel;                      ///< Pointer to the text's model.
-  FontDefaults*               mFontDefaults;               ///< Avoid allocating this when the user does not specify a font.
-  UnderlineDefaults*          mUnderlineDefaults;          ///< Avoid allocating this when the user does not specify underline parameters.
-  ShadowDefaults*             mShadowDefaults;             ///< Avoid allocating this when the user does not specify shadow parameters.
-  EmbossDefaults*             mEmbossDefaults;             ///< Avoid allocating this when the user does not specify emboss parameters.
-  OutlineDefaults*            mOutlineDefaults;            ///< Avoid allocating this when the user does not specify outline parameters.
-  EventData*                  mEventData;                  ///< Avoid allocating everything for text input until EnableTextInput().
-  TextAbstraction::FontClient mFontClient;                 ///< Handle to the font client.
-  Clipboard                   mClipboard;                  ///< Handle to the system clipboard
-  View                        mView;                       ///< The view interface to the rendering back-end.
-  MetricsPtr                  mMetrics;                    ///< A wrapper around FontClient used to get metrics & potentially down-scaled Emoji metrics.
-  Layout::Engine              mLayoutEngine;               ///< The layout engine.
-  Vector<ModifyEvent>         mModifyEvents;               ///< Temporary stores the text set until the next relayout.
-  Vector4                     mTextColor;                  ///< The regular text color
-  TextUpdateInfo              mTextUpdateInfo;             ///< Info of the characters updated.
-  OperationsMask              mOperationsPending;          ///< Operations pending to be done to layout the text.
-  Length                      mMaximumNumberOfCharacters;  ///< Maximum number of characters that can be inserted.
-  HiddenText*                 mHiddenInput;                ///< Avoid allocating this when the user does not specify hidden input mode.
-  Vector2                     mTextFitContentSize;         ///< Size of Text fit content
+  ControlInterface*            mControlInterface;           ///< Reference to the text controller.
+  EditableControlInterface*    mEditableControlInterface;   ///< Reference to the editable text controller.
+  SelectableControlInterface*  mSelectableControlInterface; ///< Reference to the selectable text controller.
+  AnchorControlInterface*      mAnchorControlInterface;     ///< Reference to the anchor controller.
+  ModelPtr                     mModel;                      ///< Pointer to the text's model.
+  FontDefaults*                mFontDefaults;               ///< Avoid allocating this when the user does not specify a font.
+  UnderlineDefaults*           mUnderlineDefaults;          ///< Avoid allocating this when the user does not specify underline parameters.
+  ShadowDefaults*              mShadowDefaults;             ///< Avoid allocating this when the user does not specify shadow parameters.
+  EmbossDefaults*              mEmbossDefaults;             ///< Avoid allocating this when the user does not specify emboss parameters.
+  OutlineDefaults*             mOutlineDefaults;            ///< Avoid allocating this when the user does not specify outline parameters.
+  EventData*                   mEventData;                  ///< Avoid allocating everything for text input until EnableTextInput().
+  TextAbstraction::FontClient  mFontClient;                 ///< Handle to the font client.
+  Clipboard                    mClipboard;                  ///< Handle to the system clipboard
+  View                         mView;                       ///< The view interface to the rendering back-end.
+  MetricsPtr                   mMetrics;                    ///< A wrapper around FontClient used to get metrics & potentially down-scaled Emoji metrics.
+  Layout::Engine               mLayoutEngine;               ///< The layout engine.
+  Vector<ModifyEvent>          mModifyEvents;               ///< Temporary stores the text set until the next relayout.
+  Vector4                      mTextColor;                  ///< The regular text color
+  TextUpdateInfo               mTextUpdateInfo;             ///< Info of the characters updated.
+  OperationsMask               mOperationsPending;          ///< Operations pending to be done to layout the text.
+  Length                       mMaximumNumberOfCharacters;  ///< Maximum number of characters that can be inserted.
+  HiddenText*                  mHiddenInput;                ///< Avoid allocating this when the user does not specify hidden input mode.
+  std::unique_ptr<InputFilter> mInputFilter;                ///< Avoid allocating this when the user does not specify input filter mode.
+  Vector2                      mTextFitContentSize;         ///< Size of Text fit content
 
   bool               mRecalculateNaturalSize : 1; ///< Whether the natural size needs to be recalculated.
   bool               mMarkupProcessorEnabled : 1; ///< Whether the mark-up procesor is enabled.
index 134a327..062153d 100644 (file)
@@ -48,7 +48,6 @@ namespace Toolkit
 {
 namespace Text
 {
-
 Size Controller::Relayouter::CalculateLayoutSizeOnRequiredControllerSize(Controller& controller, const Size& requestedControllerSize, const OperationsMask& requestedOperationsMask, bool restoreLinesAndGlyphPositions)
 {
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "-->CalculateLayoutSizeOnRequiredControllerSize\n");
@@ -66,7 +65,7 @@ Size Controller::Relayouter::CalculateLayoutSizeOnRequiredControllerSize(Control
   // The number of lines and glyph-positions inside visualModel have been changed by calling DoRelayout with requestedControllerSize.
   // Store the mLines and mGlyphPositions from visualModel so that they can be restored later on with no modifications made on them.
   //TODO: Refactor "DoRelayout" and extract common code of size calculation without modifying attributes of mVisualModel, and then blah, blah, etc.
-  Vector<LineRun> linesBackup = visualModel->mLines;
+  Vector<LineRun> linesBackup          = visualModel->mLines;
   Vector<Vector2> glyphPositionsBackup = visualModel->mGlyphPositions;
 
   // Operations that can be done only once until the text changes.
@@ -96,11 +95,10 @@ Size Controller::Relayouter::CalculateLayoutSizeOnRequiredControllerSize(Control
   const Size actualControlSize = visualModel->mControlSize;
 
   DoRelayout(controller,
-              requestedControllerSize,
-              static_cast<OperationsMask>(onlyOnceOperations |
-                                          requestedOperationsMask),
-              calculatedLayoutSize);
-
+             requestedControllerSize,
+             static_cast<OperationsMask>(onlyOnceOperations |
+                                         requestedOperationsMask),
+             calculatedLayoutSize);
 
   // Clear the update info. This info will be set the next time the text is updated.
   textUpdateInfo.Clear();
@@ -114,14 +112,13 @@ Size Controller::Relayouter::CalculateLayoutSizeOnRequiredControllerSize(Control
   // Restore the previously backed-up mLines and mGlyphPositions from visualModel.
   if(restoreLinesAndGlyphPositions)
   {
-    visualModel->mLines = linesBackup;
+    visualModel->mLines          = linesBackup;
     visualModel->mGlyphPositions = glyphPositionsBackup;
   }
 
   return calculatedLayoutSize;
 }
 
-
 Vector3 Controller::Relayouter::GetNaturalSize(Controller& controller)
 {
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "-->Controller::GetNaturalSize\n");
@@ -130,17 +127,17 @@ Vector3 Controller::Relayouter::GetNaturalSize(Controller& controller)
   // Make sure the model is up-to-date before layouting
   controller.ProcessModifyEvents();
 
-  Controller::Impl& impl           = *controller.mImpl;
-  ModelPtr&         model          = impl.mModel;
-  VisualModelPtr&   visualModel    = model->mVisualModel;
+  Controller::Impl& impl        = *controller.mImpl;
+  ModelPtr&         model       = impl.mModel;
+  VisualModelPtr&   visualModel = model->mVisualModel;
 
   if(impl.mRecalculateNaturalSize)
   {
     Size naturalSize;
 
     // Layout the text for the new width.
-    OperationsMask requestedOperationsMask = static_cast<OperationsMask>(LAYOUT | REORDER);
-    Size sizeMaxWidthAndMaxHeight = Size(MAX_FLOAT, MAX_FLOAT);
+    OperationsMask requestedOperationsMask  = static_cast<OperationsMask>(LAYOUT | REORDER);
+    Size           sizeMaxWidthAndMaxHeight = Size(MAX_FLOAT, MAX_FLOAT);
 
     naturalSize = CalculateLayoutSizeOnRequiredControllerSize(controller, sizeMaxWidthAndMaxHeight, requestedOperationsMask, true);
 
@@ -282,10 +279,9 @@ float Controller::Relayouter::GetHeightForWidth(Controller& controller, float wi
      textUpdateInfo.mFullRelayoutNeeded ||
      textUpdateInfo.mClearAll)
   {
-
     // Layout the text for the new width.
-    OperationsMask requestedOperationsMask = static_cast<OperationsMask>(LAYOUT);
-    Size sizeRequestedWidthAndMaxHeight = Size(width, MAX_FLOAT);
+    OperationsMask requestedOperationsMask        = static_cast<OperationsMask>(LAYOUT);
+    Size           sizeRequestedWidthAndMaxHeight = Size(width, MAX_FLOAT);
 
     // Skip restore, because if GetHeightForWidth called before rendering and layouting then visualModel->mControlSize will be zero which will make LineCount zero.
     // The implementation of Get LineCount property depends on calling GetHeightForWidth then read mLines.Count() from visualModel direct.
@@ -293,8 +289,7 @@ float Controller::Relayouter::GetHeightForWidth(Controller& controller, float wi
     // So we will not restore the previously backed-up mLines and mGlyphPositions from visualModel in such case.
     // Another case to skip restore is when the requested width equals the Control's width which means the caller need to update the old values.
     // For example, when the text is changed.
-    bool restoreLinesAndGlyphPositions = (visualModel->mControlSize.width>0 && visualModel->mControlSize.height>0)
-                                          && (visualModel->mControlSize.width != width);
+    bool restoreLinesAndGlyphPositions = (visualModel->mControlSize.width > 0 && visualModel->mControlSize.height > 0) && (visualModel->mControlSize.width != width);
 
     layoutSize = CalculateLayoutSizeOnRequiredControllerSize(controller, sizeRequestedWidthAndMaxHeight, requestedOperationsMask, restoreLinesAndGlyphPositions);
 
@@ -642,13 +637,13 @@ bool Controller::Relayouter::DoRelayout(Controller& controller, const Size& size
 
 void Controller::Relayouter::CalculateVerticalOffset(Controller& controller, const Size& controlSize)
 {
-  Controller::Impl& impl          = *controller.mImpl;
-  ModelPtr&         model         = impl.mModel;
-  VisualModelPtr&   visualModel   = model->mVisualModel;
-  Size              layoutSize    = model->mVisualModel->GetLayoutSize();
-  Size              oldLayoutSize = layoutSize;
-  float             offsetY       = 0.f;
-  bool              needRecalc    = false;
+  Controller::Impl& impl                  = *controller.mImpl;
+  ModelPtr&         model                 = impl.mModel;
+  VisualModelPtr&   visualModel           = model->mVisualModel;
+  Size              layoutSize            = model->mVisualModel->GetLayoutSize();
+  Size              oldLayoutSize         = layoutSize;
+  float             offsetY               = 0.f;
+  bool              needRecalc            = false;
   float             defaultFontLineHeight = impl.GetDefaultFontLineHeight();
 
   if(fabsf(layoutSize.height) < Math::MACHINE_EPSILON_1000)
@@ -659,12 +654,12 @@ void Controller::Relayouter::CalculateVerticalOffset(Controller& controller, con
 
   // Whether the text control is editable
   const bool isEditable = NULL != impl.mEventData;
-  if (isEditable && layoutSize.height != defaultFontLineHeight)
+  if(isEditable && layoutSize.height != defaultFontLineHeight && impl.IsShowingPlaceholderText())
   {
     // This code prevents the wrong positioning of cursor when the layout size is bigger/smaller than defaultFontLineHeight.
     // This situation occurs when the size of placeholder text is different from the default text.
     layoutSize.height = defaultFontLineHeight;
-    needRecalc = true;
+    needRecalc        = true;
   }
 
   switch(model->mVerticalAlignment)
@@ -672,34 +667,33 @@ void Controller::Relayouter::CalculateVerticalOffset(Controller& controller, con
     case VerticalAlignment::TOP:
     {
       model->mScrollPosition.y = 0.f;
-      offsetY = 0.f;
+      offsetY                  = 0.f;
       break;
     }
     case VerticalAlignment::CENTER:
     {
       model->mScrollPosition.y = floorf(0.5f * (controlSize.height - layoutSize.height)); // try to avoid pixel alignment.
-      if (needRecalc) offsetY  = floorf(0.5f * (layoutSize.height - oldLayoutSize.height));
+      if(needRecalc) offsetY = floorf(0.5f * (layoutSize.height - oldLayoutSize.height));
       break;
     }
     case VerticalAlignment::BOTTOM:
     {
       model->mScrollPosition.y = controlSize.height - layoutSize.height;
-      if (needRecalc) offsetY  = layoutSize.height - oldLayoutSize.height;
+      if(needRecalc) offsetY = layoutSize.height - oldLayoutSize.height;
       break;
     }
   }
 
-  if (needRecalc)
+  if(needRecalc)
   {
     // Update glyphPositions according to recalculation.
-    const Length positionCount = visualModel->mGlyphPositions.Count();
+    const Length     positionCount  = visualModel->mGlyphPositions.Count();
     Vector<Vector2>& glyphPositions = visualModel->mGlyphPositions;
     for(Length index = 0u; index < positionCount; index++)
     {
       glyphPositions[index].y += offsetY;
     }
   }
-
 }
 
 } // namespace Text
index a863317..b2b6550 100644 (file)
@@ -1618,6 +1618,23 @@ void Controller::GetHiddenInputOption(Property::Map& options)
   }
 }
 
+void Controller::SetInputFilterOption(const Property::Map& options)
+{
+  if(!mImpl->mInputFilter)
+  {
+    mImpl->mInputFilter = std::unique_ptr<InputFilter>(new InputFilter());
+  }
+  mImpl->mInputFilter->SetProperties(options);
+}
+
+void Controller::GetInputFilterOption(Property::Map& options)
+{
+  if(NULL != mImpl->mInputFilter)
+  {
+    mImpl->mInputFilter->GetProperties(options);
+  }
+}
+
 void Controller::SetPlaceholderProperty(const Property::Map& map)
 {
   PlaceholderHandler::SetPlaceholderProperty(*this, map);
index aaa3a66..0802a77 100644 (file)
@@ -28,6 +28,7 @@
 #include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/hidden-text.h>
+#include <dali-toolkit/internal/text/input-filter.h>
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
 #include <dali-toolkit/internal/text/text-anchor-control-interface.h>
 #include <dali-toolkit/internal/text/text-model-interface.h>
@@ -1386,6 +1387,16 @@ public: // Queries & retrieves.
   void GetHiddenInputOption(Property::Map& options);
 
   /**
+   * @brief Used to set the input filter option
+   */
+  void SetInputFilterOption(const Property::Map& options);
+
+  /**
+   * @brief Used to get the input filter option
+   */
+  void GetInputFilterOption(Property::Map& options);
+
+  /**
    * @brief Sets the Placeholder Properties.
    *
    * @param[in] map The placeholder property map
index 4bd0de0..af2abd0 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/input-style.h>
+#include <dali-toolkit/public-api/controls/text-controls/input-filter-properties.h>
 
 namespace Dali
 {
@@ -77,6 +78,13 @@ public:
   virtual void InputStyleChanged(InputStyle::Mask inputStyleMask) = 0;
 
   /**
+   * @brief Called when the character to be inserted is filtered by the input filter.
+   *
+   * @param[in] type The filter type is ACCEPTED or REJECTED.
+   */
+  virtual void InputFiltered(Toolkit::InputFilter::Property::Type type) = 0;
+
+  /**
    * @brief Add a decoration.
    *
    * @param[in] decoration The actor displaying a decoration.
index 30edc3e..33bee66 100644 (file)
@@ -87,17 +87,20 @@ void Fade::OnPlay()
   Property::Map startPropertyMap;
   Property::Map finishPropertyMap;
 
+  float targetOpacity                              = GetWorldColor(targetControl).a;
+  targetControl[Dali::Actor::Property::COLOR_MODE] = Dali::ColorMode::USE_OWN_COLOR;
+
   if(IsAppearingTransition())
   {
     initialPropertyMap.Insert(Dali::Actor::Property::OPACITY, 0.0f);
-    startPropertyMap.Insert(Dali::Actor::Property::OPACITY, mOpacity);
-    finishPropertyMap.Insert(Dali::Actor::Property::OPACITY, targetControl[Dali::Actor::Property::OPACITY]);
+    startPropertyMap.Insert(Dali::Actor::Property::OPACITY, mOpacity * targetOpacity);
+    finishPropertyMap.Insert(Dali::Actor::Property::OPACITY, targetOpacity);
   }
   else
   {
-    initialPropertyMap.Insert(Dali::Actor::Property::OPACITY, targetControl[Dali::Actor::Property::OPACITY]);
-    startPropertyMap.Insert(Dali::Actor::Property::OPACITY, targetControl[Dali::Actor::Property::OPACITY]);
-    finishPropertyMap.Insert(Dali::Actor::Property::OPACITY, mOpacity);
+    initialPropertyMap.Insert(Dali::Actor::Property::OPACITY, targetOpacity);
+    startPropertyMap.Insert(Dali::Actor::Property::OPACITY, targetOpacity);
+    finishPropertyMap.Insert(Dali::Actor::Property::OPACITY, mOpacity * targetOpacity);
   }
 
   SetInitialPropertyMap(initialPropertyMap);
index 1a8c238..e104adf 100644 (file)
@@ -30,13 +30,23 @@ namespace Toolkit
 {
 namespace Internal
 {
+std::unique_ptr<TransitionLifecycleController> TransitionLifecycleController::mInstance = nullptr;
+std::once_flag                                 TransitionLifecycleController::mOnceFlag;
+
+TransitionLifecycleController& TransitionLifecycleController::GetInstance()
+{
+  std::call_once(mOnceFlag, []()
+                 { mInstance.reset(new TransitionLifecycleController); });
+  return *(mInstance.get());
+}
+
 void TransitionLifecycleController::AddTransitions(Dali::Toolkit::TransitionSet transitions)
 {
   mTransitionList.push_back(transitions);
   transitions.FinishedSignal().Connect(this, &TransitionLifecycleController::RemoveTransitions);
 }
 
-void TransitionLifecycleController::RemoveTransitions(Dali::Toolkit::TransitionSet &transitions)
+void TransitionLifecycleController::RemoveTransitions(Dali::Toolkit::TransitionSettransitions)
 {
   mTransitionList.erase(std::remove(mTransitionList.begin(), mTransitionList.end(), transitions));
 }
index 8511635..b064f1e 100644 (file)
@@ -33,24 +33,11 @@ namespace Toolkit
 {
 namespace Internal
 {
-class TransitionLifecycleController;
-
-namespace
-{
-std::unique_ptr<TransitionLifecycleController> instance = nullptr;
-std::once_flag                                 onceFlag;
-} // namespace
 
 class TransitionLifecycleController : public ConnectionTracker
 {
 public:
-  static TransitionLifecycleController& GetInstance()
-  {
-    std::call_once(onceFlag, []() {
-      instance.reset(new TransitionLifecycleController);
-    });
-    return *(instance.get());
-  }
+  static TransitionLifecycleController& GetInstance();
 
   void AddTransitions(Dali::Toolkit::TransitionSet transitions);
 
@@ -70,7 +57,9 @@ private:
   TransitionLifecycleController& operator=(const TransitionLifecycleController& rhs) = delete;
 
 private:
-  std::vector<Dali::Toolkit::TransitionSet> mTransitionList;
+  std::vector<Dali::Toolkit::TransitionSet>             mTransitionList;
+  static std::unique_ptr<TransitionLifecycleController> mInstance;
+  static std::once_flag                                 mOnceFlag;
 };
 
 } // namespace Internal
index 6bbc2df..8c4b2f8 100644 (file)
@@ -166,7 +166,6 @@ Toolkit::Visual::Base VisualFactory::CreateVisual(const Property::Map& propertyM
                 break;
               }
               case VisualUrl::JSON:
-              case VisualUrl::RIVE:
               {
                 visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
                 break;
@@ -331,7 +330,6 @@ Toolkit::Visual::Base VisualFactory::CreateVisual(const std::string& url, ImageD
         break;
       }
       case VisualUrl::JSON:
-      case VisualUrl::RIVE:
       {
         visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
         break;
index 97bc9b9..e498313 100644 (file)
@@ -103,12 +103,10 @@ VisualUrl::Type ResolveType(const std::string& url)
     char         GIF[4]    = {'f', 'i', 'g', '.'};
     char         WEBP[5]   = {'p', 'b', 'e', 'w', '.'};
     char         JSON[5]   = {'n', 'o', 's', 'j', '.'};
-    char         RIVE[4]   = {'v', 'i', 'r', '.'};
     unsigned int svgScore  = 0;
     unsigned int gifScore  = 0;
     unsigned int webpScore = 0;
     unsigned int jsonScore = 0;
-    unsigned int riveScore = 0;
     int          index     = count;
     while(--index >= 0)
     {
@@ -146,14 +144,6 @@ VisualUrl::Type ResolveType(const std::string& url)
           return VisualUrl::JSON;
         }
       }
-      if((offsetFromEnd < sizeof(RIVE)) && (currentChar == RIVE[offsetFromEnd]))
-      {
-        // early out if RIVE as can't be used in N patch for now
-        if(++riveScore == sizeof(RIVE))
-        {
-          return VisualUrl::RIVE;
-        }
-      }
       switch(state)
       {
         case SUFFIX:
index 827dfce..8857184 100644 (file)
@@ -38,8 +38,7 @@ public:
     SVG,
     GIF,
     WEBP,
-    JSON,
-    RIVE
+    JSON
   };
 
   enum ProtocolType
index 414fb07..20fcb02 100755 (executable)
@@ -20,3 +20,5 @@ msgstr "لصق"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "الحافظة"
 
+msgid "slider"
+msgstr ""
index 6581e52..cfd4a80 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Yapışdır"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Mübadilə buferi"
 
+msgid "icon"
+msgstr "Piktoqram"
+
+msgid "slider"
+msgstr "Sürüngəc"
index 52a2d78..4b13de1 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Поставяне"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Системен буфер"
 
+msgid "icon"
+msgstr "Икона"
+
+msgid "slider"
+msgstr "Плъзгач"
index c29c744..a6191a8 100644 (file)
@@ -16,3 +16,8 @@ msgstr "পেস্ট করুন"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "ক্লিপবোর্ড"
 
+msgid "icon"
+msgstr "Icon"
+
+msgid "slider"
+msgstr "স্লাইডার"
index 34c6125..ba85f18 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Enganxar"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Porta-retalls"
 
+msgid "slider"
+msgstr "control lliscant"
index c8c68f9..3e4f477 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Vložit"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Schránka"
 
+msgid "slider"
+msgstr "šoupátko"
index 0898d64..fea998c 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Indsæt"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Udklipsholder"
 
+msgid "icon"
+msgstr "Ikon"
+
+msgid "slider"
+msgstr "skyder"
index 3082bbb..f1b0020 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Einfügen"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Zwischenablage"
 
+msgid "slider"
+msgstr ""
index 8f93b05..3ed1056 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Επικόλληση"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Πρόχειρο"
 
+msgid "icon"
+msgstr "Εικονίδιο"
+
+msgid "slider"
+msgstr "Ρυθμιστικό"
index 2579c1c..9945b39 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Paste"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Clipboard"
 
+msgid "icon"
+msgstr "Icon"
+
+msgid "slider"
+msgstr "Slider"
index 2579c1c..9945b39 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Paste"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Clipboard"
 
+msgid "icon"
+msgstr "Icon"
+
+msgid "slider"
+msgstr "Slider"
index 5fed085..b0b516e 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Pegar"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Portapapeles"
 
+msgid "icon"
+msgstr "Icono"
+
+msgid "slider"
+msgstr "Controlador deslizante"
index fdb40d8..5e7ec49 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Pegar"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Portapapeles"
 
+msgid "icon"
+msgstr "Icono"
+
+msgid "slider"
+msgstr "Controlador deslizante"
index 361b88a..a68fc27 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Kleebi"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Lõikelaud"
 
+msgid "icon"
+msgstr "Ikoon"
+
+msgid "slider"
+msgstr "Liugur"
index 86fe6e5..616c68f 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Itsatsi"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Arbela"
 
+msgid "icon"
+msgstr "Ikonoa"
+
+msgid "slider"
+msgstr "Irristagailua"
index 5e8369b..5ac66a0 100644 (file)
@@ -20,3 +20,5 @@ msgstr "الحاق"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "کلیپ بورد"
 
+msgid "slider"
+msgstr ""
index fd23422..f6c7931 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Liitä"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Leikepöytä"
 
+msgid "slider"
+msgstr "liukusäädin"
index e217eef..dfff479 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Coller"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Presse-papier"
 
+msgid "slider"
+msgstr "curseur"
index 0a8fdd2..7902515 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Coller"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Presse-papier"
 
+msgid "icon"
+msgstr "Icône"
+
+msgid "slider"
+msgstr "Curseur"
index 3e66cbf..4b08c18 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Pegar"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Portapapeis"
 
+msgid "slider"
+msgstr "Barra de desprazamento"
index 6c8a251..436f894 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Zalijepi"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Međuspremnik"
 
+msgid "icon"
+msgstr "Ikona"
+
+msgid "slider"
+msgstr "Klizač"
index accab91..367144c 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Beilleszt"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Vágólap"
 
+msgid "slider"
+msgstr "csúszka"
index 9892948..42a66e1 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Տեղադրել"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Գզրոց"
 
+msgid "icon"
+msgstr "Պատկերակ"
+
+msgid "slider"
+msgstr "Սողանիկ"
index bd1952e..fe0b00d 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Líma"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Klippiborð"
 
+msgid "icon"
+msgstr "Tákn"
+
+msgid "slider"
+msgstr "Skyggna"
index f68a4f9..0f578de 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Incolla"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Appunti"
 
+msgid "icon"
+msgstr "Icona"
+
+msgid "slider"
+msgstr "Dispositivo di scorrimento"
index 5dd6d53..28f1b73 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "ჩასმა"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "ბუფერული მეხს."
 
+msgid "icon"
+msgstr "ნიშანი"
+
+msgid "slider"
+msgstr "სლაიდერი"
index 6de1a32..20845c9 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Қою"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Буфер"
 
+msgid "icon"
+msgstr "Белгіше"
+
+msgid "slider"
+msgstr "Сырғытпа"
index 8ecb8d3..dadd773 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "붙여넣기"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "클립보드"
 
+msgid "slider"
+msgstr "슬라이더"
index d403fcc..4163cd3 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Įklijuoti"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Iškarpinė"
 
+msgid "slider"
+msgstr "šliaužiklis"
index 519597b..9698938 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Ielīmēt"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Starpliktuve"
 
+msgid "icon"
+msgstr "Ikona"
+
+msgid "slider"
+msgstr "Slīdnis"
index cc2b51b..ee6fc24 100644 (file)
@@ -16,3 +16,8 @@ msgstr "Буулгах"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Түр санах ой"
 
+msgid "icon"
+msgstr "Дүрс"
+
+msgid "slider"
+msgstr "Slider"
index 0c15456..ae6d545 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Lim inn"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Utklippstavle"
 
+msgid "icon"
+msgstr "Ikon"
+
+msgid "slider"
+msgstr "Glidebryter"
index 48645c4..16e7bd4 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Plakken"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Klembord"
 
+msgid "slider"
+msgstr ""
index c87ec62..b1a99b5 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Wklej"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Schowek"
 
+msgid "slider"
+msgstr "slajder"
index 9c6743a..eb86f8e 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Colar"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Área de transferência"
 
+msgid "icon"
+msgstr "Ícone"
+
+msgid "slider"
+msgstr "Controle deslizante"
index e1a21da..b6c820e 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Colar"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Área transferência"
 
+msgid "icon"
+msgstr "Ícone"
+
+msgid "slider"
+msgstr "Cursor de deslocamento"
index 0d78703..4e5278e 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Lipire"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Clipboard"
 
+msgid "icon"
+msgstr "Pictogr."
+
+msgid "slider"
+msgstr "Cursor"
index 8134f66..c7dc38c 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Вставить"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Буфер обмена"
 
+msgid "icon"
+msgstr "Значок"
+
+msgid "slider"
+msgstr "Ползунок"
index 1944646..327899d 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Vložiť"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Schránka"
 
+msgid "icon"
+msgstr "Ikona"
+
+msgid "slider"
+msgstr "Posuvný ovládač"
index 4c8ad23..6de5ccd 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Prilepi"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Odložišče"
 
+msgid "slider"
+msgstr "drsnik"
index 1be1832..d792061 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "Zalepi"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Privremena memorija"
 
+msgid "slider"
+msgstr "клизач"
index 13c587d..573dd6a 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Klistra in"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Urklipp"
 
+msgid "icon"
+msgstr "Ikon"
+
+msgid "slider"
+msgstr "Slider"
index a360194..e116eec 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Yapıştır"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Pano"
 
+msgid "icon"
+msgstr "Simge"
+
+msgid "slider"
+msgstr "Kaydırıcı"
index c41b559..baab2fa 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Вставити"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Буфер обміну"
 
+msgid "icon"
+msgstr "Значок"
+
+msgid "slider"
+msgstr "Слайдер"
index b4bf3be..b663b28 100644 (file)
@@ -20,3 +20,5 @@ msgstr "جوڑ دیں"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "کلپ بورڈ"
 
+msgid "slider"
+msgstr ""
index bcad8b0..bdce823 100755 (executable)
@@ -16,3 +16,8 @@ msgstr "Qo‘shib qo‘yish"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Bufer"
 
+msgid "icon"
+msgstr "Ikoncha"
+
+msgid "slider"
+msgstr "Slider"
index e22211f..5c1e515 100644 (file)
@@ -16,3 +16,5 @@ msgstr "Dán"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "Bộ nhớ tạm"
 
+msgid "slider"
+msgstr "Thanh Trượt"
index b80e9d9..603d05f 100755 (executable)
@@ -16,3 +16,5 @@ msgstr "粘贴"
 msgid "IDS_COM_BODY_CLIPBOARD"
 msgstr "剪贴板"
 
+msgid "slider"
+msgstr "滑块"
diff --git a/dali-toolkit/public-api/controls/text-controls/input-filter-properties.h b/dali-toolkit/public-api/controls/text-controls/input-filter-properties.h
new file mode 100644 (file)
index 0000000..6f9b07f
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef DALI_INPUT_FILTER_PROPERTIES_H
+#define DALI_INPUT_FILTER_PROPERTIES_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+namespace Toolkit
+{
+/**
+ * @addtogroup dali_toolkit_controls_text_controls
+ * @{
+ */
+
+namespace InputFilter
+{
+/**
+ * @brief InputFilter Property.
+ * @SINCE_2_0.33
+ */
+namespace Property
+{
+/**
+ * @brief Enumeration for the type of InputFilter.
+ *
+ * An enum that determines the input filter type of the InputFilter map.
+ * Users can set the ACCEPTED or REJECTED character set, or both.
+ * If both are used, REJECTED has higher priority.
+ * The character set must follow the regular expression rules.
+ * Behaviour can not be guaranteed for incorrect grammars.
+ *
+ * Useful Meta characters:
+ *
+ * | %Meta characters  | Description
+ * |-------------------|------------------------------------------------------------------------------------------------------------|
+ * | \\w               | Matches an alphanumeric character, including "_"; same as [A-Za-z0-9_].                                    |
+ * | \\W               | Matches a non-alphanumeric character, excluding "_"; same as [^A-Za-z0-9_].                                |
+ * | \\s               | Matches a whitespace character, which in ASCII are tab, line feed, form feed, carriage return, and space.  |
+ * | \\S               | Matches anything but a whitespace.                                                                         |
+ * | \\d               | Matches a digit; same as [0-9].                                                                            |
+ * | \\D               | Matches a non-digit; same as [^0-9].                                                                       |
+ *
+ * Example Usage:
+ * @code
+ *   Property::Map filter;
+ *   filter[InputFilter::Property::ACCEPTED] = "[\\d]"; // accept whole digits
+ *   filter[InputFilter::Property::REJECTED] = "[0-5]"; // reject 0, 1, 2, 3, 4, 5
+ *
+ *   field.SetProperty(DevelTextField::Property::INPUT_FILTER, filter); // acceptable inputs are 6, 7, 8, 9
+ * @endcode
+ * @SINCE_2_0.33
+ */
+enum Type
+{
+  /**
+   * @brief The set of characters to be accepted.
+   * @details Name "accepted", type Property::STRING.
+   * @SINCE_2_0.33
+   * @note Available on regex string.
+   */
+  ACCEPTED,
+
+  /**
+   * @brief The set of characters to be rejected.
+   * @details Name "rejected", type Property::STRING.
+   * @SINCE_2_0.33
+   * @note Available on regex string.
+   */
+  REJECTED
+};
+
+} // namespace Property
+
+} // namespace InputFilter
+
+/**
+ * @}
+ */
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_INPUT_FILTER_PROPERTIES_H
index 1010fe1..02d0628 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 32;
+const unsigned int TOOLKIT_MICRO_VERSION = 33;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 895bfc7..15e202b 100644 (file)
@@ -114,6 +114,7 @@ SET( public_api_styling_header_files
 
 SET( public_api_text_controls_header_files
   ${public_api_src_dir}/controls/text-controls/hidden-input-properties.h
+  ${public_api_src_dir}/controls/text-controls/input-filter-properties.h
   ${public_api_src_dir}/controls/text-controls/placeholder-properties.h
   ${public_api_src_dir}/controls/text-controls/text-editor.h
   ${public_api_src_dir}/controls/text-controls/text-label.h
index 2c852c4..d4c7bdc 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.0.32
+Version:    2.0.33
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT