[dali_1.2.32] Merge branch 'devel/master' 76/120876/1
authorVictor Cebollada <v.cebollada@samsung.com>
Fri, 24 Mar 2017 11:51:58 +0000 (11:51 +0000)
committerVictor Cebollada <v.cebollada@samsung.com>
Fri, 24 Mar 2017 11:51:58 +0000 (11:51 +0000)
Change-Id: Icfaab1d451a7edd7f29812f5c6f72824c0454cd6

71 files changed:
automated-tests/CMakeLists.txt.in
automated-tests/resources/po/ar.po [new file with mode: 0755]
automated-tests/resources/po/en.po [new file with mode: 0755]
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit-internal/utc-Dali-DebugRendering.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-VisualFactoryResolveUrl.cpp [deleted file]
automated-tests/src/dali-toolkit-internal/utc-Dali-VisualUrl.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit-styling/utc-Dali-StyleManager.cpp
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-PushButton.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextSelectionPopupMirroringLTR.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-TextSelectionPopupMirroringRTL.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp
build/tizen/docs-internal/dali-internal.doxy.in
build/tizen/docs/dali.doxy.in
dali-toolkit/dali-toolkit.h
dali-toolkit/devel-api/controls/text-controls/text-selection-toolbar.cpp
dali-toolkit/devel-api/controls/text-controls/text-selection-toolbar.h
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.cpp [new file with mode: 0644]
dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h [new file with mode: 0644]
dali-toolkit/devel-api/visual-factory/visual-base.h
dali-toolkit/devel-api/visuals/image-visual-properties-devel.h [new file with mode: 0644]
dali-toolkit/devel-api/visuals/visual-properties-devel.h
dali-toolkit/internal/controls/buttons/button-impl.cpp
dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp
dali-toolkit/internal/controls/progress-bar/progress-bar-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp
dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.cpp
dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.h
dali-toolkit/internal/file.list
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp
dali-toolkit/internal/visuals/animated-image/animated-image-visual.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/npatch-loader.cpp
dali-toolkit/internal/visuals/npatch-loader.h
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.h
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.h
dali-toolkit/internal/visuals/visual-base-data-impl.cpp
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/internal/visuals/visual-factory-resolve-url.h [deleted file]
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h
dali-toolkit/internal/visuals/visual-url.cpp [new file with mode: 0644]
dali-toolkit/internal/visuals/visual-url.h [new file with mode: 0644]
dali-toolkit/po/ar.po
dali-toolkit/po/fa.po
dali-toolkit/po/ur.po
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
docs/content/shared-javascript-and-cpp-documentation/visuals.md
packaging/dali-toolkit.spec
plugins/dali-swig/SWIG/adaptor/window.i [new file with mode: 0755]
plugins/dali-swig/SWIG/dali-adaptor.i
plugins/dali-swig/SWIG/dali-toolkit.i
plugins/dali-swig/SWIG/dali.i
plugins/dali-swig/examples/hello-world.cs
plugins/dali-swig/examples/visuals-using-custom-view/ContactView.cs
plugins/dali-swig/manual/csharp/FocusManager.cs

index 0a0b958..377ec92 100644 (file)
@@ -11,3 +11,31 @@ INCLUDE_DIRECTORIES(
 )
 
 ADD_SUBDIRECTORY(src)
+
+#Internationalization
+SET(PO_DIR ${CMAKE_SOURCE_DIR}/resources/po)
+MESSAGE("po dir: ${PO_DIR}")
+FILE(GLOB PO_FILES RELATIVE "${PO_DIR}" "${PO_DIR}/*.po")
+
+SET(MSGFMT "/usr/bin/msgfmt")
+SET(MO_FILES_DIR /tmp/locale/en/LC_MESSAGES)
+FILE(MAKE_DIRECTORY ${MO_FILES_DIR})
+MESSAGE("mo dir: ${MO_FILES_DIR}")
+
+FOREACH(PO_FILE ${PO_FILES})
+        SET(PO_FILE ${PO_DIR}/${PO_FILE})
+        MESSAGE("PO: ${PO_FILE}")
+        GET_FILENAME_COMPONENT(ABS_PO_FILE ${PO_FILE} ABSOLUTE)
+        MESSAGE("ABS_PO_FILE : ${ABS_PO_FILE}")
+        GET_FILENAME_COMPONENT(lang ${ABS_PO_FILE} NAME_WE)
+        MESSAGE("lang : ${lang}")
+        SET(MO_FILE ${MO_FILES_DIR}/dali-toolkit.mo.${lang})
+        MESSAGE("MO_FILE : ${MO_FILE}")
+        ADD_CUSTOM_COMMAND(OUTPUT ${MO_FILE}
+                           COMMAND ${MSGFMT} -o ${MO_FILE} ${ABS_PO_FILE}
+                           DEPENDS ${ABS_PO_FILE})
+        SET(MO_FILES ${MO_FILES} ${MO_FILE})
+ENDFOREACH(PO_FILE)
+
+MESSAGE(".mo files: ${MO_FILES}")
+ADD_CUSTOM_TARGET(po ALL DEPENDS ${MO_FILES})
diff --git a/automated-tests/resources/po/ar.po b/automated-tests/resources/po/ar.po
new file mode 100755 (executable)
index 0000000..b91b3a7
--- /dev/null
@@ -0,0 +1,3 @@
+#: Used to know if the language is using a right to left script
+msgid "IDS_LTR"
+msgstr "RTL"
diff --git a/automated-tests/resources/po/en.po b/automated-tests/resources/po/en.po
new file mode 100755 (executable)
index 0000000..566fbbd
--- /dev/null
@@ -0,0 +1,3 @@
+#: Used to know if the language is using a right to left script
+msgid "IDS_LTR"
+msgstr "LTR"
index 023d4bc..6ec6207 100755 (executable)
@@ -17,7 +17,7 @@ SET(TC_SOURCES
  utc-Dali-VisualModel.cpp
  utc-Dali-Text-Layout.cpp
  utc-Dali-Text-Controller.cpp
- utc-Dali-VisualFactoryResolveUrl.cpp
+ utc-Dali-VisualUrl.cpp
  utc-Dali-Text-Markup.cpp
  utc-Dali-Text-Typesetter.cpp
  utc-Dali-Text-ViewModel.cpp
index 7348859..f853c90 100644 (file)
@@ -41,7 +41,7 @@ const char* TEST_GIF_FILE_NAME = TEST_RESOURCE_DIR "/anim.gif";
 
 const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
 
-void TestDebugVisual( Visual::Base& visual, Visual::Type actualType, Vector2 expectedNaturalSize )
+void TestDebugVisual( Visual::Base& visual, DevelVisual::Type actualType, Vector2 expectedNaturalSize )
 {
   DALI_TEST_CHECK( &typeid( Toolkit::Internal::WireframeVisual ) == &typeid( GetImplementation(visual) ) );
 
@@ -96,7 +96,7 @@ int UtcDaliDebugRenderingGetVisual1(void)
   propertyMap1.Insert(ColorVisual::Property::MIX_COLOR,  Color::BLUE);
   Visual::Base colorVisual = factory.CreateVisual(propertyMap1);
   DALI_TEST_CHECK( colorVisual );
-  TestDebugVisual( colorVisual, Visual::COLOR, Vector2::ZERO );
+  TestDebugVisual( colorVisual, DevelVisual::COLOR, Vector2::ZERO );
 
   // Test that border visual is replaced with debug visual
   Property::Map propertyMap2;
@@ -105,7 +105,7 @@ int UtcDaliDebugRenderingGetVisual1(void)
   propertyMap2.Insert(BorderVisual::Property::SIZE,  2.f);
   Visual::Base borderVisual = factory.CreateVisual(propertyMap2);
   DALI_TEST_CHECK( borderVisual );
-  TestDebugVisual( borderVisual, Visual::BORDER, Vector2::ZERO );
+  TestDebugVisual( borderVisual, DevelVisual::BORDER, Vector2::ZERO );
 
   // Test that gradient visual is replaced with debug visual
   Property::Map propertyMap3;
@@ -125,7 +125,7 @@ int UtcDaliDebugRenderingGetVisual1(void)
   propertyMap3.Insert(GradientVisual::Property::STOP_COLOR, stopColors);
   Visual::Base gradientVisual = factory.CreateVisual(propertyMap3);
   DALI_TEST_CHECK( gradientVisual );
-  TestDebugVisual( gradientVisual, Visual::GRADIENT, Vector2::ZERO );
+  TestDebugVisual( gradientVisual, DevelVisual::GRADIENT, Vector2::ZERO );
 
   // Test that image visual is replaced with debug visual
   Property::Map propertyMap4;
@@ -135,7 +135,7 @@ int UtcDaliDebugRenderingGetVisual1(void)
   propertyMap4.Insert( ImageVisual::Property::DESIRED_HEIGHT,  100.f );
   Visual::Base imageVisual = factory.CreateVisual( propertyMap4 );
   DALI_TEST_CHECK( imageVisual );
-  TestDebugVisual( imageVisual, Visual::IMAGE, Vector2( 50.f, 100.f ) );
+  TestDebugVisual( imageVisual, DevelVisual::IMAGE, Vector2( 50.f, 100.f ) );
 
   // Test that SVG visual is replaced with debug visual
   // TEST_SVG_FILE:
@@ -143,21 +143,21 @@ int UtcDaliDebugRenderingGetVisual1(void)
   //  <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
   //  </svg>
   Property::Map propertyMap5;
-  propertyMap5.Insert( Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMap5.Insert( Visual::Property::TYPE, DevelVisual::SVG );
   propertyMap5.Insert( ImageVisual::Property::URL,  TEST_SVG_FILE_NAME );
   Visual::Base svgVisual = factory.CreateVisual( propertyMap5 );
   DALI_TEST_CHECK( svgVisual );
-  TestDebugVisual( svgVisual, Visual::IMAGE, Vector2(100.f, 100.f) );
+  TestDebugVisual( svgVisual, DevelVisual::SVG, Vector2(100.f, 100.f) );
 
   // Test that AnimatedImageVisual is replaced with debug visual
   // TEST_GIF_FILE: anim.gif
   // resolution: 50*50, frame count: 4, frame delay: 0.2 second for each frame
   Property::Map propertyMap6;
-  propertyMap6.Insert( Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMap6.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_IMAGE );
   propertyMap6.Insert( ImageVisual::Property::URL,  TEST_GIF_FILE_NAME );
   Visual::Base animatedImageVisual = factory.CreateVisual( propertyMap6 );
   DALI_TEST_CHECK( animatedImageVisual );
-  TestDebugVisual( animatedImageVisual, Visual::IMAGE, Vector2(50.f, 50.f) );
+  TestDebugVisual( animatedImageVisual, DevelVisual::ANIMATED_IMAGE, Vector2(50.f, 50.f) );
 
   // Test that text visual is replaced with debug visual
 
@@ -188,6 +188,15 @@ int UtcDaliDebugRenderingGetVisual1(void)
   const float height = textVisual.GetHeightForWidth( 40.f );
   DALI_TEST_EQUALS( height, 40.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
+  // Test that NPatchVisual is replaced with debug visual
+  // TEST_NPATCH_FILE_NAME: image_01.9.jpg
+  Property::Map propertyMap8;
+  propertyMap8.Insert( Visual::Property::TYPE, DevelVisual::N_PATCH );
+  propertyMap8.Insert( ImageVisual::Property::URL,  TEST_NPATCH_FILE_NAME );
+  Visual::Base nPatchVisual = factory.CreateVisual( propertyMap8 );
+  DALI_TEST_CHECK( nPatchVisual );
+  TestDebugVisual( nPatchVisual, DevelVisual::N_PATCH, Vector2::ZERO );
+
   EnvironmentVariable::SetTestingEnvironmentVariable(false);
   END_TEST;
 }
@@ -208,7 +217,7 @@ int UtcDaliDebugRenderingGetVisual2(void)
 
   Visual::Base colorVisual = factory.CreateVisual( map);
   DALI_TEST_CHECK( colorVisual );
-  TestDebugVisual( colorVisual, Visual::COLOR, Vector2::ZERO );
+  TestDebugVisual( colorVisual, DevelVisual::COLOR, Vector2::ZERO );
 
   // Test that border visual is replaced with debug visual
   map.Clear();
@@ -217,18 +226,18 @@ int UtcDaliDebugRenderingGetVisual2(void)
   map[ BorderVisual::Property::SIZE   ] = 2.f;
   Visual::Base borderVisual = factory.CreateVisual( map );
   DALI_TEST_CHECK( borderVisual );
-  TestDebugVisual( borderVisual, Visual::BORDER, Vector2::ZERO );
+  TestDebugVisual( borderVisual, DevelVisual::BORDER, Vector2::ZERO );
 
   // Test that image visual is replaced with debug visual
   Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME);
   Visual::Base imageVisual = factory.CreateVisual( image );
   DALI_TEST_CHECK( imageVisual );
-  TestDebugVisual( imageVisual, Visual::IMAGE, Vector2::ZERO);
+  TestDebugVisual( imageVisual, DevelVisual::IMAGE, Vector2::ZERO);
 
   // Test that n patch visual is replaced with debug visual
   Visual::Base nPatchVisual = factory.CreateVisual( TEST_NPATCH_FILE_NAME, ImageDimensions() );
   DALI_TEST_CHECK( nPatchVisual );
-  TestDebugVisual( nPatchVisual, Visual::IMAGE, Vector2::ZERO );
+  TestDebugVisual( nPatchVisual, DevelVisual::N_PATCH, Vector2::ZERO );
 
   EnvironmentVariable::SetTestingEnvironmentVariable(false);
   END_TEST;
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-VisualFactoryResolveUrl.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-VisualFactoryResolveUrl.cpp
deleted file mode 100644 (file)
index 8235355..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-
-#include <stdlib.h>
-
-#include <dali-toolkit-test-suite-utils.h>
-#include <dali-toolkit/internal/visuals/visual-factory-resolve-url.h>
-
-using namespace Dali::Toolkit::Internal;
-
-int UtcDaliResolveUrlRegularImage(void)
-{
-  tet_infoline( "UtcDaliResolveUrl REGULAR_IMAGE" );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("foobar.jpeg"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("foobar.PNG"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("foobar.Png123"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("foobar.Png1.23"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType(""), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType(" "), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("."), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("9"), TEST_LOCATION );
-
-  END_TEST;
-}
-
-int UtcDaliResolveUrlSvg(void)
-{
-  tet_infoline( "UtcDaliResolveUrl SVG" );
-
-  DALI_TEST_EQUALS( UrlType::SVG, ResolveUrlType("foobar.svg"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::SVG, ResolveUrlType("foobar.svg.svg"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::SVG, ResolveUrlType("foobar.svG"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::SVG, ResolveUrlType("foobar.SVG"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::SVG, ResolveUrlType(".SvG"), TEST_LOCATION );
-
-  // SVGs aren't N-patch
-  DALI_TEST_EQUALS( UrlType::SVG, ResolveUrlType("foobar.9.svg"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("svg.png"), TEST_LOCATION );
-
-  // maybe controversial, but for now we expect the suffix to be exactly .svg
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("svg.svg1"), TEST_LOCATION );
-
-  END_TEST;
-}
-
-int UtcDaliResolveUrlNPatch(void)
-{
-  tet_infoline( "UtcDaliResolveUrl N_PATCH" );
-
-  DALI_TEST_EQUALS( UrlType::N_PATCH, ResolveUrlType("foobar.#.png"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::N_PATCH, ResolveUrlType("foobar.9.9.bmp"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::N_PATCH, ResolveUrlType("foobar.9.9.jpg[]=$$"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::N_PATCH, ResolveUrlType("foobar.9.#.#.9.wbpm123"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("svg.##.png"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("svg.99.jpeg"), TEST_LOCATION );
-
-  END_TEST;
-}
-
-int UtcDaliResolveUrlGif(void)
-{
-  tet_infoline( "UtcDaliResolveUrl GIF" );
-
-  DALI_TEST_EQUALS( UrlType::GIF, ResolveUrlType("foobar.gif"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::GIF, ResolveUrlType("foobar.gif.gif"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::GIF, ResolveUrlType("foobar.giF"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::GIF, ResolveUrlType("foobar.GIF"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::GIF, ResolveUrlType(".GiF"), TEST_LOCATION );
-
-  // GIFs aren't N-patch
-  DALI_TEST_EQUALS( UrlType::GIF, ResolveUrlType("foobar.9.gif"), TEST_LOCATION );
-
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("gif.png"), TEST_LOCATION );
-  DALI_TEST_EQUALS( UrlType::REGULAR_IMAGE, ResolveUrlType("gif.gif1"), TEST_LOCATION );
-
-  END_TEST;
-}
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-VisualUrl.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-VisualUrl.cpp
new file mode 100644 (file)
index 0000000..476a023
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+
+#include <stdlib.h>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
+
+using namespace Dali::Toolkit::Internal;
+
+int UtcDaliVisualUrlConstructor(void)
+{
+  const char* url="http://bar.org/foobar.gif";
+  VisualUrl visualUrl(url);
+  DALI_TEST_EQUALS( true, visualUrl.IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl.GetType(), VisualUrl::GIF, TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl.GetLocation(), VisualUrl::REMOTE, TEST_LOCATION );
+
+  VisualUrl visualUrl2("foobar.jpeg");
+  visualUrl2 = visualUrl;
+  DALI_TEST_EQUALS( true, visualUrl2.IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl2.GetType(), VisualUrl::GIF, TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl2.GetLocation(), VisualUrl::REMOTE, TEST_LOCATION );
+
+  VisualUrl visualUrl3( visualUrl );
+  DALI_TEST_EQUALS( true, visualUrl3.IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl3.GetType(), VisualUrl::GIF, TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl3.GetLocation(), VisualUrl::REMOTE, TEST_LOCATION );
+  END_TEST;
+}
+
+
+int UtcDaliVisualUrlRegularImage(void)
+{
+  tet_infoline( "UtcDaliVisualUrl REGULAR_IMAGE" );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("foobar.jpeg").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("foobar.PNG").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("foobar.Png123").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("foobar.Png1.23").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl(" ").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl(".").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("9").GetType(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliVisualUrlSvg(void)
+{
+  tet_infoline( "UtcDaliVisualUrl SVG" );
+
+  DALI_TEST_EQUALS( VisualUrl::SVG, VisualUrl("foobar.svg").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::SVG, VisualUrl("foobar.svg.svg").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::SVG, VisualUrl("foobar.svG").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::SVG, VisualUrl("foobar.SVG").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::SVG, VisualUrl(".SvG").GetType(), TEST_LOCATION );
+
+  // SVGs aren't N-patch
+  DALI_TEST_EQUALS( VisualUrl::SVG, VisualUrl("foobar.9.svg").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("svg.png").GetType(), TEST_LOCATION );
+
+  // maybe controversial, but for now we expect the suffix to be exactly .svg
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("svg.svg1").GetType(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliVisualUrlNPatch(void)
+{
+  tet_infoline( "UtcDaliVisualUrl N_PATCH" );
+
+  DALI_TEST_EQUALS( VisualUrl::N_PATCH, VisualUrl("foobar.#.png").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::N_PATCH, VisualUrl("foobar.9.9.bmp").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::N_PATCH, VisualUrl("foobar.9.9.jpg[]=$$").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::N_PATCH, VisualUrl("foobar.9.#.#.9.wbpm123").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("svg.##.png").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("svg.99.jpeg").GetType(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliVisualUrlGif(void)
+{
+  tet_infoline( "UtcDaliVisualUrl GIF" );
+
+  DALI_TEST_EQUALS( VisualUrl::GIF, VisualUrl("foobar.gif").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::GIF, VisualUrl("foobar.gif.gif").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::GIF, VisualUrl("foobar.giF").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::GIF, VisualUrl("foobar.GIF").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::GIF, VisualUrl(".GiF").GetType(), TEST_LOCATION );
+
+  // GIFs aren't N-patch
+  DALI_TEST_EQUALS( VisualUrl::GIF, VisualUrl("foobar.9.gif").GetType(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("gif.png").GetType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REGULAR_IMAGE, VisualUrl("gif.gif1").GetType(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliVisualUrlLocationP(void)
+{
+  tet_infoline( "UtcDaliVisualUrl Location" );
+
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("foobar.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("foobar.svg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("foobar.GIF").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("foobar.9.png").GetLocation(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("file://bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("file://bar.org/foobar.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("file://bar.org/foobar.svg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("file://bar.org/foobar.jpeg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("file://bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("ftp://bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("ftp://bar.org/foobar.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("ftp://bar.org/foobar.svg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("ftp://bar.org/foobar.GIF").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("ftp://bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("ssh://bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("ssh://bar.org/foobar.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("ssh://bar.org/foobar.svg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("ssh://bar.org/foobar.GIF").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("ssh://bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("http://bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("http://bar.org/foobar.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("http://bar.org/foobar.svg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("http://bar.org/foobar.GIF").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("http://bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("https://bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("https://bar.org/foobar.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("https://bar.org/foobar.svg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("https://bar.org/foobar.GIF").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("https://bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("FTP://bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("FTP://bar.org/foobar.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("FTP://bar.org/foobar.svg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("FTP://bar.org/foobar.GIF").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("FTP://BAR.ORG/foobar.9.png").GetLocation(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("SSH://bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("SSH://bar.org/foobar.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("SSH://bar.org/foobar.svg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("SSH://bar.org/foobar.GIF").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("SSH://BAR.ORG/foobar.9.png").GetLocation(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("HTTP://bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("HTTP://bar.org/foobar.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("HTTP://bar.org/foobar.svg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("HTTP://bar.org/foobar.GIF").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("HTTP://bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("HTTPS://bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("HTTPS://bar.org/foobar.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("HTTPS://bar.org/foobar.svg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("HTTPS://bar.org/foobar.GIF").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::REMOTE, VisualUrl("HTTPS://bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliVisualUrlLocationN(void)
+{
+  tet_infoline( "UtcDaliVisualUrl Location negative tests" );
+
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("htp://bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("htpp://bar.org/foobar.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("sshttp://bar.org/foobar.svg").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("htth://bar.org/foobar.GIF").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("http:https://bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("https:http://bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("HPPT://bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("ftp:/bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("ssh;//bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("ssh:/bar.org/foobar.9.png").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("http:/bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("https:/bar.org/foobar.gif").GetLocation(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("file://bar.org/foobar.png").GetLocation(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliVisualUrlIsLocal(void)
+{
+  tet_infoline( "UtcDaliVisualUrl IsLocal" );
+
+  DALI_TEST_EQUALS( true, VisualUrl("foobar.gif").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("foobar.png").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("foobar.svg").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("foobar.GIF").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("foobar.9.png").IsLocal(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( false, VisualUrl("http://bar.org/foobar.gif").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("http://bar.org/foobar.png").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("http://bar.org/foobar.svg").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("http://bar.org/foobar.GIF").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("http://bar.org/foobar.9.png").IsLocal(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( false, VisualUrl("https://bar.org/foobar.gif").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("https://bar.org/foobar.png").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("https://bar.org/foobar.svg").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("https://bar.org/foobar.GIF").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("https://bar.org/foobar.9.png").IsLocal(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( false, VisualUrl("HTTP://bar.org/foobar.gif").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("HTTP://bar.org/foobar.png").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("HTTP://bar.org/foobar.svg").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("HTTP://bar.org/foobar.GIF").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("HTTP://bar.org/foobar.9.png").IsLocal(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( false, VisualUrl("HTTPS://bar.org/foobar.gif").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("HTTPS://bar.org/foobar.png").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("HTTPS://bar.org/foobar.svg").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("HTTPS://bar.org/foobar.GIF").IsLocal(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("HTTPS://bar.org/foobar.9.png").IsLocal(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliVisualUrlIsValid(void)
+{
+  tet_infoline( "UtcDaliVisualUrl IsValid" );
+
+  DALI_TEST_EQUALS( false, VisualUrl().IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( false, VisualUrl("").IsValid(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( true, VisualUrl("foobar.gif").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("foobar.png").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("foobar.svg").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("foobar.GIF").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("foobar.9.png").IsValid(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( true, VisualUrl("http://bar.org/foobar.gif").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("http://bar.org/foobar.png").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("http://bar.org/foobar.svg").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("http://bar.org/foobar.GIF").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("http://bar.org/foobar.9.png").IsValid(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( true, VisualUrl("https://bar.org/foobar.gif").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("https://bar.org/foobar.png").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("https://bar.org/foobar.svg").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("https://bar.org/foobar.GIF").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("https://bar.org/foobar.9.png").IsValid(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( true, VisualUrl("HTTP://bar.org/foobar.gif").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("HTTP://bar.org/foobar.png").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("HTTP://bar.org/foobar.svg").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("HTTP://bar.org/foobar.GIF").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("HTTP://bar.org/foobar.9.png").IsValid(), TEST_LOCATION );
+
+  DALI_TEST_EQUALS( true, VisualUrl("HTTPS://bar.org/foobar.gif").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("HTTPS://bar.org/foobar.png").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("HTTPS://bar.org/foobar.svg").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("HTTPS://bar.org/foobar.GIF").IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, VisualUrl("HTTPS://bar.org/foobar.9.png").IsValid(), TEST_LOCATION );
+
+  END_TEST;
+}
index 6a81e06..20de8e8 100644 (file)
@@ -1,5 +1,5 @@
  /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
 #include <dummy-control.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
 
@@ -641,8 +642,11 @@ int UtcDaliStyleManagerStyleChangedSignalFontFamily(void)
   Toolkit::TextLabel label = Toolkit::TextLabel::New(labelStr);
   Stage::GetCurrent().Add( label );
 
-  Toolkit::TextLabel label2 = Toolkit::TextLabel::New(labelStr);
-  Stage::GetCurrent().Add( label2 );
+  Toolkit::TextField field = Toolkit::TextField::New();
+  Stage::GetCurrent().Add( field );
+
+  Toolkit::TextEditor editor = Toolkit::TextEditor::New();
+  Stage::GetCurrent().Add( editor );
 
   StyleChangedSignalChecker styleChangedSignalHandler;
   Dali::StyleMonitor styleMonitor = Dali::StyleMonitor::Get();
@@ -665,6 +669,18 @@ int UtcDaliStyleManagerStyleChangedSignalFontFamily(void)
 
   DALI_TEST_EQUALS( familyStr, "Times New Roman", TEST_LOCATION);
 
+  // Check that the field's font style has been altered
+  family = field.GetProperty(TextField::Property::FONT_FAMILY);
+  family.Get( familyStr );
+
+  DALI_TEST_EQUALS( familyStr, "Times New Roman", TEST_LOCATION);
+
+  // Check that the editor's font style has been altered
+  family = editor.GetProperty(TextEditor::Property::FONT_FAMILY);
+  family.Get( familyStr );
+
+  DALI_TEST_EQUALS( familyStr, "Times New Roman", TEST_LOCATION);
+
   END_TEST;
 }
 
@@ -1249,13 +1265,13 @@ int UtcDaliStyleManagerSetSubState02(void)
   tet_infoline( "Changing state to FOCUSED - check visual changes\n");
 
   Visual::Base fgVisual1 = CheckVisual( dummyImpl, DummyControl::Property::FOREGROUND_VISUAL, Toolkit::Visual::GRADIENT, TEST_LOCATION);
-  Visual::Base focusVisual1 = CheckVisual( dummyImpl, DummyControl::Property::FOCUS_VISUAL, Toolkit::Visual::IMAGE, TEST_LOCATION);
+  Visual::Base focusVisual1 = CheckVisual( dummyImpl, DummyControl::Property::FOCUS_VISUAL, Toolkit::DevelVisual::N_PATCH, TEST_LOCATION);
 
   actor.SetProperty(DevelControl::Property::SUB_STATE, "SELECTED");
   tet_infoline( "Changing  substate to SELECTED - Expect no change\n");
 
   Visual::Base fgVisual2 = CheckVisual( dummyImpl, DummyControl::Property::FOREGROUND_VISUAL, Toolkit::Visual::GRADIENT, TEST_LOCATION);
-  Visual::Base focusVisual2 = CheckVisual( dummyImpl, DummyControl::Property::FOCUS_VISUAL, Toolkit::Visual::IMAGE, TEST_LOCATION);
+  Visual::Base focusVisual2 = CheckVisual( dummyImpl, DummyControl::Property::FOCUS_VISUAL, Toolkit::DevelVisual::N_PATCH, TEST_LOCATION);
 
   DALI_TEST_CHECK( fgVisual1 == fgVisual2 );
   DALI_TEST_CHECK( focusVisual1 == focusVisual2 );
index 97975d1..c7a1b8b 100755 (executable)
@@ -32,6 +32,8 @@ SET(TC_SOURCES
    utc-Dali-TextField.cpp
    utc-Dali-TextLabel.cpp
    utc-Dali-TextSelectionPopup.cpp
+   utc-Dali-TextSelectionPopupMirroringLTR.cpp
+   utc-Dali-TextSelectionPopupMirroringRTL.cpp
    utc-Dali-ToolBar.cpp
    utc-Dali-Tooltip.cpp
    utc-Dali-TransitionData.cpp
index d32b7ff..1788df2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
 
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali/integration-api/events/key-event-integ.h>
+#include <dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 
 using namespace Dali;
@@ -43,6 +44,45 @@ void utc_dali_toolkit_keyboard_focus_manager_cleanup(void)
 namespace
 {
 
+// Functors to test whether GetNextFocusableActor() method of CustomAlgorithmInterface is called when the keyboard focus is about to change
+class CustomAlgorithm : public Dali::Toolkit::DevelKeyboardFocusManager::CustomAlgorithmInterface
+{
+public:
+  CustomAlgorithm(bool& interfaceVerified)
+  : mInterfaceVerified(interfaceVerified),
+    mCurrentFocusedActor(),
+    mProposedActorToFocus(),
+    mDirection(Control::KeyboardFocus::LEFT)
+  {
+  }
+
+  Actor GetNextFocusableActor(Actor currentFocusedActor, Actor proposedActorToFocus, Control::KeyboardFocus::Direction direction)
+  {
+    tet_infoline("Verifying CustomAlgorithm()");
+
+    mInterfaceVerified = true;
+
+    mCurrentFocusedActor = currentFocusedActor;
+    mProposedActorToFocus = proposedActorToFocus;
+    mDirection = direction;
+
+    return mProposedActorToFocus;
+  }
+
+  void Reset()
+  {
+    mInterfaceVerified = false;
+    mCurrentFocusedActor = Actor();
+    mProposedActorToFocus = Actor();
+    mDirection = Control::KeyboardFocus::LEFT;
+  }
+
+  bool& mInterfaceVerified;
+  Actor mCurrentFocusedActor;
+  Actor mProposedActorToFocus;
+  Control::KeyboardFocus::Direction mDirection;
+};
+
 // Functors to test whether PreFocusChange signal is emitted when the keyboard focus is about to change
 class PreFocusChangeCallback : public Dali::ConnectionTracker
 {
@@ -434,6 +474,222 @@ int UtcDaliKeyboardFocusManagerMoveFocus(void)
   END_TEST;
 }
 
+int UtcDaliKeyboardFocusManagerCustomAlgorithmMoveFocus(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline(" UtcDaliKeyboardFocusManagerCustomAlgorithmMoveFocus");
+
+  // Register Type
+  TypeInfo type;
+  type = TypeRegistry::Get().GetTypeInfo( "KeyboardFocusManager" );
+  DALI_TEST_CHECK( type );
+  BaseHandle handle = type.CreateInstance();
+  DALI_TEST_CHECK( handle );
+
+  KeyboardFocusManager manager = KeyboardFocusManager::Get();
+  DALI_TEST_CHECK(manager);
+
+  bool preFocusChangeSignalVerified = false;
+  PreFocusChangeCallback preFocusChangeCallback(preFocusChangeSignalVerified);
+  manager.PreFocusChangeSignal().Connect( &preFocusChangeCallback, &PreFocusChangeCallback::Callback );
+
+  bool focusChangedSignalVerified = false;
+  FocusChangedCallback focusChangedCallback(focusChangedSignalVerified);
+  manager.FocusChangedSignal().Connect( &focusChangedCallback, &FocusChangedCallback::Callback );
+
+  // Create the first actor and add it to the stage
+  Actor first = Actor::New();
+  first.SetKeyboardFocusable(true);
+  Stage::GetCurrent().Add(first);
+
+  // Create the second actor and add it to the stage
+  Actor second = Actor::New();
+  second.SetKeyboardFocusable(true);
+  Stage::GetCurrent().Add(second);
+
+  // Move the focus to the right
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == false);
+
+  // Because no layout control in the stage and no actor is focused, it should emit the PreFocusChange signal
+  DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
+  DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == Actor());
+  DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
+  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::KeyboardFocus::RIGHT);
+  preFocusChangeCallback.Reset();
+
+  bool customAlgorithmInterfaceVerified = false;
+  CustomAlgorithm customAlgorithm(customAlgorithmInterfaceVerified);
+  Toolkit::DevelKeyboardFocusManager::SetCustomAlgorithm(manager, customAlgorithm);
+
+  // Move the focus towards right
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == false);
+
+  // Because no layout control in the stage and the first actor is focused, it should invoke CustomAlgorithm
+  DALI_TEST_CHECK(customAlgorithm.mInterfaceVerified);
+  DALI_TEST_CHECK(customAlgorithm.mCurrentFocusedActor == Actor());
+  DALI_TEST_CHECK(customAlgorithm.mProposedActorToFocus == Actor());
+  DALI_TEST_CHECK(customAlgorithm.mDirection == Control::KeyboardFocus::RIGHT);
+  customAlgorithm.Reset();
+
+  // Check that the focus is set on the first actor
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == Actor());
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == first);
+  focusChangedCallback.Reset();
+
+  // Move the focus towards right
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == false);
+
+  // Because no layout control in the stage and the first actor is focused, it should invoke CustomAlgorithm
+  DALI_TEST_CHECK(customAlgorithm.mInterfaceVerified);
+  DALI_TEST_CHECK(customAlgorithm.mCurrentFocusedActor == first);
+  DALI_TEST_CHECK(customAlgorithm.mProposedActorToFocus == Actor());
+  DALI_TEST_CHECK(customAlgorithm.mDirection == Control::KeyboardFocus::RIGHT);
+  customAlgorithm.Reset();
+
+  // Check that the focus is set on the second actor
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == first);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == second);
+  focusChangedCallback.Reset();
+
+  // Move the focus towards up
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::UP) == false);
+
+  // Because no layout control in the stage and no actor is focused, it should invoke CustomAlgorithm
+  DALI_TEST_CHECK(customAlgorithm.mInterfaceVerified);
+  DALI_TEST_CHECK(customAlgorithm.mCurrentFocusedActor == second);
+  DALI_TEST_CHECK(customAlgorithm.mProposedActorToFocus == Actor());
+  DALI_TEST_CHECK(customAlgorithm.mDirection == Control::KeyboardFocus::UP);
+  customAlgorithm.Reset();
+  DALI_TEST_CHECK(!focusChangedCallback.mSignalVerified);
+
+  END_TEST;
+}
+int UtcDaliKeyboardFocusManagerFocusablePropertiesMoveFocus(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline(" UtcDaliKeyboardFocusManagerCustomAlgorithmMoveFocus");
+
+  // Register Type
+  TypeInfo type;
+  type = TypeRegistry::Get().GetTypeInfo( "KeyboardFocusManager" );
+  DALI_TEST_CHECK( type );
+  BaseHandle handle = type.CreateInstance();
+  DALI_TEST_CHECK( handle );
+
+  KeyboardFocusManager manager = KeyboardFocusManager::Get();
+  DALI_TEST_CHECK(manager);
+
+  bool focusChangedSignalVerified = false;
+  FocusChangedCallback focusChangedCallback(focusChangedSignalVerified);
+  manager.FocusChangedSignal().Connect( &focusChangedCallback, &FocusChangedCallback::Callback );
+
+  PushButton button1 = PushButton::New();
+  PushButton button2 = PushButton::New();
+  button1.SetKeyboardFocusable(true);
+  button2.SetKeyboardFocusable(true);
+  Stage::GetCurrent().Add(button1);
+  Stage::GetCurrent().Add(button2);
+
+  // Set the focus to the button1
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(button1) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == button1);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == Actor());
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1);
+  focusChangedCallback.Reset();
+
+  // set the navigation properties of button1
+  button1.SetProperty(Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID, Property::Value((int)button2.GetId()));
+  button1.SetProperty(Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID, Property::Value((int)button2.GetId()));
+  button1.SetProperty(Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID, Property::Value((int)button2.GetId()));
+  button1.SetProperty(Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::Value((int)button2.GetId()));
+
+  // set the navigation properties of button2
+  button2.SetProperty(Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID, Property::Value((int)button1.GetId()));
+  button2.SetProperty(Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID, Property::Value((int)button1.GetId()));
+  button2.SetProperty(Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID, Property::Value((int)button1.GetId()));
+  button2.SetProperty(Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::Value((int)button1.GetId()));
+
+  // Move the focus towards left
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == true);
+
+  // Confirm whether focus is moved to button2
+  DALI_TEST_EQUALS(button2.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button1);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button2);
+  focusChangedCallback.Reset();
+
+  // Move the focus towards right
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == true);
+
+  // Confirm whether focus is moved to button1
+  DALI_TEST_EQUALS(button1.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button2);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1);
+  focusChangedCallback.Reset();
+
+  // Move the focus towards up
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::UP) == true);
+
+  // Confirm whether focus is moved to button2
+  DALI_TEST_EQUALS(button2.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button1);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button2);
+  focusChangedCallback.Reset();
+
+  // Move the focus towards down
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::DOWN) == true);
+
+  // Confirm whether focus is moved to button1
+  DALI_TEST_EQUALS(button1.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button2);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1);
+  focusChangedCallback.Reset();
+
+  // Create a 1x1 table view and try to move focus inside it
+  TableView tableView = TableView::New( 1, 1 );
+  Stage::GetCurrent().Add(tableView);
+
+  PushButton button = PushButton::New();
+  button.SetKeyboardFocusable(true);
+  tableView.AddChild(button, TableView::CellPosition(0, 0));
+
+  // set the navigation properties of button3
+  button.SetProperty(Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID, Property::Value((int)button1.GetId()));
+
+  // Set the focus to the button
+  DALI_TEST_CHECK(manager.SetCurrentFocusActor(button) == true);
+  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == button);
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button1);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button);
+  focusChangedCallback.Reset();
+
+  // Move the focus towards left
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == true);
+
+  // Confirm whether focus is moved to button1
+  DALI_TEST_EQUALS(button1.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+  DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+  DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button);
+  DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1);
+  focusChangedCallback.Reset();
+
+  END_TEST;
+}
+
 int UtcDaliKeyboardFocusManagerClearFocus(void)
 {
   ToolkitTestApplication application;
index 421083f..ad65aea 100644 (file)
@@ -30,6 +30,8 @@
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
 
+#include <dali/devel-api/adaptor-framework/image-loading.h>
+
 using namespace Dali;
 using namespace Toolkit;
 
@@ -741,8 +743,11 @@ int UtcDaliPushButtonPaddingLayout(void)
   PushButton pushButton = PushButton::New();
 
   const Vector4 TEST_ICON_PADDING( 20.0f, 20.0f, 20.0f, 20.0f );
-  const Vector4 TEST_LABEL_PADDING( 10.0f, 10.0f, 10.0f ,10.0f );
-  const Vector2 TEST_IMAGE_SIZE = Vector2( 5.0f, 5.0f);
+  const Vector4 TEST_LABEL_PADDING( 10.0f, 10.0f, 10.0f, 10.0f );
+
+  // Get actual size of test image
+  ImageDimensions testImageSize = Dali::GetClosestImageSize( TEST_IMAGE_ONE );
+  const Vector2 TEST_IMAGE_SIZE( testImageSize.GetWidth(), testImageSize.GetHeight() );
 
   pushButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
   pushButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
@@ -800,8 +805,6 @@ int UtcDaliPushButtonPaddingLayout(void)
 
   Stage::GetCurrent().Add( pushButton );
 
-  TestPlatformAbstraction& platform = application.GetPlatform();
-  platform.SetClosestImageSize( TEST_IMAGE_SIZE );
 
   pushButton.SetProperty( Toolkit::PushButton::Property::ICON_ALIGNMENT, "RIGHT" );
   pushButton.SetProperty( Toolkit::PushButton::Property::UNSELECTED_ICON, TEST_IMAGE_ONE );
@@ -824,7 +827,7 @@ int UtcDaliPushButtonPaddingLayout(void)
   size.width = pushButton.GetRelayoutSize( Dimension::WIDTH );
   size.height = pushButton.GetRelayoutSize( Dimension::HEIGHT );
   tet_printf( "Button RelayoutSize after icon padding(%f,%f)\n", size.width, size.height );
-  const Vector2 expectedIconAndPaddingSize( TEST_ICON_PADDING.x+TEST_ICON_PADDING.y+TEST_IMAGE_SIZE.width, TEST_ICON_PADDING.w+TEST_ICON_PADDING.z +TEST_IMAGE_SIZE.height );
+  const Vector2 expectedIconAndPaddingSize( TEST_ICON_PADDING.x+TEST_ICON_PADDING.y+TEST_IMAGE_SIZE.width, TEST_ICON_PADDING.w + TEST_ICON_PADDING.z + TEST_IMAGE_SIZE.height );
   DALI_TEST_EQUALS( size, expectedIconAndPaddingSize, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
   // Now test padding for both label and icon simultaneously.
@@ -847,7 +850,8 @@ int UtcDaliPushButtonPaddingLayout(void)
   tet_printf( "Button RelayoutSize after icon and label padding(%f,%f)\n", size.width, size.height );
 
   DALI_TEST_EQUALS( size.width, sizeLabelAndPadding.width + expectedIconAndPaddingSize.width, TEST_LOCATION );
-  DALI_TEST_GREATER( size.height, expectedIconAndPaddingSize.width, TEST_LOCATION ); // Test height of control is greater than icon and padding. As Text set to larger values.
+  // Test height of control is same as icon and padding, as Text is smaller than icon
+  DALI_TEST_EQUALS( size.height, expectedIconAndPaddingSize.height, TEST_LOCATION );
 
   END_TEST;
 }
@@ -885,7 +889,10 @@ int UtcDaliPushButtonAlignmentLayout(void)
 
   const Vector4 TEST_ICON_PADDING( 70.0f, 70.0f, 70.0f, 70.0f );
   const Vector4 TEST_LABEL_PADDING( 30.0f, 30.0f, 30.0f, 30.0f );
-  const Vector2 TEST_IMAGE_SIZE = Vector2( 10.0f, 10.0f);
+
+  // Get actual size of test image
+  ImageDimensions testImageSize = Dali::GetClosestImageSize( TEST_IMAGE_ONE );
+  const Vector2 TEST_IMAGE_SIZE( testImageSize.GetWidth(), testImageSize.GetHeight() );
 
   PushButton pushButton = PushButton::New();
 
@@ -925,9 +932,6 @@ int UtcDaliPushButtonAlignmentLayout(void)
   const Vector2 testImageWithPaddingSize = Vector2 ( ( TEST_IMAGE_SIZE.width + TEST_ICON_PADDING.x + TEST_ICON_PADDING.y ),
                                                      ( TEST_IMAGE_SIZE.height + TEST_ICON_PADDING.w + TEST_ICON_PADDING.z ) );
 
-  TestPlatformAbstraction& platform = application.GetPlatform();
-  platform.SetClosestImageSize( TEST_IMAGE_SIZE );
-
   // Add Icon and set its alignment
   pushButton.SetProperty( Toolkit::PushButton::Property::ICON_ALIGNMENT, "RIGHT" );
   pushButton.SetProperty( Toolkit::PushButton::Property::UNSELECTED_ICON, TEST_IMAGE_ONE );
index e4926c6..5f53c6f 100644 (file)
@@ -2072,3 +2072,163 @@ int utcDaliTextFieldStyleWhilstSelected(void)
 
   END_TEST;
 }
+
+int utcDaliTextFieldEscKeyLoseFocus(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextFieldEscKeyLoseFocus");
+
+  // Creates a tap event. After creating a tap event the text field should
+  // have the focus and add text with key events should be possible.
+
+  TextField field = TextField::New();
+  DALI_TEST_CHECK( field );
+
+  Stage::GetCurrent().Add( field );
+
+  field.SetSize( 300.f, 50.f );
+  field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  field.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Add a key event but as the text field has not the focus it should do nothing.
+  application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Up ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), std::string(""), TEST_LOCATION );
+
+  // Create a tap event to touch the text field.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Now the text field has the focus, so it can handle the key events.
+  application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Up ) );
+  application.ProcessEvent( GenerateKey( "d", "d", KEY_D_CODE, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "d", "d", KEY_D_CODE, 0, 0, Integration::KeyEvent::Up ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), std::string("ad"), TEST_LOCATION );
+
+  // Generate a Esc key event. The text field should lose the focus.
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_ESCAPE, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_ESCAPE, 0, 0, Integration::KeyEvent::Up ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( false, field.HasKeyInputFocus(), TEST_LOCATION );
+
+  // No more text should be introduced
+  application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "a", "a", KEY_A_CODE, 0, 0, Integration::KeyEvent::Up ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), std::string("ad"), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int utcDaliTextFieldSomeSpecialKeys(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextFieldSomeSpecialKeys");
+
+  // Checks some special keys when the text is selected.
+
+  TextField field = TextField::New();
+  DALI_TEST_CHECK( field );
+  Stage::GetCurrent().Add( field );
+  LoadMarkerImages(application, field);
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  const std::string longText( "This is a long text for the size of the text-field." );
+
+  field.SetProperty( TextField::Property::TEXT, longText );
+  field.SetProperty( TextField::Property::POINT_SIZE, 10.f );
+  field.SetSize( 300.f, 50.f );
+  field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  field.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Create a tap event to touch the text field.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Tap first to get the focus.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 1.f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 1.f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Double tap to select a word.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 2u, 1u, Vector2( 1.f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 2u, 1u, Vector2( 1.f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Generate a Esc key event. The text field should lose the focus.
+  application.ProcessEvent( GenerateKey( "XF86PowerOff", "XF86PowerOff", DALI_KEY_POWER, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "XF86PowerOff", "XF86PowerOff", DALI_KEY_POWER, 0, 0, Integration::KeyEvent::Up ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Generate a Esc key event. The text field should lose the focus.
+  application.ProcessEvent( GenerateKey( "XF86Menu", "XF86Menu", DALI_KEY_MENU, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "XF86Menu", "XF86Menu", DALI_KEY_MENU, 0, 0, Integration::KeyEvent::Up ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Generate a Esc key event. The text field should lose the focus.
+  application.ProcessEvent( GenerateKey( "XF86Home", "XF86Home", DALI_KEY_HOME, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "XF86Home", "XF86Home", DALI_KEY_HOME, 0, 0, Integration::KeyEvent::Up ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // The text shouldn't be deleted.
+  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), longText, TEST_LOCATION );
+
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextSelectionPopupMirroringLTR.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextSelectionPopupMirroringLTR.cpp
new file mode 100644 (file)
index 0000000..5234210
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <stdlib.h>
+#include <locale.h>
+#include <libintl.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+namespace
+{
+
+const char* DEFAULT_LOCALE_DIR = "/tmp/locale/";
+const std::string DEFAULT_EN_LOCALE_DIR = "/tmp/locale/en/LC_MESSAGES/";
+
+}
+
+void dali_textselectionpopupmirroringltr_startup(void)
+{
+  // Cheat! Copy the .mo file
+  std::ifstream  src( std::string( DEFAULT_EN_LOCALE_DIR + "dali-toolkit.mo.en" ).c_str(), std::ifstream::binary );
+  std::ofstream  dst( std::string( DEFAULT_EN_LOCALE_DIR + "dali-toolkit.mo" ).c_str(), std::ofstream::binary );
+  dst << src.rdbuf();
+
+  test_return_value = TET_UNDEF;
+}
+
+void dali_textselectionpopupmirroringltr_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliToolkitTextSelectionPopupMirroringLTR(void)
+{
+  // Test the popup mirroring.
+  const std::string CUT( "optionCut" );
+  const std::string COPY( "optionCopy" );
+  const std::string PASTE( "optionPaste" );
+
+  ToolkitTestApplication application;
+
+  setlocale( LC_ALL, "en_GB.UTF-8" );
+  textdomain("dali-toolkit");
+  bindtextdomain("dali-toolkit", DEFAULT_LOCALE_DIR );
+
+  TextSelectionPopup textSelectionPopup = TextSelectionPopup::New( NULL );
+
+  // Enable some buttons.
+  TextSelectionPopup::Buttons buttons = static_cast<TextSelectionPopup::Buttons>( TextSelectionPopup::COPY | TextSelectionPopup::CUT | TextSelectionPopup::PASTE );
+  textSelectionPopup.EnableButtons( buttons );
+
+  // Show the popup.
+  textSelectionPopup.ShowPopup();
+
+  Actor cutActor = textSelectionPopup.FindChildByName( CUT );
+  if( !cutActor )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  Actor tableOfButtons = cutActor.GetParent();
+  if( !tableOfButtons )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  // The order should be COPY, CUT, PASTE
+  DALI_TEST_EQUALS( COPY, tableOfButtons.GetChildAt( 0 ).GetName(), TEST_LOCATION );
+  DALI_TEST_EQUALS( CUT, tableOfButtons.GetChildAt( 2 ).GetName(), TEST_LOCATION );
+  DALI_TEST_EQUALS( PASTE, tableOfButtons.GetChildAt( 4 ).GetName(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextSelectionPopupMirroringRTL.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextSelectionPopupMirroringRTL.cpp
new file mode 100644 (file)
index 0000000..9d3e750
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <stdlib.h>
+#include <locale.h>
+#include <libintl.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+namespace
+{
+
+const char* DEFAULT_LOCALE_DIR = "/tmp/locale/";
+const std::string DEFAULT_EN_LOCALE_DIR = "/tmp/locale/en/LC_MESSAGES/";
+
+}
+
+void dali_textselectionpopupmirroringrtl_startup(void)
+{
+  // Cheat! Copy the .mo file
+  std::ifstream  src( std::string( DEFAULT_EN_LOCALE_DIR + "dali-toolkit.mo.ar" ).c_str(), std::ifstream::binary );
+  std::ofstream  dst( std::string( DEFAULT_EN_LOCALE_DIR + "dali-toolkit.mo" ).c_str(), std::ofstream::binary );
+  dst << src.rdbuf();
+
+  test_return_value = TET_UNDEF;
+}
+
+void dali_textselectionpopupmirroringrtl_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliToolkitTextSelectionPopupMirroringRTL(void)
+{
+  // Test the popup mirroring.
+  const std::string CUT( "optionCut" );
+  const std::string COPY( "optionCopy" );
+  const std::string PASTE( "optionPaste" );
+
+  ToolkitTestApplication application;
+
+  setlocale( LC_ALL, "en_GB.UTF-8" );
+  textdomain("dali-toolkit");
+  bindtextdomain("dali-toolkit", DEFAULT_LOCALE_DIR );
+
+  TextSelectionPopup textSelectionPopup = TextSelectionPopup::New( NULL );
+
+  // Enable some buttons.
+  TextSelectionPopup::Buttons buttons = static_cast<TextSelectionPopup::Buttons>( TextSelectionPopup::COPY | TextSelectionPopup::CUT | TextSelectionPopup::PASTE );
+  textSelectionPopup.EnableButtons( buttons );
+
+  // Show the popup.
+  textSelectionPopup.ShowPopup();
+
+  Actor cutActor = textSelectionPopup.FindChildByName( CUT );
+  if( !cutActor )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  Actor tableOfButtons = cutActor.GetParent();
+  if( !tableOfButtons )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  // The order should be PASTE, CUT, COPY
+  DALI_TEST_EQUALS( PASTE, tableOfButtons.GetChildAt( 0 ).GetName(), TEST_LOCATION );
+  DALI_TEST_EQUALS( CUT, tableOfButtons.GetChildAt( 2 ).GetName(), TEST_LOCATION );
+  DALI_TEST_EQUALS( COPY, tableOfButtons.GetChildAt( 4 ).GetName(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
index fc94130..9e39e36 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali-toolkit/devel-api/visual-factory/transition-data.h>
 #include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/align-enums.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include "dummy-control.h"
@@ -54,7 +55,8 @@ Property::Map DefaultTransform()
     .Add( Toolkit::DevelVisual::Transform::Property::SIZE, Vector2(1.0f, 1.0f) )
     .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::CENTER )
     .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::CENTER )
-    .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4::ZERO );
+    .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::DevelVisual::Transform::Policy::RELATIVE, Toolkit::DevelVisual::Transform::Policy::RELATIVE ) )
+    .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::DevelVisual::Transform::Policy::RELATIVE, Toolkit::DevelVisual::Transform::Policy::RELATIVE ) );
   return transformMap;
 }
 
@@ -747,12 +749,15 @@ int UtcDaliVisualGetPropertyMap6(void)
   ToolkitTestApplication application;
   tet_infoline( "UtcDaliVisualGetPropertyMap6: NPatchVisual" );
 
+  Rect< int > border( 1, 1, 1, 1 );
+
   VisualFactory factory = VisualFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert( Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMap.Insert( Visual::Property::TYPE, DevelVisual::N_PATCH );
   propertyMap.Insert( "mixColor",  Color::MAGENTA );
   propertyMap.Insert( ImageVisual::Property::URL,  TEST_NPATCH_FILE_NAME );
   propertyMap.Insert( ImageVisual::Property::BORDER_ONLY,  true );
+  propertyMap.Insert( DevelImageVisual::Property::BORDER, border );
   Visual::Base nPatchVisual = factory.CreateVisual( propertyMap );
 
   Property::Map resultMap;
@@ -761,7 +766,40 @@ int UtcDaliVisualGetPropertyMap6(void)
   // check the property values from the returned map from visual
   Property::Value* value = resultMap.Find( Visual::Property::TYPE,  Property::INTEGER );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<int>() == Visual::IMAGE );
+  DALI_TEST_CHECK( value->Get<int>() == DevelVisual::N_PATCH );
+
+  value = resultMap.Find( DevelVisual::Property::MIX_COLOR,  Property::VECTOR4 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<Vector4>() == Color::MAGENTA );
+
+  value = resultMap.Find( ImageVisual::Property::URL,  Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<std::string>() == TEST_NPATCH_FILE_NAME );
+
+  value = resultMap.Find( ImageVisual::Property::BORDER_ONLY,  Property::BOOLEAN );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<bool>() );
+
+  value = resultMap.Find( DevelImageVisual::Property::BORDER,  Property::RECTANGLE );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get< Rect< int > >() == border );
+
+  Vector4 border1( 1.0f, 1.0f, 1.0f, 1.0f );
+
+  Property::Map propertyMap1;
+  propertyMap1.Insert( Visual::Property::TYPE, DevelVisual::N_PATCH );
+  propertyMap1.Insert( "mixColor",  Color::MAGENTA );
+  propertyMap1.Insert( ImageVisual::Property::URL,  TEST_NPATCH_FILE_NAME );
+  propertyMap1.Insert( ImageVisual::Property::BORDER_ONLY,  true );
+  propertyMap1.Insert( DevelImageVisual::Property::BORDER, border1 );
+  nPatchVisual = factory.CreateVisual( propertyMap1 );
+
+  nPatchVisual.CreatePropertyMap( resultMap );
+
+  // check the property values from the returned map from visual
+  value = resultMap.Find( Visual::Property::TYPE,  Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<int>() == DevelVisual::N_PATCH );
 
   value = resultMap.Find( DevelVisual::Property::MIX_COLOR,  Property::VECTOR4 );
   DALI_TEST_CHECK( value );
@@ -775,6 +813,9 @@ int UtcDaliVisualGetPropertyMap6(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_CHECK( value->Get<bool>() );
 
+  value = resultMap.Find( DevelImageVisual::Property::BORDER,  Property::RECTANGLE );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get< Rect< int > >() == border );
 
   END_TEST;
 }
@@ -787,7 +828,7 @@ int UtcDaliVisualGetPropertyMap7(void)
   // request SvgVisual with a property map
   VisualFactory factory = VisualFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert( Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMap.Insert( Visual::Property::TYPE, DevelVisual::SVG );
   propertyMap.Insert( DevelVisual::Property::MIX_COLOR, Color::WHITE );
   propertyMap.Insert( ImageVisual::Property::URL, TEST_SVG_FILE_NAME );
   Visual::Base svgVisual = factory.CreateVisual( propertyMap );
@@ -797,7 +838,7 @@ int UtcDaliVisualGetPropertyMap7(void)
   // check the property values from the returned map from a visual
   Property::Value* value = resultMap.Find( Visual::Property::TYPE,  Property::INTEGER );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<int>() == Visual::IMAGE );
+  DALI_TEST_CHECK( value->Get<int>() == DevelVisual::SVG );
 
   value = resultMap.Find( ImageVisual::Property::URL,  Property::STRING );
   DALI_TEST_CHECK( value );
@@ -810,7 +851,7 @@ int UtcDaliVisualGetPropertyMap7(void)
   // check the property values from the returned map from a visual
   value = resultMap.Find( Visual::Property::TYPE,  Property::INTEGER );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<int>() == Visual::IMAGE );
+  DALI_TEST_CHECK( value->Get<int>() == DevelVisual::SVG );
 
   value = resultMap.Find( ImageVisual::Property::URL,  Property::STRING );
   DALI_TEST_CHECK( value );
@@ -1041,34 +1082,33 @@ int UtcDaliVisualGetPropertyMap10(void)
 int UtcDaliVisualGetPropertyMap11(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliVisualGetPropertyMap7: AnimatedImageVisual" );
+  tet_infoline( "UtcDaliVisualGetPropertyMap11: AnimatedImageVisual" );
 
-  // request SvgVisual with a property map
+  // request AnimatedImageVisual with a property map
   VisualFactory factory = VisualFactory::Get();
-  Property::Map propertyMap;
-  Visual::Base svgVisual = factory.CreateVisual( Property::Map()
-                                                 .Add( Visual::Property::TYPE,  Visual::IMAGE )
+  Visual::Base animatedImageVisual = factory.CreateVisual( Property::Map()
+                                                 .Add( Visual::Property::TYPE, DevelVisual::ANIMATED_IMAGE )
                                                  .Add( ImageVisual::Property::URL, TEST_GIF_FILE_NAME ) );
 
   Property::Map resultMap;
-  svgVisual.CreatePropertyMap( resultMap );
+  animatedImageVisual.CreatePropertyMap( resultMap );
   // check the property values from the returned map from a visual
   Property::Value* value = resultMap.Find( Visual::Property::TYPE,  Property::INTEGER );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<int>() == Visual::IMAGE );
+  DALI_TEST_CHECK( value->Get<int>() == DevelVisual::ANIMATED_IMAGE );
 
   value = resultMap.Find( ImageVisual::Property::URL,  Property::STRING );
   DALI_TEST_CHECK( value );
   DALI_TEST_CHECK( value->Get<std::string>() == TEST_GIF_FILE_NAME );
 
-  // request SvgVisual with an URL
-  Visual::Base svgVisual2 = factory.CreateVisual( TEST_GIF_FILE_NAME, ImageDimensions() );
+  // request AnimatedImageVisual with an URL
+  Visual::Base animatedImageVisual2 = factory.CreateVisual( TEST_GIF_FILE_NAME, ImageDimensions() );
   resultMap.Clear();
-  svgVisual2.CreatePropertyMap( resultMap );
+  animatedImageVisual2.CreatePropertyMap( resultMap );
   // check the property values from the returned map from a visual
   value = resultMap.Find( Visual::Property::TYPE,  Property::INTEGER );
   DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( value->Get<int>() == Visual::IMAGE );
+  DALI_TEST_CHECK( value->Get<int>() == DevelVisual::ANIMATED_IMAGE );
 
   value = resultMap.Find( ImageVisual::Property::URL,  Property::STRING );
   DALI_TEST_CHECK( value );
@@ -1639,9 +1679,14 @@ int UtcDaliVisualGetTransform(void)
     DALI_TEST_CHECK( typeValue->Get<Vector2>() == Vector2(1.0f,1.0f) );
   }
   {
-    Property::Value* typeValue = map->Find( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE );
+    Property::Value* typeValue = map->Find( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY );
     DALI_TEST_CHECK( typeValue );
-    DALI_TEST_CHECK( typeValue->Get<Vector4>() == Vector4(0.0f,0.0f,0.0f,0.0f) );
+    DALI_TEST_CHECK( typeValue->Get< Vector2 >() == Vector2( Toolkit::DevelVisual::Transform::Policy::RELATIVE, Toolkit::DevelVisual::Transform::Policy::RELATIVE ) );
+  }
+  {
+    Property::Value* typeValue = map->Find( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY );
+    DALI_TEST_CHECK( typeValue );
+    DALI_TEST_CHECK( typeValue->Get< Vector2 >() == Vector2( Toolkit::DevelVisual::Transform::Policy::RELATIVE, Toolkit::DevelVisual::Transform::Policy::RELATIVE ) );
   }
   {
     Property::Value* typeValue = map->Find( Toolkit::DevelVisual::Transform::Property::ORIGIN );
@@ -1662,7 +1707,7 @@ static void TestTransform( ToolkitTestApplication& application, Visual::Base vis
   Property::Map transform;
   transform.Insert( DevelVisual::Transform::Property::OFFSET, Vector2(10.0f, 10.0f) );
   transform.Insert( DevelVisual::Transform::Property::SIZE, Vector2(0.2f, 0.2f) );
-  transform.Insert( DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4(1.0f, 1.0f, 0.0f,0.0f) );
+  transform.Insert( DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::DevelVisual::Transform::Policy::ABSOLUTE, Toolkit::DevelVisual::Transform::Policy::ABSOLUTE ) );
   transform.Insert( DevelVisual::Transform::Property::ORIGIN, "TOP_BEGIN" );
   transform.Insert( DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::BOTTOM_END );
 
@@ -1685,9 +1730,14 @@ static void TestTransform( ToolkitTestApplication& application, Visual::Base vis
     DALI_TEST_EQUALS( typeValue->Get<Vector2>(), Vector2(0.2f,0.2f), TEST_LOCATION );
   }
   {
-    Property::Value* typeValue = map->Find( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE );
+    Property::Value* typeValue = map->Find( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY );
     DALI_TEST_CHECK( typeValue );
-    DALI_TEST_EQUALS( typeValue->Get<Vector4>(), Vector4(1.0f,1.0f,0.0f,0.0f), TEST_LOCATION );
+    DALI_TEST_EQUALS( typeValue->Get< Vector2 >(), Vector2( Toolkit::DevelVisual::Transform::Policy::ABSOLUTE, Toolkit::DevelVisual::Transform::Policy::ABSOLUTE ), TEST_LOCATION );
+  }
+  {
+    Property::Value* typeValue = map->Find( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY );
+    DALI_TEST_CHECK( typeValue );
+    DALI_TEST_EQUALS( typeValue->Get< Vector2 >(), Vector2( Toolkit::DevelVisual::Transform::Policy::RELATIVE, Toolkit::DevelVisual::Transform::Policy::RELATIVE ), TEST_LOCATION );
   }
   {
     Property::Value* typeValue = map->Find( Toolkit::DevelVisual::Transform::Property::ORIGIN );
@@ -1745,7 +1795,7 @@ static void TestTransform( ToolkitTestApplication& application, Visual::Base vis
   transform = DefaultTransform();
   transform.Insert( DevelVisual::Transform::Property::OFFSET, Vector2(20.0f, 20.0f) );
   transform.Insert( DevelVisual::Transform::Property::SIZE, Vector2(100.0f, 100.0f) );
-  transform.Insert( DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4(0.0f, 0.0f, 1.0f,1.0f) );
+  transform.Insert( DevelVisual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::DevelVisual::Transform::Policy::ABSOLUTE, Toolkit::DevelVisual::Transform::Policy::ABSOLUTE ) );
   visual.SetTransformAndSize( transform, Vector2(100, 100) );
   application.SendNotification();
   application.Render(0);
@@ -1927,6 +1977,44 @@ int UtcDaliVisualSetTransform7(void)
   END_TEST;
 }
 
+int UtcDaliVisualTestTransformPoliciesAsStrings(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualTestTransformPoliciesAsStrings: Use a ColorVisual and test the offset and size policies as strings" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert(Visual::Property::TYPE,  Visual::COLOR);
+  propertyMap.Insert(ColorVisual::Property::MIX_COLOR,  Color::BLUE);
+  Visual::Base visual = factory.CreateVisual( propertyMap );
+
+  Property::Map transform;
+  transform[ "offsetPolicy" ] = Property::Array().Add( "ABSOLUTE" )
+                                                 .Add( "RELATIVE" );
+  transform[ "sizePolicy"   ] = Property::Array().Add( "RELATIVE" )
+                                                 .Add( "ABSOLUTE" );
+  visual.SetTransformAndSize( transform, Vector2(100, 100) );
+
+  Dali::Property::Map visualMap;
+  visual.CreatePropertyMap( visualMap );
+  Property::Value* value = visualMap.Find( Dali::Toolkit::DevelVisual::Property::TRANSFORM );
+  Dali::Property::Map* map = value->GetMap();
+  DALI_TEST_CHECK( map );
+
+  {
+    Property::Value* typeValue = map->Find( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY );
+    DALI_TEST_CHECK( typeValue );
+    DALI_TEST_EQUALS( typeValue->Get< Vector2 >(), Vector2( Toolkit::DevelVisual::Transform::Policy::ABSOLUTE, Toolkit::DevelVisual::Transform::Policy::RELATIVE ), TEST_LOCATION );
+  }
+  {
+    Property::Value* typeValue = map->Find( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY );
+    DALI_TEST_CHECK( typeValue );
+    DALI_TEST_EQUALS( typeValue->Get< Vector2 >(), Vector2( Toolkit::DevelVisual::Transform::Policy::RELATIVE, Toolkit::DevelVisual::Transform::Policy::ABSOLUTE ), TEST_LOCATION );
+  }
+
+  END_TEST;
+}
+
 int UtcDaliNPatchVisualCustomShader(void)
 {
   ToolkitTestApplication application;
@@ -1941,7 +2029,7 @@ int UtcDaliNPatchVisualCustomShader(void)
   Property::Map transformMap;
   transformMap["size"] = Vector2( 0.5f, 0.5f ) ;
   transformMap["offset"] = Vector2( 20.0f, 0.0f ) ;
-  transformMap["offsetSizeMode"] = Vector4( 1.0f, 1.0f, 0.0f, 0.0f );
+  transformMap["offsetPolicy"] = Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE );
   transformMap["anchorPoint"] = Align::CENTER;
   transformMap["origin"] = Align::CENTER;
   properties[DevelVisual::Property::TRANSFORM] = transformMap;
index 4ad689f..29c4cc7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
 #include <dali/devel-api/images/nine-patch-image.h>
 #include <dali-toolkit/devel-api/align-enums.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include "dummy-control.h"
@@ -61,7 +62,8 @@ Property::Map DefaultTransform()
     .Add( Toolkit::DevelVisual::Transform::Property::SIZE, Vector2(1.0f, 1.0f) )
     .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::CENTER )
     .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::CENTER )
-    .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4::ZERO );
+    .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::DevelVisual::Transform::Policy::RELATIVE, Toolkit::DevelVisual::Transform::Policy::RELATIVE ) )
+    .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::DevelVisual::Transform::Policy::RELATIVE, Toolkit::DevelVisual::Transform::Policy::RELATIVE ) );
   return transformMap;
 }
 
@@ -844,7 +846,7 @@ int UtcDaliVisualFactoryGetNPatchVisual1(void)
   Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY );
 
   Property::Map propertyMap;
-  propertyMap.Insert( Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMap.Insert( Visual::Property::TYPE, DevelVisual::N_PATCH );
   propertyMap.Insert( ImageVisual::Property::URL,  TEST_NPATCH_FILE_NAME );
   {
     tet_infoline( "whole grid" );
@@ -888,6 +890,52 @@ int UtcDaliVisualFactoryGetNPatchVisual1(void)
 int UtcDaliVisualFactoryGetNPatchVisual2(void)
 {
   ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual1: Request 9-patch visual with a Property::Map including border" );
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Property::Map propertyMap;
+  propertyMap.Insert( Visual::Property::TYPE, DevelVisual::N_PATCH );
+  propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA );
+  propertyMap.Insert( DevelImageVisual::Property::BORDER, Rect< int >( 2, 2, 2, 2 ) );
+  {
+    tet_infoline( "whole grid" );
+    Visual::Base visual = factory.CreateVisual( propertyMap );
+    DALI_TEST_CHECK( visual );
+
+    TestGlAbstraction& gl = application.GetGlAbstraction();
+    TraceCallStack& textureTrace = gl.GetTextureTrace();
+    textureTrace.Enable(true);
+
+    DummyControl actor = DummyControl::New();
+    TestVisualRender( application, actor, visual, 1u );
+
+    DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+  }
+
+  propertyMap.Insert( ImageVisual::Property::BORDER_ONLY,  true );
+  {
+    tet_infoline( "border only" );
+    Visual::Base visual = factory.CreateVisual( propertyMap );
+    DALI_TEST_CHECK( visual );
+
+    TestGlAbstraction& gl = application.GetGlAbstraction();
+    TraceCallStack& textureTrace = gl.GetTextureTrace();
+    textureTrace.Enable(true);
+
+    DummyControl actor = DummyControl::New();
+    TestVisualRender( application, actor, visual, 1u );
+
+    DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+  }
+
+  END_TEST;
+}
+
+int UtcDaliVisualFactoryGetNPatchVisual3(void)
+{
+  ToolkitTestApplication application;
   tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual2: Request n-patch visual with a Property::Map" );
 
   VisualFactory factory = VisualFactory::Get();
@@ -907,7 +955,7 @@ int UtcDaliVisualFactoryGetNPatchVisual2(void)
   Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY );
 
   Property::Map propertyMap;
-  propertyMap.Insert( Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMap.Insert( Visual::Property::TYPE, DevelVisual::N_PATCH );
   propertyMap.Insert( ImageVisual::Property::URL,  TEST_NPATCH_FILE_NAME );
   {
     Visual::Base visual = factory.CreateVisual( propertyMap );
@@ -952,7 +1000,7 @@ int UtcDaliVisualFactoryGetNPatchVisual2(void)
   END_TEST;
 }
 
-int UtcDaliVisualFactoryGetNPatchVisual3(void)
+int UtcDaliVisualFactoryGetNPatchVisual4(void)
 {
   ToolkitTestApplication application;
   tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual3: Request 9-patch visual with an image url" );
@@ -993,7 +1041,7 @@ int UtcDaliVisualFactoryGetNPatchVisual3(void)
   END_TEST;
 }
 
-int UtcDaliVisualFactoryGetNPatchVisual4(void)
+int UtcDaliVisualFactoryGetNPatchVisual5(void)
 {
   ToolkitTestApplication application;
   tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual4: Request n-patch visual with an image url" );
@@ -1073,7 +1121,7 @@ int UtcDaliVisualFactoryGetNPatchVisualN2(void)
   DALI_TEST_CHECK( factory );
 
   Property::Map propertyMap;
-  propertyMap.Insert( Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMap.Insert( Visual::Property::TYPE, DevelVisual::N_PATCH );
   propertyMap.Insert( ImageVisual::Property::URL,  "ERROR.9.jpg" );
 
   Visual::Base visual = factory.CreateVisual( propertyMap );
index 173bfed..7ba3d11 100644 (file)
@@ -359,6 +359,7 @@ ALIASES += SINCE_1_2_4="@since 1.2.4"
 ALIASES += SINCE_1_2_5="@since 1.2.5"
 ALIASES += SINCE_1_2_10="@since 1.2.10"
 ALIASES += SINCE_1_2_14="@since 1.2.14"
+ALIASES += SINCE_1_2_32="@since 1.2.32"
 
 ALIASES += DEPRECATED_1_0="@deprecated Deprecated since 1.0"
 ALIASES += DEPRECATED_1_1="@deprecated Deprecated since 1.1"
@@ -386,6 +387,7 @@ ALIASES += REMARK_STORAGE=""
 #ALIASES += SINCE_1_2_5="\par Since:\n 3.0, DALi version 1.2.5"
 #ALIASES += SINCE_1_2_10="\par Since:\n 3.0, DALi version 1.2.10"
 #ALIASES += SINCE_1_2_14="\par Since:\n 3.0, DALi version 1.2.14"
+#ALIASES += SINCE_1_2_32="\par Since:\n 3.0, DALi version 1.2.32"
 
 ## DALi has no deprecated API in Tizen 2.4 because it's DALi's first release.
 ## Thus deprecated APIs in DALi 1.0.xx will be deprecated in Tizen 3.0.
index 9eaa3a2..5ec0293 100644 (file)
@@ -352,6 +352,7 @@ ALIASES += SINCE_1_2_4="@since 1.2.4"
 ALIASES += SINCE_1_2_5="@since 1.2.5"
 ALIASES += SINCE_1_2_10="@since 1.2.10"
 ALIASES += SINCE_1_2_14="@since 1.2.14"
+ALIASES += SINCE_1_2_32="@since 1.2.32"
 
 ALIASES += DEPRECATED_1_0="@deprecated Deprecated since 1.0"
 ALIASES += DEPRECATED_1_1="@deprecated Deprecated since 1.1"
@@ -379,6 +380,7 @@ ALIASES += REMARK_STORAGE=""
 #ALIASES += SINCE_1_2_5="\par Since:\n 3.0, DALi version 1.2.5"
 #ALIASES += SINCE_1_2_10="\par Since:\n 3.0, DALi version 1.2.10"
 #ALIASES += SINCE_1_2_14="\par Since:\n 3.0, DALi version 1.2.14"
+#ALIASES += SINCE_1_2_32="\par Since:\n 3.0, DALi version 1.2.32"
 
 ## DALi has no deprecated API in Tizen 2.4 because it's DALi's first release.
 ## Thus deprecated APIs in DALi 1.0.xx will be deprecated in Tizen 3.0.
index c155cc2..1812c4d 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index 46c32c8..84bd8db 100644 (file)
@@ -76,6 +76,11 @@ void TextSelectionToolbar::RaiseAbove( Layer target )
   GetImpl(*this).RaiseAbove( target );
 }
 
+void TextSelectionToolbar::ScrollTo( const Vector2& position )
+{
+  GetImpl(*this).ScrollTo( position );
+}
+
 TextSelectionToolbar TextSelectionToolbar::DownCast( BaseHandle handle )
 {
   return Control::DownCast<TextSelectionToolbar, Internal::TextSelectionToolbar>(handle);
index 26d81a4..6193f77 100644 (file)
@@ -130,6 +130,11 @@ public:
   void RaiseAbove( Layer target );
 
   /**
+   * @copydoc Toolkit::ScrollView::ScrollTo(const Vector2&)
+   */
+  void ScrollTo( const Vector2& position );
+
+  /**
    * @brief Downcast a handle to TextSelectionToolbar.
    *
    * If the BaseHandle points is a TextSelectionToolbar the downcast returns a valid handle.
index 7702ef4..7e66e66 100755 (executable)
@@ -24,6 +24,7 @@ devel_api_src_files = \
   $(devel_api_src_dir)/controls/text-controls/text-selection-toolbar.cpp \
   $(devel_api_src_dir)/controls/tool-bar/tool-bar.cpp \
   $(devel_api_src_dir)/focus-manager/keyinput-focus-manager.cpp \
+  $(devel_api_src_dir)/focus-manager/keyboard-focus-manager-devel.cpp \
   $(devel_api_src_dir)/image-loader/atlas-upload-observer.cpp \
   $(devel_api_src_dir)/image-loader/image-atlas.cpp \
   $(devel_api_src_dir)/scripting/script.cpp \
@@ -98,13 +99,15 @@ devel_api_visual_factory_header_files = \
 
 devel_api_visuals_header_files = \
   $(devel_api_src_dir)/visuals/text-visual-properties.h \
+  $(devel_api_src_dir)/visuals/image-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/visual-properties-devel.h
 
 devel_api_shadow_view_header_files = \
   $(devel_api_src_dir)/controls/shadow-view/shadow-view.h
 
 devel_api_focus_manager_header_files = \
-  $(devel_api_src_dir)/focus-manager/keyinput-focus-manager.h
+  $(devel_api_src_dir)/focus-manager/keyinput-focus-manager.h \
+  $(devel_api_src_dir)/focus-manager/keyboard-focus-manager-devel.h
 
 devel_api_image_loader_header_files = \
   $(devel_api_src_dir)/image-loader/atlas-upload-observer.h \
diff --git a/dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.cpp b/dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.cpp
new file mode 100644 (file)
index 0000000..a56ece5
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h>
+#include <dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace DevelKeyboardFocusManager
+{
+
+void SetCustomAlgorithm(KeyboardFocusManager keyboardFocusManager, CustomAlgorithmInterface& interface)
+{
+  GetImpl(keyboardFocusManager).SetCustomAlgorithm(interface);
+}
+
+} // namespace DevelKeyboardFocusManager
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h b/dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h
new file mode 100644 (file)
index 0000000..18885a8
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef DALI_TOOLKIT_KEYBOARD_FOCUS_MANAGER_DEVEL_H
+#define DALI_TOOLKIT_KEYBOARD_FOCUS_MANAGER_DEVEL_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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-toolkit/public-api/controls/control.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace DevelKeyboardFocusManager
+{
+/**
+ * @brief Interface used to provide custom keyboard focus algorithm for retrieving the next focusable actor.
+ *
+ * The application / toolkit can implement the interface and override the keyboard focus behaviour.
+ * Upon providing an implementation of this interface, the PreFocusChangeSignal is no longer emitted.
+ * If focus is changing within a layout container, then the layout container is queried first to provide
+ * the next focusable actor. If this does not provide a valid actor, then the Keyboard FocusManager will
+ * check focusable properties to determine next focusable actor. If focusable properties are not set,
+ * then the Keyboard FocusManager calls the GetNextFocusableActor() method of this interface.
+ */
+class CustomAlgorithmInterface
+{
+public:
+
+  /**
+   * @brief Virtual destructor.
+   */
+  virtual ~CustomAlgorithmInterface() {};
+
+  /**
+   * @brief Called by the KeyboardFocusManager to get the next focusable actor.
+   *
+   * @param[in] current The current focused actor
+   * @param[in] proposed The proposed focused actor
+   * @param[in] direction The direction of focus movement
+   * @return A handle to the next focusable actor
+   */
+  virtual Actor GetNextFocusableActor(Actor current, Actor proposed, Control::KeyboardFocus::Direction direction) = 0;
+};
+
+/**
+ * @brief Provide the implementation of custom Focus algorithm interface
+ *
+ * @param[in] keyboardFocusManager The instance of KeyboardFocusManager
+ * @param[in] interface The user's implementation of CustomAlgorithmInterface
+ * @see DevelKeyboardFocusManager::CustomAlgorithmInterface
+ */
+void SetCustomAlgorithm(KeyboardFocusManager keyboardFocusManager, CustomAlgorithmInterface& interface);
+
+} // namespace DevelKeyboardFocusManager
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_KEYBOARD_FOCUS_MANAGER_DEVEL_H
index f7ffb51..4e2e0f5 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_TOOLKIT_VISUAL_BASE_H
 #define DALI_TOOLKIT_VISUAL_BASE_H
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -52,27 +52,23 @@ namespace Visual
  * | transform               | MAP              |
  *
  * where \b customShader is a map with at least one of the following properties:
- * | %Property Name          | Type             | Required | Default | Description |
- * |-------------------------|------------------|----------|---------|-------------|
- * | vertexShader            | STRING           | No | "" | Vertex shader code|
- * | fragmentShader          | STRING           | No | "" | Fragment shader code|
- * | subdivideGridX          | INTEGER          | No | 1 | How to subdivide the grid along X |
- * | subdivideGridY          | INTEGER          | No | 1 | How to subdivide the grid along Y |
- * | shaderHints             | INTEGER or ARRAY of STRING | No | NONE | Bitmask of hints @sa Dali::Shader::Hint |
+ * | %Property Name          | Type                       | Required | Default | Description                             |
+ * |-------------------------|----------------------------|----------|---------|-----------------------------------------|
+ * | vertexShader            | STRING                     | No       | ""      | Vertex shader code                      |
+ * | fragmentShader          | STRING                     | No       | ""      | Fragment shader code                    |
+ * | subdivideGridX          | INTEGER                    | No       | 1       | How to subdivide the grid along X       |
+ * | subdivideGridY          | INTEGER                    | No       | 1       | How to subdivide the grid along Y       |
+ * | shaderHints             | INTEGER or ARRAY of STRING | No       | NONE    | Bitmask of hints @sa Dali::Shader::Hint |
  *
  * and \b transform is a map with the following properties:
- * | %Property Name          | Type             | Required | Default |Description |
- * |-------------------------|------------------|----------|---------|------------|
- * | offset                  | VECTOR2          | No | (0,0) | Offset of visual from origin |
- * | size                    | VECTOR2          | No | (1,1) | size of visual |
- * | origin                  | INTEGER or STRING | No | CENTER | origin of the visual @sa Dali::Toolkit::Align |
- * | anchorPoint             | INTEGER or STRING | No | CENTER | anchor point of the visual @sa Dali::Toolkit::Align |
- * | offsetSizeMode          | VECTOR4          | No | (0,0,0,0) | See below |
- *
- *
- * offsetSizeMode describes whether the offset and the size are
- * relative or absolute by using 0 or 1 respectively in the corresponding
- * components (offsetSizeMode.xy for offset.xy; offsetSizeMode.zw for size.xy).
+ * | %Property Name          | Type              | Required | Default                | Description                                         |
+ * |-------------------------|-------------------|----------|------------------------|-----------------------------------------------------|
+ * | offset                  | VECTOR2           | No       | (0,0)                  | Offset of visual from origin                        |
+ * | size                    | VECTOR2           | No       | (1,1)                  | size of visual                                      |
+ * | origin                  | INTEGER or STRING | No       | CENTER                 | origin of the visual @sa Dali::Toolkit::Align       |
+ * | anchorPoint             | INTEGER or STRING | No       | CENTER                 | anchor point of the visual @sa Dali::Toolkit::Align |
+ * | offsetPolicy            | VECTOR2           | No       | ( RELATIVE, RELATIVE ) | @sa Dali::Toolkit::DevelVisual::Transform::Policy   |
+ * | sizePolicy              | VECTOR2           | No       | ( RELATIVE, RELATIVE ) | @sa Dali::Toolkit::DevelVisual::Transform::Policy   |
  *
  * Relative means that the component describes a factor of the parent control size;
  * size.x = 1 means full width; size.y = 0.5 means half height.
diff --git a/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h b/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h
new file mode 100644 (file)
index 0000000..eb2ac49
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef DALI_TOOLKIT_DEVEL_API_VISUALS_IMAGE_VISUAL_PROPERTIES_DEVEL_H
+#define DALI_TOOLKIT_DEVEL_API_VISUALS_IMAGE_VISUAL_PROPERTIES_DEVEL_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/visuals/image-visual-properties.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace DevelImageVisual
+{
+
+namespace Property
+{
+
+enum Type
+{
+  URL                 = Dali::Toolkit::ImageVisual::Property::URL,
+  FITTING_MODE        = Dali::Toolkit::ImageVisual::Property::FITTING_MODE,
+  SAMPLING_MODE       = Dali::Toolkit::ImageVisual::Property::SAMPLING_MODE,
+  DESIRED_WIDTH       = Dali::Toolkit::ImageVisual::Property::DESIRED_WIDTH,
+  DESIRED_HEIGHT      = Dali::Toolkit::ImageVisual::Property::DESIRED_HEIGHT,
+  SYNCHRONOUS_LOADING = Dali::Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING,
+  BORDER_ONLY         = Dali::Toolkit::ImageVisual::Property::BORDER_ONLY,
+  PIXEL_AREA          = Dali::Toolkit::ImageVisual::Property::PIXEL_AREA,
+  WRAP_MODE_U         = Dali::Toolkit::ImageVisual::Property::WRAP_MODE_U,
+  WRAP_MODE_V         = Dali::Toolkit::ImageVisual::Property::WRAP_MODE_V,
+
+  /**
+   * @brief The border of the image
+   * @details Name "border", type Property::RECTANGLE or Property::VECTOR4
+   *          The border of the image in the order: left, right, bottom, top.
+   *
+   * @note Optional.
+   * @note For N-Patch images only.
+   */
+  BORDER = WRAP_MODE_V + 1,
+};
+
+} //namespace Property
+
+} // namespace DevelImageVisual
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_DEVEL_API_VISUALS_IMAGE_VISUAL_PROPERTIES_DEVEL_H
index b70d254..adecf39 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_DEVEL_API_VISUALS_VISUAL_PROPERTIES_DEVEL_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,15 +35,18 @@ namespace DevelVisual
  */
 enum Type
 {
-  BORDER    = Dali::Toolkit::Visual::BORDER,
-  COLOR     = Dali::Toolkit::Visual::COLOR,
-  GRADIENT  = Dali::Toolkit::Visual::GRADIENT,
-  IMAGE     = Dali::Toolkit::Visual::IMAGE,
-  MESH      = Dali::Toolkit::Visual::MESH,
-  PRIMITIVE = Dali::Toolkit::Visual::PRIMITIVE,
-  WIREFRAME = Dali::Toolkit::Visual::WIREFRAME,
-
-  TEXT      = WIREFRAME + 1, ///< Renders text.
+  BORDER         = Dali::Toolkit::Visual::BORDER,
+  COLOR          = Dali::Toolkit::Visual::COLOR,
+  GRADIENT       = Dali::Toolkit::Visual::GRADIENT,
+  IMAGE          = Dali::Toolkit::Visual::IMAGE,
+  MESH           = Dali::Toolkit::Visual::MESH,
+  PRIMITIVE      = Dali::Toolkit::Visual::PRIMITIVE,
+  WIREFRAME      = Dali::Toolkit::Visual::WIREFRAME,
+
+  TEXT           = WIREFRAME + 1, ///< Renders text.
+  N_PATCH        = WIREFRAME + 2, ///< Renders an n-patch image.
+  SVG            = WIREFRAME + 3, ///< Renders an SVG image.
+  ANIMATED_IMAGE = WIREFRAME + 4  ///< Renders a animated image.
 };
 
 namespace Property
@@ -91,27 +94,41 @@ enum Type
   OPACITY = SHADER + 4
 };
 
-} //namespace Property
+} // namespace Property
 
 namespace Transform
 {
 
+/**
+ * @brief Policies used by the transform for the offset or size.
+ */
+namespace Policy
+{
+
+enum Type
+{
+  RELATIVE = 0,   ///< Relative to the control (percentage [0.0f to 1.0f] of the control).
+  ABSOLUTE = 1    ///< Absolute value in world units.
+};
+
+} // namespace Policy
+
 namespace Property
 {
 
 enum Type
 {
   /**
-   * @brief Offset of the visual. It can be either relative (percentage of the parent)
-   * or absolute (in world units).
+   * @brief Offset of the visual, which can be either relative (percentage [0.0f to 1.0f] of the parent) or absolute (in world units).
    * @details Name "offset", type Property::VECTOR2
+   * @see OFFSET_POLICY
    */
   OFFSET,
 
   /**
-   * @brief Size of the visual. It can be either relative (percentage of the parent)
-   * or absolute (in world units).
+   * @brief Size of the visual, which can be either relative (percentage [0.0f to 1.0f] of the parent) or absolute (in world units).
    * @details Name "size", type Property::VECTOR2
+   * @see SIZE_POLICY
    */
   SIZE,
 
@@ -130,15 +147,50 @@ enum Type
   ANCHOR_POINT,
 
   /**
-   * @brief Indicates which components of the offset and size are relative
-   * (percentage of the parent) or absolute (in world units).
-   * 0 indicates the component is relative, and 1 absolute.
-   * @details Name "offsetSizeMode", type Property::VECTOR4
+   * @brief Whether the x or y OFFSET values are relative (percentage [0.0f to 1.0f] of the control) or absolute (in world units).
+   * @details Name "offsetPolicy", type Vector2 or Property::ARRAY of Property::STRING.
+   *          If Property::ARRAY then 2 strings expected for the x and y.
+   *
+   * C++:
+   * @code
+   * control.SetProperty( ..., // Some visual based property
+   *                      Property::Map().Add( ... ) // Properties to set up visual
+   *                                     .Add( DevelVisual::Property::TRANSFORM,
+   *                                           Property::Array().Add( DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( Policy::ABSOLUTE, Policy::RELATIVE ) ) )
+   *                                                            .Add( DevelVisual::Transform::Property::OFFSET, Vector2( 10, 1.0f ) ) );
+   * @endcode
+   *
+   * JSON:
+   * @code
+   * {
+   *   ...
+   *   "transition":
+   *   {
+   *     "offsetPolicy" : [ "ABSOLUTE", "RELATIVE" ],
+   *     "offset" : [ 10, 1.0 ]
+   *   }
+   *   ...
+   * }
+   *
+   * @endcode
+   * @see Policy::Type
+   * @note By default, both the x and the y offset is RELATIVE.
+   */
+  OFFSET_POLICY,
+
+  /**
+   * @brief Whether the width or height SIZE values are relative (percentage [0.0f to 1.0f] of the control) or absolute (in world units).
+   * @details Name "sizePolicy", type Vector2 or Property::ARRAY of Property::STRING.
+   *          If Property::ARRAY then 2 strings expected for the width and height.
+   *
+   * @see Policy::Type
+   * @see OFFSET_POLICY for example
+   * @note By default, both the width and the height is RELATIVE to the control's size.
    */
-  OFFSET_SIZE_MODE
+  SIZE_POLICY,
 };
 
-} //namespace Property
+} // namespace Property
 
 } // namespace Transform
 
index a8ab543..79ac7db 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -980,7 +980,7 @@ void Button::OnRelayout( const Vector2& size, RelayoutContainer& container )
     Property::Map visualTransform;
 
     visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, size )
-                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 0.0f, 0.0f, 1.0f, 1.0f) );  // Use relative size
+                   .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) );
 
     currentBackGroundVisual.SetTransformAndSize( visualTransform, size );
   }
@@ -993,7 +993,8 @@ void Button::OnRelayout( const Vector2& size, RelayoutContainer& container )
 
     visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, visualSize )
                    .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, visualPosition )
-                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 1.0f, 1.0f, 1.0f, 1.0f) )  // Use absolute size
+                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
+                   .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
                    .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
                    .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
 
@@ -1023,7 +1024,8 @@ void Button::OnRelayout( const Vector2& size, RelayoutContainer& container )
       Property::Map textVisualTransform;
       textVisualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, preSize )
                          .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, labelPosition )
-                         .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 1.0f, 1.0f, 1.0f,1.0f ) ) // Use absolute size
+                         .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
+                         .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
                          .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
                          .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
 
index 555cb7b..0e2b58c 100755 (executable)
@@ -324,7 +324,8 @@ void ToggleButton::RelayoutVisual( Property::Index index, const Vector2& size )
     Property::Map visualTransform;
     visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, visualSize )
                    .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, visualPosition )
-                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) )  // Use absolute size
+                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
+                   .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
                    .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::CENTER )
                    .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::CENTER );
 
index 05005f5..cddfa35 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -142,7 +142,9 @@ void ProgressBar::OnRelayout( const Vector2& size, RelayoutContainer& container
     Property::Map visualTransform;
 
     visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, trackSize )
-                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );  // Use Absolute size
+                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
+                   .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) );
+
     trackVisual.SetTransformAndSize( visualTransform, trackSize );
   }
 
@@ -151,7 +153,8 @@ void ProgressBar::OnRelayout( const Vector2& size, RelayoutContainer& container
     Property::Map visualTransform;
 
     visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, Vector2( mDomain.from.x + mSecondaryProgressValue * ( mDomain.to.x - mDomain.from.x ), trackSize.height  ) )
-                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) )  // Use Absolute size
+                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
+                   .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
                    .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
                    .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN );
     secondProgressVisual.SetTransformAndSize( visualTransform, trackSize );
@@ -162,7 +165,8 @@ void ProgressBar::OnRelayout( const Vector2& size, RelayoutContainer& container
     Property::Map visualTransform;
 
     visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, Vector2( mDomain.from.x + mProgressValue * ( mDomain.to.x - mDomain.from.x ), trackSize.height ) )
-                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) )  // Use Absolute size
+                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
+                   .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
                    .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
                    .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN );
     progressVisual.SetTransformAndSize( visualTransform, trackSize );
@@ -173,8 +177,8 @@ void ProgressBar::OnRelayout( const Vector2& size, RelayoutContainer& container
     Property::Map visualTransform;
 
     visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, trackSize )
-                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );  // Use Absolute size
-
+                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
+                   .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) );
     labelVisual.SetTransformAndSize( visualTransform, trackSize );
   }
 
@@ -183,7 +187,8 @@ void ProgressBar::OnRelayout( const Vector2& size, RelayoutContainer& container
     Property::Map visualTransform;
 
     visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, trackSize )
-                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );  // Use Absolute size
+                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
+                   .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) );
     indeterminateVisual.SetTransformAndSize( visualTransform, trackSize );
   }
 
index 5e2de42..c08b897 100644 (file)
@@ -1037,6 +1037,9 @@ void TextEditor::OnInitialize()
   // Enable the smooth handle panning.
   mController->SetSmoothHandlePanEnabled( true );
 
+  mController->SetNoTextDoubleTapAction( Controller::NoTextTap::HIGHLIGHT );
+  mController->SetNoTextLongPressAction( Controller::NoTextTap::HIGHLIGHT );
+
   // Forward input events to controller
   EnableGestureDetection( static_cast<Gesture::Type>( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) );
   GetTapGestureDetector().SetMaximumTapsRequired( 2 );
@@ -1095,20 +1098,25 @@ void TextEditor::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange:
       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
       // Property system did not set the font so should update it.
       mController->UpdateAfterFontChange( newFont );
+      RelayoutRequest();
       break;
     }
 
     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
     {
       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+      RelayoutRequest();
       break;
     }
     case StyleChange::THEME_CHANGE:
     {
-      GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+      // Nothing to do, let control base class handle this
       break;
     }
   }
+
+  // Up call to Control
+  Control::OnStyleChange( styleManager, change );
 }
 
 Vector3 TextEditor::GetNaturalSize()
index 240dfde..2e300b1 100644 (file)
@@ -1162,8 +1162,8 @@ void TextField::OnInitialize()
   // Disable the smooth handle panning.
   mController->SetSmoothHandlePanEnabled( false );
 
-  mController->SetNoTextDoubleTapAction( Controller::NoTextTap::NO_ACTION );
-  mController->SetNoTextLongPressAction( Controller::NoTextTap::SHOW_SELECTION_POPUP );
+  mController->SetNoTextDoubleTapAction( Controller::NoTextTap::HIGHLIGHT );
+  mController->SetNoTextLongPressAction( Controller::NoTextTap::HIGHLIGHT );
 
   // Forward input events to controller
   EnableGestureDetection( static_cast<Gesture::Type>( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) );
@@ -1209,20 +1209,25 @@ void TextField::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::
       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
       // Property system did not set the font so should update it.
       mController->UpdateAfterFontChange( newFont );
+      RelayoutRequest();
       break;
     }
 
     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
     {
       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+      RelayoutRequest();
       break;
     }
     case StyleChange::THEME_CHANGE:
     {
-      GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+      // Nothing to do, let control base class handle this
       break;
     }
   }
+
+  // Up call to Control
+  Control::OnStyleChange( styleManager, change );
 }
 
 Vector3 TextField::GetNaturalSize()
index b6b5db0..3d161e0 100644 (file)
@@ -672,19 +672,24 @@ void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::
       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
       DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnStyleChange StyleChange::DEFAULT_FONT_CHANGE newFont(%s)\n", newFont.c_str() );
       mController->UpdateAfterFontChange( newFont );
+      RelayoutRequest();
       break;
     }
     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
     {
       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+      RelayoutRequest();
       break;
     }
     case StyleChange::THEME_CHANGE:
     {
-      GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+      // Nothing to do, let control base class handle this
       break;
     }
   }
+
+  // Up call to Control
+  Control::OnStyleChange( styleManager, change );
 }
 
 Vector3 TextLabel::GetNaturalSize()
index 6ea83c0..babd0eb 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <libintl.h>
+#include <string.h>
 #include <cfloat>
 #include <dali/public-api/animation/animation.h>
 #include <dali/devel-api/images/nine-patch-image.h>
@@ -88,6 +89,9 @@ const char* const OPTION_COPY("optionCopy");
 const char* const OPTION_PASTE("optionPaste");                                    // "Paste" popup option.
 const char* const OPTION_CLIPBOARD("optionClipboard");                            // "Clipboard" popup option.
 
+const std::string IDS_LTR( "IDS_LTR" );
+const std::string RTL_DIRECTION( "RTL" );
+
 BaseHandle Create()
 {
   return Toolkit::TextSelectionPopup::New( NULL );
@@ -802,6 +806,19 @@ std::string TextSelectionPopup::GetPressedImage() const
      self.Add( mToolbar );
    }
 
+   // Whether to mirror the list of buttons (for right to left languages)
+   bool mirror = false;
+   char* idsLtr = GET_LOCALE_TEXT( IDS_LTR.c_str() );
+   if( NULL != idsLtr )
+   {
+     mirror = ( 0 == strcmp( idsLtr, RTL_DIRECTION.c_str() ) );
+
+     if( mirror )
+     {
+       std::reverse( mOrderListOfButtons.begin(), mOrderListOfButtons.end() );
+     }
+   }
+
    // Iterate list of buttons and add active ones to Toolbar
    std::size_t numberOfOptionsRequired =  GetNumberOfEnabledOptions();
    std::size_t numberOfOptionsAdded = 0u;
@@ -814,6 +831,11 @@ std::string TextSelectionPopup::GetPressedImage() const
        AddOption(  button, ( numberOfOptionsAdded < numberOfOptionsRequired ) , showIcons, showCaptions );
      }
    }
+
+   if( mirror )
+   {
+     mToolbar.ScrollTo( Vector2( mPopupMaxSize.x, 0.f ) );
+   }
  }
 
 void TextSelectionPopup::CreateBackgroundBorder( Property::Map& propertyMap )
index 957e152..612ca8b 100644 (file)
@@ -280,11 +280,16 @@ void TextSelectionToolbar::SetUpScrollBar( bool enable )
 
 void TextSelectionToolbar::OnScrollStarted( const Vector2& position )
 {
+  if( mFirstScrollEnd )
+  {
+    mScrollView.SetOvershootEnabled( true );
+  }
   mTableOfButtons.SetSensitive( false );
 }
 
 void TextSelectionToolbar::OnScrollCompleted( const Vector2& position )
 {
+  mFirstScrollEnd = true;
   mTableOfButtons.SetSensitive( true );
 }
 
@@ -327,6 +332,13 @@ void TextSelectionToolbar::SetScrollBarPadding( const Vector2& padding )
   RelayoutRequest();
 }
 
+void TextSelectionToolbar::ScrollTo( const Vector2& position )
+{
+  mFirstScrollEnd = false;
+  mScrollView.SetOvershootEnabled( false );
+  mScrollView.ScrollTo( position, 0.f );
+}
+
 void TextSelectionToolbar::ConfigureScrollview( const Property::Map& properties )
 {
   // Set any properties specified for the label by iterating through all property key-value pairs.
@@ -369,7 +381,8 @@ TextSelectionToolbar::TextSelectionToolbar()
   mMaxSize (),
   mScrollBarPadding( DEFAULT_SCROLL_BAR_PADDING ),
   mIndexInTable( 0 ),
-  mDividerIndexes()
+  mDividerIndexes(),
+  mFirstScrollEnd( false )
 {
 }
 
index f5908bb..adaf3b6 100644 (file)
@@ -97,6 +97,11 @@ public:
    */
   const Vector2& GetScrollBarPadding() const;
 
+  /**
+   * @copydoc Toolkit::TextSelectionToolbar::ScrollTo()
+   */
+  void ScrollTo( const Vector2& position );
+
 private: // From Control
 
   /**
@@ -184,6 +189,7 @@ private: // Data
   Vector2 mScrollBarPadding;                          ///< The padding used to position the scroll indicator.
   unsigned int mIndexInTable;                         ///< Index in table to add option
   Dali::Vector< unsigned int > mDividerIndexes;       ///< Vector of indexes in the Toolbar that contain dividers.
+  bool mFirstScrollEnd;                               ///< Used for RTL mirroring. Avoids the overshoot to be shown the first time the popup is shown.
 };
 
 } // namespace Internal
index b787acd..12c2274 100755 (executable)
@@ -11,29 +11,30 @@ toolkit_src_files = \
    $(toolkit_src_dir)/builder/style.cpp \
    $(toolkit_src_dir)/builder/tree-node-manipulator.cpp \
    $(toolkit_src_dir)/builder/replacement.cpp \
-   $(toolkit_src_dir)/visuals/visual-base-impl.cpp \
-   $(toolkit_src_dir)/visuals/visual-base-data-impl.cpp \
-   $(toolkit_src_dir)/visuals/image-atlas-manager.cpp \
-   $(toolkit_src_dir)/visuals/npatch-loader.cpp \
-   $(toolkit_src_dir)/visuals/visual-factory-cache.cpp \
-   $(toolkit_src_dir)/visuals/visual-factory-impl.cpp \
-   $(toolkit_src_dir)/visuals/visual-string-constants.cpp \
    $(toolkit_src_dir)/visuals/animated-image/animated-image-visual.cpp \
    $(toolkit_src_dir)/visuals/border/border-visual.cpp \
    $(toolkit_src_dir)/visuals/color/color-visual.cpp \
+   $(toolkit_src_dir)/visuals/gradient/gradient-visual.cpp \
    $(toolkit_src_dir)/visuals/gradient/gradient.cpp \
    $(toolkit_src_dir)/visuals/gradient/linear-gradient.cpp \
    $(toolkit_src_dir)/visuals/gradient/radial-gradient.cpp \
-   $(toolkit_src_dir)/visuals/gradient/gradient-visual.cpp \
+   $(toolkit_src_dir)/visuals/image-atlas-manager.cpp \
    $(toolkit_src_dir)/visuals/image/image-visual.cpp \
    $(toolkit_src_dir)/visuals/mesh/mesh-visual.cpp \
+   $(toolkit_src_dir)/visuals/npatch-loader.cpp \
    $(toolkit_src_dir)/visuals/npatch/npatch-visual.cpp \
    $(toolkit_src_dir)/visuals/primitive/primitive-visual.cpp \
    $(toolkit_src_dir)/visuals/svg/svg-rasterize-thread.cpp \
    $(toolkit_src_dir)/visuals/svg/svg-visual.cpp \
    $(toolkit_src_dir)/visuals/text/text-visual.cpp \
-   $(toolkit_src_dir)/visuals/wireframe/wireframe-visual.cpp \
    $(toolkit_src_dir)/visuals/transition-data-impl.cpp \
+   $(toolkit_src_dir)/visuals/visual-base-data-impl.cpp \
+   $(toolkit_src_dir)/visuals/visual-base-impl.cpp \
+   $(toolkit_src_dir)/visuals/visual-factory-cache.cpp \
+   $(toolkit_src_dir)/visuals/visual-factory-impl.cpp \
+   $(toolkit_src_dir)/visuals/visual-string-constants.cpp \
+   $(toolkit_src_dir)/visuals/visual-url.cpp \
+   $(toolkit_src_dir)/visuals/wireframe/wireframe-visual.cpp \
    $(toolkit_src_dir)/controls/alignment/alignment-impl.cpp \
    $(toolkit_src_dir)/controls/bloom-view/bloom-view-impl.cpp \
    $(toolkit_src_dir)/controls/bubble-effect/bubble-emitter-impl.cpp \
index 29073b7..72f9359 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -121,7 +121,8 @@ KeyboardFocusManager::KeyboardFocusManager()
   mIsFocusIndicatorEnabled( false ),
   mIsWaitingKeyboardFocusChangeCommit( false ),
   mFocusHistory(),
-  mSlotDelegate( this )
+  mSlotDelegate( this ),
+  mCustomAlgorithmInterface(NULL)
 {
   // TODO: Get FocusIndicatorEnable constant from stylesheet to set mIsFocusIndicatorEnabled.
   Toolkit::KeyInputFocusManager::Get().UnhandledKeyEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnKeyEvent);
@@ -268,33 +269,106 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction
   bool succeed = false;
 
   // Go through the actor's hierarchy until we find a layout control that knows how to move the focus
-  Toolkit::Control parentLayoutControl = GetParentLayoutControl(currentFocusActor);
-  while(parentLayoutControl && !succeed)
+  Toolkit::Control parentLayoutControl = GetParentLayoutControl( currentFocusActor );
+  while( parentLayoutControl && !succeed )
   {
-    succeed = DoMoveFocusWithinLayoutControl(parentLayoutControl, currentFocusActor, direction);
-    parentLayoutControl = GetParentLayoutControl(parentLayoutControl);
+    succeed = DoMoveFocusWithinLayoutControl( parentLayoutControl, currentFocusActor, direction );
+    parentLayoutControl = GetParentLayoutControl( parentLayoutControl );
   }
 
-  if(!succeed && !mPreFocusChangeSignal.Empty())
+  if( !succeed )
   {
-    // Don't know how to move the focus further. The application needs to tell us which actor to move the focus to
-    mIsWaitingKeyboardFocusChangeCommit = true;
-    Actor nextFocusableActor = mPreFocusChangeSignal.Emit(currentFocusActor, Actor(), direction);
-    mIsWaitingKeyboardFocusChangeCommit = false;
+    Actor nextFocusableActor;
+
+    Toolkit::Control currentFocusControl = Toolkit::Control::DownCast(currentFocusActor);
+
+    // If the current focused actor is a control, then find the next focusable actor via the focusable properties.
+    if( currentFocusControl )
+    {
+      int actorId = -1;
+      Property::Index index = Property::INVALID_INDEX;
+      Property::Value value;
+
+      // Find property index based upon focus direction
+      switch ( direction )
+      {
+        case Toolkit::Control::KeyboardFocus::LEFT:
+        {
+          index = Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID;
+          break;
+        }
+        case Toolkit::Control::KeyboardFocus::RIGHT:
+        {
+          index = Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID;
+          break;
+        }
+        case Toolkit::Control::KeyboardFocus::UP:
+        {
+          index = Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID;
+          break;
+        }
+        case Toolkit::Control::KeyboardFocus::DOWN:
+        {
+          index = Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID;
+          break;
+        }
+        default:
+          break;
+      }
+
+      // If the focusable property is set then determine next focusable actor
+      if( index != Property::INVALID_INDEX)
+      {
+        value = currentFocusActor.GetProperty( index );
+        actorId = value.Get<int>();
+
+        // If actor's id is valid then find actor form actor's id. The actor should be on the stage.
+        if( actorId != -1 )
+        {
+          if( currentFocusActor.GetParent() )
+          {
+            nextFocusableActor = currentFocusActor.GetParent().FindChildById( actorId );
+          }
 
-    if ( nextFocusableActor && nextFocusableActor.IsKeyboardFocusable() )
+          if( !nextFocusableActor )
+          {
+            nextFocusableActor = Stage::GetCurrent().GetRootLayer().FindChildById( actorId );
+          }
+        }
+      }
+    }
+
+    if( !nextFocusableActor )
+    {
+      // If the implementation of CustomAlgorithmInterface is provided then the PreFocusChangeSignal is no longer emitted.
+      if( mCustomAlgorithmInterface )
+      {
+        mIsWaitingKeyboardFocusChangeCommit = true;
+        nextFocusableActor = mCustomAlgorithmInterface->GetNextFocusableActor( currentFocusActor, Actor(), direction );
+        mIsWaitingKeyboardFocusChangeCommit = false;
+      }
+      else if( !mPreFocusChangeSignal.Empty() )
+      {
+        // Don't know how to move the focus further. The application needs to tell us which actor to move the focus to
+        mIsWaitingKeyboardFocusChangeCommit = true;
+        nextFocusableActor = mPreFocusChangeSignal.Emit( currentFocusActor, Actor(), direction );
+        mIsWaitingKeyboardFocusChangeCommit = false;
+      }
+    }
+
+    if( nextFocusableActor && nextFocusableActor.IsKeyboardFocusable() )
     {
       // Whether the next focusable actor is a layout control
-      if(IsLayoutControl(nextFocusableActor))
+      if( IsLayoutControl( nextFocusableActor ) )
       {
         // If so, move the focus inside it.
-        Toolkit::Control layoutControl = Toolkit::Control::DownCast(nextFocusableActor);
-        succeed = DoMoveFocusWithinLayoutControl(layoutControl, currentFocusActor, direction);
+        Toolkit::Control layoutControl = Toolkit::Control::DownCast( nextFocusableActor) ;
+        succeed = DoMoveFocusWithinLayoutControl( layoutControl, currentFocusActor, direction );
       }
       else
       {
         // Otherwise, just set focus to the next focusable actor
-        succeed = SetCurrentFocusActor(nextFocusableActor);
+        succeed = SetCurrentFocusActor( nextFocusableActor );
       }
     }
   }
@@ -798,6 +872,11 @@ bool KeyboardFocusManager::DoConnectSignal( BaseObject* object, ConnectionTracke
   return connected;
 }
 
+void KeyboardFocusManager::SetCustomAlgorithm(CustomAlgorithmInterface& interface)
+{
+  mCustomAlgorithmInterface = &interface;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 468687a..6816200 100644 (file)
@@ -23,6 +23,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
+#include <dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h>
 
 namespace Dali
 {
@@ -40,6 +41,8 @@ class KeyboardFocusManager : public Dali::BaseObject
 {
 public:
 
+  typedef Toolkit::DevelKeyboardFocusManager::CustomAlgorithmInterface CustomAlgorithmInterface;
+
   /**
    * @copydoc Toolkit::KeyboardFocusManager::Get
    */
@@ -110,6 +113,11 @@ public:
    */
   void MoveFocusBackward();
 
+  /**
+   * @copydoc Toolkit::DevelKeyboardFocusManager::SetCustomAlgorithm
+   */
+  void SetCustomAlgorithm(CustomAlgorithmInterface& interface);
+
 public:
 
   /**
@@ -254,6 +262,8 @@ private:
 
   SlotDelegate< KeyboardFocusManager > mSlotDelegate;
 
+  CustomAlgorithmInterface* mCustomAlgorithmInterface; ///< The user's (application / toolkit) implementation of CustomAlgorithmInterface
+
 };
 
 } // namespace Internal
index 55f40e9..b79430a 100644 (file)
@@ -1751,7 +1751,8 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
 {
   DALI_ASSERT_DEBUG( mImpl->mEventData && "Unexpected KeyEvent" );
 
-  bool textChanged( false );
+  bool textChanged = false;
+  bool relayoutNeeded = false;
 
   if( ( NULL != mImpl->mEventData ) &&
       ( keyEvent.state == KeyEvent::Down ) )
@@ -1771,6 +1772,9 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
     {
       // Escape key is a special case which causes focus loss
       KeyboardFocusLostEvent();
+
+      // Will request for relayout.
+      relayoutNeeded = true;
     }
     else if( ( Dali::DALI_KEY_CURSOR_LEFT  == keyCode ) ||
              ( Dali::DALI_KEY_CURSOR_RIGHT == keyCode ) ||
@@ -1803,10 +1807,16 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
       Event event( Event::CURSOR_KEY_EVENT );
       event.p1.mInt = keyCode;
       mImpl->mEventData->mEventQueue.push_back( event );
+
+      // Will request for relayout.
+      relayoutNeeded = true;
     }
     else if( Dali::DALI_KEY_BACKSPACE == keyCode )
     {
       textChanged = BackspaceKeyEvent();
+
+      // Will request for relayout.
+      relayoutNeeded = true;
     }
     else if( IsKey( keyEvent, Dali::DALI_KEY_POWER ) ||
              IsKey( keyEvent, Dali::DALI_KEY_MENU ) ||
@@ -1815,6 +1825,9 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
       // Power key/Menu/Home key behaviour does not allow edit mode to resume.
       mImpl->ChangeState( EventData::INACTIVE );
 
+      // Will request for relayout.
+      relayoutNeeded = true;
+
       // This branch avoids calling the InsertText() method of the 'else' branch which can delete selected text.
     }
     else if( Dali::DALI_KEY_SHIFT_LEFT == keyCode )
@@ -1824,6 +1837,11 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
 
       // Do nothing.
     }
+    else if( ( Dali::DALI_KEY_VOLUME_UP == keyCode ) || ( Dali::DALI_KEY_VOLUME_DOWN == keyCode ) )
+    {
+      // This branch avoids calling the InsertText() method of the 'else' branch which can delete selected text.
+      // Do nothing.
+    }
     else
     {
       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::KeyEvent %p keyString %s\n", this, keyString.c_str() );
@@ -1833,20 +1851,31 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
 
       InsertText( keyString, COMMIT );
       textChanged = true;
+
+      // Will request for relayout.
+      relayoutNeeded = true;
     }
 
     if ( ( mImpl->mEventData->mState != EventData::INTERRUPTED ) &&
          ( mImpl->mEventData->mState != EventData::INACTIVE ) &&
          ( !isNullKey ) &&
-         ( Dali::DALI_KEY_SHIFT_LEFT != keyCode ) )
+         ( Dali::DALI_KEY_SHIFT_LEFT != keyCode ) &&
+         ( Dali::DALI_KEY_VOLUME_UP != keyCode ) &&
+         ( Dali::DALI_KEY_VOLUME_DOWN != keyCode ) )
     {
       // Should not change the state if the key is the shift send by the imf manager.
       // Otherwise, when the state is SELECTING the text controller can't send the right
       // surrounding info to the imf.
       mImpl->ChangeState( EventData::EDITING );
+
+      // Will request for relayout.
+      relayoutNeeded = true;
     }
 
-    mImpl->RequestRelayout();
+    if( relayoutNeeded )
+    {
+      mImpl->RequestRelayout();
+    }
   }
 
   if( textChanged &&
@@ -2276,8 +2305,9 @@ void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Butt
 
 void Controller::InsertText( const std::string& text, Controller::InsertType type )
 {
-  bool removedPrevious( false );
-  bool maxLengthReached( false );
+  bool removedPrevious = false;
+  bool removedSelected = false;
+  bool maxLengthReached = false;
 
   DALI_ASSERT_DEBUG( NULL != mImpl->mEventData && "Unexpected InsertText" )
 
@@ -2293,9 +2323,6 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
   // TODO: At the moment the underline runs are only for pre-edit.
   mImpl->mModel->mVisualModel->mUnderlineRuns.Clear();
 
-  // Keep the current number of characters.
-  const Length currentNumberOfCharacters = mImpl->IsShowingRealText() ? mImpl->mModel->mLogicalModel->mText.Count() : 0u;
-
   // Remove the previous IMF pre-edit.
   if( mImpl->mEventData->mPreEditFlag && ( 0u != mImpl->mEventData->mPreEditLength ) )
   {
@@ -2309,7 +2336,8 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
   else
   {
     // Remove the previous Selection.
-    removedPrevious = RemoveSelectedText();
+    removedSelected = RemoveSelectedText();
+
   }
 
   Vector<Character> utf32Characters;
@@ -2479,8 +2507,6 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Inserted %d characters, new size %d new cursor %d\n", maxSizeOfNewText, mImpl->mModel->mLogicalModel->mText.Count(), mImpl->mEventData->mPrimaryCursorPosition );
   }
 
-  const Length numberOfCharacters = mImpl->IsShowingRealText() ? mImpl->mModel->mLogicalModel->mText.Count() : 0u;
-
   if( ( 0u == mImpl->mModel->mLogicalModel->mText.Count() ) &&
       mImpl->IsPlaceholderAvailable() )
   {
@@ -2490,13 +2516,14 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
     mImpl->ClearPreEditFlag();
   }
   else if( removedPrevious ||
+           removedSelected ||
            ( 0 != utf32Characters.Count() ) )
   {
     // Queue an inserted event
     mImpl->QueueModifyEvent( ModifyEvent::TEXT_INSERTED );
 
     mImpl->mEventData->mUpdateCursorPosition = true;
-    if( numberOfCharacters < currentNumberOfCharacters )
+    if( removedSelected )
     {
       mImpl->mEventData->mScrollAfterDelete = true;
     }
index 0031bc3..217994e 100644 (file)
@@ -54,7 +54,7 @@ const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 
 }
 
-AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl, const Property::Map& properties )
+AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl, const Property::Map& properties )
 {
   AnimatedImageVisual* visual = new AnimatedImageVisual( factoryCache );
   visual->mImageUrl = imageUrl;
@@ -63,7 +63,7 @@ AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCach
   return visual;
 }
 
-AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl )
+AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl )
 {
   AnimatedImageVisual* visual = new AnimatedImageVisual( factoryCache );
   visual->mImageUrl = imageUrl;
@@ -90,7 +90,7 @@ void AnimatedImageVisual::GetNaturalSize( Vector2& naturalSize )
 {
   if( mImageSize.GetWidth() == 0 &&  mImageSize.GetHeight() == 0)
   {
-    mImageSize = Dali::GetGifImageSize( mImageUrl );
+    mImageSize = Dali::GetGifImageSize( mImageUrl.GetUrl() );
   }
 
   naturalSize.width = mImageSize.GetWidth();
@@ -101,11 +101,11 @@ void AnimatedImageVisual::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
 
-  map.Insert( Toolkit::DevelVisual::Property::TYPE, Toolkit::Visual::IMAGE );
+  map.Insert( Toolkit::DevelVisual::Property::TYPE, Toolkit::DevelVisual::ANIMATED_IMAGE );
 
-  if( !mImageUrl.empty() )
+  if( mImageUrl.IsValid() )
   {
-    map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl );
+    map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl.GetUrl() );
   }
 
   map.Insert( Toolkit::ImageVisual::Property::PIXEL_AREA, mPixelArea );
@@ -221,12 +221,16 @@ Texture AnimatedImageVisual::PrepareAnimatedImage()
 {
   // load from image file
   std::vector<Dali::PixelData> pixelDataList;
-  if( Dali::LoadAnimatedGifFromFile( mImageUrl.c_str() , pixelDataList, mFrameDelayContainer ) )
+
+  if( mImageUrl.IsLocal() )
   {
-    mImageSize.SetWidth( pixelDataList[0].GetWidth() );
-    mImageSize.SetHeight( pixelDataList[0].GetHeight() );
+    if( Dali::LoadAnimatedGifFromFile( mImageUrl.GetUrl().c_str() , pixelDataList, mFrameDelayContainer ) )
+    {
+      mImageSize.SetWidth( pixelDataList[0].GetWidth() );
+      mImageSize.SetHeight( pixelDataList[0].GetHeight() );
 
-    return Toolkit::ImageAtlas::PackToAtlas( pixelDataList, mTextureRectContainer );
+      return Toolkit::ImageAtlas::PackToAtlas( pixelDataList, mTextureRectContainer );
+    }
   }
 
   return Texture();
index e89fec6..4e11cce 100644 (file)
@@ -26,6 +26,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
 
 namespace Dali
 {
@@ -77,7 +78,7 @@ public:
    * @param[in] properties A Property::Map containing settings for this visual
    * @return A smart-pointer to the newly allocated visual.
    */
-  static AnimatedImageVisualPtr New( VisualFactoryCache& factoryCache, const std::string& imageUrl, const Property::Map& properties );
+  static AnimatedImageVisualPtr New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl, const Property::Map& properties );
 
   /**
    * @brief Create the animated image visual using the image URL.
@@ -85,7 +86,7 @@ public:
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    * @param[in] imageUrl The URL to animated image resource to use
    */
-  static AnimatedImageVisualPtr New( VisualFactoryCache& factoryCache, const std::string& imageUrl );
+  static AnimatedImageVisualPtr New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl );
 
 public:  // from Visual
 
@@ -163,7 +164,7 @@ private:
   Dali::Vector<Vector4> mTextureRectContainer;
   Dali::Vector<uint32_t> mFrameDelayContainer;
   Vector4 mPixelArea;
-  std::string  mImageUrl;
+  VisualUrl mImageUrl;
 
   ImageDimensions mImageSize;
   uint32_t mCurrentFrameIndex;
index 812e854..49e2c00 100644 (file)
 // CLASS HEADER
 #include <dali-toolkit/internal/visuals/image/image-visual.h>
 
-// EXTERNAL HEADER
-#include <cstring> // for strncasecmp
+// EXTERNAL HEADERS
+#include <cstring> // for strlen()
 #include <dali/public-api/images/resource-image.h>
 #include <dali/public-api/images/native-image.h>
 #include <dali/devel-api/images/texture-set-image.h>
 #include <dali/devel-api/adaptor-framework/bitmap-loader.h>
+#include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/devel-api/scripting/enum-helper.h>
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/integration-api/debug.h>
 
-// INTERNAL HEADER
+// INTERNAL HEADERS
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -37,6 +38,7 @@
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
 
 namespace Dali
 {
@@ -49,8 +51,6 @@ namespace Internal
 
 namespace
 {
-const char HTTP_URL[] = "http://";
-const char HTTPS_URL[] = "https://";
 
 // property names
 const char * const IMAGE_FITTING_MODE( "fittingMode" );
@@ -213,7 +213,7 @@ Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridS
 } // unnamed namespace
 
 ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache,
-                                 const std::string& imageUrl,
+                                 const VisualUrl& imageUrl,
                                  const Property::Map& properties,
                                  ImageDimensions size,
                                  FittingMode::Type fittingMode,
@@ -225,7 +225,7 @@ ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache,
 }
 
 ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache,
-                                 const std::string& imageUrl,
+                                 const VisualUrl& imageUrl,
                                  ImageDimensions size,
                                  FittingMode::Type fittingMode,
                                  Dali::SamplingMode::Type samplingMode )
@@ -239,7 +239,7 @@ ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, const Image&
 }
 
 ImageVisual::ImageVisual( VisualFactoryCache& factoryCache,
-                          const std::string& imageUrl,
+                          const VisualUrl& imageUrl,
                           ImageDimensions size,
                           FittingMode::Type fittingMode,
                           Dali::SamplingMode::Type samplingMode )
@@ -323,7 +323,7 @@ void ImageVisual::DoSetProperties( const Property::Map& propertyMap )
     }
   }
 
-  if( mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING && mImageUrl.size() > 0u )
+  if( mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING && mImageUrl.IsValid() )
   {
     // if sync loading is required, the loading should start
     // immediately when new image url is set or the actor is off stage
@@ -440,9 +440,9 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize )
     naturalSize.y = mDesiredSize.GetHeight();
     return;
   }
-  else if( !mImageUrl.empty() )
+  else if( mImageUrl.IsValid() && mImageUrl.GetLocation() == VisualUrl::LOCAL )
   {
-    ImageDimensions dimentions = ResourceImage::GetImageSize( mImageUrl );
+    ImageDimensions dimentions = Dali::GetClosestImageSize( mImageUrl.GetUrl() );
     naturalSize.x = dimentions.GetWidth();
     naturalSize.y = dimentions.GetHeight();
     return;
@@ -553,15 +553,15 @@ bool ImageVisual::IsSynchronousResourceLoading() const
 
 void ImageVisual::LoadResourceSynchronously()
 {
-  if( !mImageUrl.empty() )
+  if( mImageUrl.IsValid() )
   {
-    BitmapLoader loader = BitmapLoader::New( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode );
+    BitmapLoader loader = BitmapLoader::New( mImageUrl.GetUrl(), mDesiredSize, mFittingMode, mSamplingMode );
     loader.Load();
     mPixels = loader.GetPixelData();
   }
 }
 
-TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading, bool attemptAtlasing )
+TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, bool synchronousLoading, bool attemptAtlasing )
 {
   TextureSet textureSet;
   textureRect = FULL_TEXTURE_RECT;
@@ -595,13 +595,13 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin
   {
     if( attemptAtlasing )
     {
-      textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, url, mDesiredSize, mFittingMode, true, this );
+      textureSet = mFactoryCache.GetAtlasManager()->Add( textureRect, mImageUrl.GetUrl(), mDesiredSize, mFittingMode, true, this );
       mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
     }
     if( !textureSet ) // big image, no atlasing or atlasing failed
     {
       mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
-      ResourceImage resourceImage = Dali::ResourceImage::New( url, mDesiredSize, mFittingMode, mSamplingMode );
+      ResourceImage resourceImage = Dali::ResourceImage::New( mImageUrl.GetUrl(), mDesiredSize, mFittingMode, mSamplingMode );
       resourceImage.LoadingFinishedSignal().Connect( this, &ImageVisual::OnImageLoaded );
       textureSet = TextureSet::New();
       TextureSetImage( textureSet, 0u, resourceImage );
@@ -617,21 +617,18 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin
   return textureSet;
 }
 
-void ImageVisual::InitializeRenderer( const std::string& imageUrl )
+void ImageVisual::InitializeRenderer()
 {
-  mImageUrl = imageUrl;
   mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
 
-  if( !mImpl->mCustomShader &&
-      ( strncasecmp( imageUrl.c_str(), HTTP_URL,  sizeof(HTTP_URL)  -1 ) != 0 ) && // dont atlas remote images
-      ( strncasecmp( imageUrl.c_str(), HTTPS_URL, sizeof(HTTPS_URL) -1 ) != 0 ) )
+  if( !mImpl->mCustomShader && mImageUrl.GetLocation() == VisualUrl::LOCAL )
   {
     bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE;
 
     Vector4 atlasRect;
     // texture set has to be created first as we need to know if atlasing succeeded or not
     // when selecting the shader
-    TextureSet textures = CreateTextureSet( atlasRect, imageUrl, IsSynchronousResourceLoading(), true );
+    TextureSet textures = CreateTextureSet( atlasRect, IsSynchronousResourceLoading(), true );
     CreateRenderer( textures );
 
     if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED ) // the texture is packed inside atlas
@@ -649,7 +646,7 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl )
   {
     // for custom shader or remote image, atlas is not applied
     Vector4 atlasRect; // ignored in this case
-    TextureSet textures = CreateTextureSet( atlasRect, imageUrl, IsSynchronousResourceLoading(), false );
+    TextureSet textures = CreateTextureSet( atlasRect, IsSynchronousResourceLoading(), false );
     CreateRenderer( textures );
   }
 }
@@ -689,9 +686,9 @@ void ImageVisual::UploadCompleted()
 
 void ImageVisual::DoSetOnStage( Actor& actor )
 {
-  if( !mImageUrl.empty() )
+  if( mImageUrl.IsValid() )
   {
-    InitializeRenderer( mImageUrl );
+    InitializeRenderer();
   }
   else if ( mImage )
   {
@@ -723,9 +720,9 @@ void ImageVisual::DoSetOffStage( Actor& actor )
 
   //If we own the image then make sure we release it when we go off stage
   actor.RemoveRenderer( mImpl->mRenderer);
-  if( !mImageUrl.empty() )
+  if( mImageUrl.IsValid() )
   {
-    RemoveFromAtlas(mImageUrl);
+    RemoveFromAtlas( mImageUrl.GetUrl() );
     mImage.Reset();
   }
 
@@ -740,9 +737,9 @@ void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const
 
   bool sync = IsSynchronousResourceLoading();
   map.Insert( SYNCHRONOUS_LOADING, sync );
-  if( !mImageUrl.empty() )
+  if( mImageUrl.IsValid() )
   {
-    map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl );
+    map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl.GetUrl() );
     map.Insert( Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth() );
     map.Insert( Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight() );
   }
@@ -770,7 +767,7 @@ void ImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
 {
   map.Clear();
   map.Insert( Toolkit::DevelVisual::Property::TYPE, Toolkit::Visual::IMAGE );
-  if( !mImageUrl.empty() )
+  if( mImageUrl.IsValid() )
   {
     map.Insert( Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth() );
     map.Insert( Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight() );
index bf71048..83fd71c 100644 (file)
@@ -26,8 +26,9 @@
 #include <dali/devel-api/object/weak-handle.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/devel-api/image-loader/atlas-upload-observer.h>
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
 
 namespace Dali
 {
@@ -108,7 +109,7 @@ public:
    * @return A smart-pointer to the newly allocated visual.
    */
   static ImageVisualPtr New( VisualFactoryCache& factoryCache,
-                             const std::string& imageUrl,
+                             const VisualUrl& imageUrl,
                              const Property::Map& properties,
                              ImageDimensions size = ImageDimensions(),
                              FittingMode::Type fittingMode = FittingMode::DEFAULT,
@@ -127,7 +128,7 @@ public:
    * @return A smart-pointer to the newly allocated visual.
    */
   static ImageVisualPtr New( VisualFactoryCache& factoryCache,
-                             const std::string& imageUrl,
+                             const VisualUrl& imageUrl,
                              ImageDimensions size = ImageDimensions(),
                              FittingMode::Type fittingMode = FittingMode::DEFAULT,
                              Dali::SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR );
@@ -171,7 +172,7 @@ protected:
    * @param[in] samplingMode The SamplingMode of the resource to load
    */
   ImageVisual( VisualFactoryCache& factoryCache,
-               const std::string& imageUrl,
+               const VisualUrl& imageUrl,
                ImageDimensions size,
                FittingMode::Type fittingMode,
                Dali::SamplingMode::Type samplingMode );
@@ -237,11 +238,9 @@ private:
   void ApplyImageToSampler( const Image& image );
 
   /**
-   * @brief Initializes the Dali::Renderer from an image url string
-   *
-   * @param[in] imageUrl The image url string to intialize this ImageVisual from
+   * @brief Initializes the Dali::Renderer from the image url
    */
-  void InitializeRenderer( const std::string& imageUrl );
+  void InitializeRenderer();
 
   /**
    * @brief Initializes the Dali::Renderer from an image handle
@@ -281,7 +280,7 @@ private:
    * @param[in] attemptAtlasing If true will attempt atlasing, otherwise create unique texture
    * @return the texture set to use
    */
-  TextureSet CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading, bool attemptAtlasing );
+  TextureSet CreateTextureSet( Vector4& textureRect, bool synchronousLoading, bool attemptAtlasing );
 
   /**
    * Callback function of image resource loading succeed
@@ -313,7 +312,7 @@ private:
   PixelData mPixels;
   Vector4 mPixelArea;
   WeakHandle<Actor> mPlacementActor;
-  std::string mImageUrl;
+  VisualUrl mImageUrl;
 
   Dali::ImageDimensions mDesiredSize;
   Dali::FittingMode::Type mFittingMode:3;
index 6e3c8ec..5da7bd1 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL HEADER
 #include <dali/devel-api/common/hash.h>
 #include <dali/devel-api/images/texture-set-image.h>
+#include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
 
 namespace Dali
 {
@@ -39,7 +40,7 @@ NPatchLoader::~NPatchLoader()
 {
 }
 
-std::size_t NPatchLoader::Load( const std::string& url )
+std::size_t NPatchLoader::Load( const std::string& url, const Rect< int >& border )
 {
   std::size_t hash = CalculateHash( url );
   OwnerContainer< Data* >::SizeType index = UNINITIALIZED_ID;
@@ -56,26 +57,62 @@ std::size_t NPatchLoader::Load( const std::string& url )
     }
   }
   // got to the end so no match, decode N patch and append new item to cache
-  NinePatchImage ninePatch = NinePatchImage::New( url );
-  if( ninePatch )
+  if( border == Rect< int >( 0, 0, 0, 0 ) )
   {
-    BufferImage croppedImage = ninePatch.CreateCroppedBufferImage();
-    if( croppedImage )
+    NinePatchImage ninePatch = NinePatchImage::New( url );
+    if( ninePatch )
+    {
+      BufferImage croppedImage = ninePatch.CreateCroppedBufferImage();
+      if( croppedImage )
+      {
+        Data* data = new Data();
+        data->hash = hash;
+        data->url = url;
+        data->textureSet = TextureSet::New();
+        TextureSetImage( data->textureSet, 0u, croppedImage );
+        data->croppedWidth = croppedImage.GetWidth();
+        data->croppedHeight = croppedImage.GetHeight();
+        data->stretchPixelsX = ninePatch.GetStretchPixelsX();
+        data->stretchPixelsY = ninePatch.GetStretchPixelsY();
+        mCache.PushBack( data );
+
+        return mCache.Count(); // valid ids start from 1u
+      }
+    }
+  }
+  else
+  {
+    // Load image from file
+    PixelData pixels = SyncImageLoader::Load( url );
+    if( pixels )
     {
       Data* data = new Data();
       data->hash = hash;
       data->url = url;
+      data->croppedWidth = pixels.GetWidth();
+      data->croppedHeight = pixels.GetHeight();
+
+      Texture texture = Texture::New( TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight() );
+      texture.Upload( pixels, 0, 0, 0, 0, pixels.GetWidth(), pixels.GetHeight() );
+
       data->textureSet = TextureSet::New();
-      TextureSetImage( data->textureSet, 0u, croppedImage );
-      data->croppedWidth = croppedImage.GetWidth();
-      data->croppedHeight = croppedImage.GetHeight();
-      data->stretchPixelsX = ninePatch.GetStretchPixelsX();
-      data->stretchPixelsY = ninePatch.GetStretchPixelsY();
+      data->textureSet.SetTexture( 0u, texture );
+
+      NinePatchImage::StretchRanges stretchRangesX;
+      stretchRangesX.PushBack( Uint16Pair( border.left, data->croppedWidth - border.right ) );
+
+      NinePatchImage::StretchRanges stretchRangesY;
+      stretchRangesY.PushBack( Uint16Pair( border.top, data->croppedHeight - border.bottom ) );
+
+      data->stretchPixelsX = stretchRangesX;
+      data->stretchPixelsY = stretchRangesY;
+
       mCache.PushBack( data );
 
       return mCache.Count(); // valid ids start from 1u
     }
   }
+
   return 0u;
 }
 
index 0d9a1c2..61ec60d 100644 (file)
@@ -80,9 +80,10 @@ public:
    * @brief Retrieve a texture matching the n-patch url.
    *
    * @param [in] url to retrieve
+   * @param [in] border The border size of the image
    * @return id of the texture.
    */
-  std::size_t Load( const std::string& url );
+  std::size_t Load( const std::string& url, const Rect< int >& border );
 
   /**
    * @brief Retrieve N patch data matching to an id
index 31e6344..36700fe 100644 (file)
@@ -27,6 +27,7 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/internal/visuals/npatch-loader.h>
 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
@@ -46,7 +47,8 @@ namespace Internal
 
 namespace
 {
-const char * const BORDER_ONLY("borderOnly");
+const char * const BORDER_ONLY( "borderOnly" );
+const char * const BORDER( "border" );
 
 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
@@ -232,7 +234,7 @@ void RegisterStretchProperties( Renderer& renderer, const char * uniformName, co
 
 /////////////////NPatchVisual////////////////
 
-NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl, const Property::Map& properties )
+NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl, const Property::Map& properties )
 {
   NPatchVisualPtr nPatchVisual( new NPatchVisual( factoryCache ) );
   nPatchVisual->mImageUrl = imageUrl;
@@ -241,7 +243,7 @@ NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, const std::
   return nPatchVisual;
 }
 
-NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl )
+NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl )
 {
   NPatchVisualPtr nPatchVisual( new NPatchVisual( factoryCache ) );
   nPatchVisual->mImageUrl = imageUrl;
@@ -252,8 +254,8 @@ NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, const std::
 NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, NinePatchImage image )
 {
   NPatchVisualPtr nPatchVisual( new NPatchVisual( factoryCache ) );
-  nPatchVisual->mImageUrl = image.GetUrl();
-
+  VisualUrl visualUrl( image.GetUrl() );
+  nPatchVisual->mImageUrl = visualUrl;
   return nPatchVisual;
 }
 
@@ -261,10 +263,11 @@ void NPatchVisual::GetNaturalSize( Vector2& naturalSize )
 {
   naturalSize.x = 0u;
   naturalSize.y = 0u;
+
   // load now if not already loaded
-  if( NPatchLoader::UNINITIALIZED_ID == mId )
+  if( NPatchLoader::UNINITIALIZED_ID == mId && mImageUrl.IsLocal() )
   {
-    mId = mLoader.Load( mImageUrl );
+    mId = mLoader.Load( mImageUrl.GetUrl(), mBorder );
   }
   const NPatchLoader::Data* data;
   if( mLoader.GetNPatchData( mId, data ) )
@@ -283,14 +286,28 @@ void NPatchVisual::DoSetProperties( const Property::Map& propertyMap )
   {
     borderOnlyValue->Get( mBorderOnly );
   }
+
+  Property::Value* borderValue = propertyMap.Find( Toolkit::DevelImageVisual::Property::BORDER, BORDER );
+  if( borderValue && ! borderValue->Get( mBorder ) ) // If value exists and is rect, just set mBorder
+  {
+    // Not a rect so try vector4
+    Vector4 border;
+    if( borderValue->Get( border ) )
+    {
+      mBorder.left = static_cast< int >( border.x );
+      mBorder.right = static_cast< int >( border.y );
+      mBorder.bottom = static_cast< int >( border.z );
+      mBorder.top = static_cast< int >( border.w );
+    }
+  }
 }
 
 void NPatchVisual::DoSetOnStage( Actor& actor )
 {
   // load when first go on stage
-  if( NPatchLoader::UNINITIALIZED_ID == mId )
+  if( NPatchLoader::UNINITIALIZED_ID == mId && mImageUrl.IsLocal() )
   {
-    mId = mLoader.Load( mImageUrl );
+    mId = mLoader.Load( mImageUrl.GetUrl(), mBorder );
   }
 
   Geometry geometry = CreateGeometry();
@@ -319,9 +336,10 @@ void NPatchVisual::OnSetTransform()
 void NPatchVisual::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
-  map.Insert( Toolkit::DevelVisual::Property::TYPE, Toolkit::Visual::IMAGE );
-  map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl );
+  map.Insert( Toolkit::DevelVisual::Property::TYPE, Toolkit::DevelVisual::N_PATCH );
+  map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl.GetUrl() );
   map.Insert( Toolkit::ImageVisual::Property::BORDER_ONLY, mBorderOnly );
+  map.Insert( Toolkit::DevelImageVisual::Property::BORDER, mBorder );
 }
 
 void NPatchVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
@@ -334,7 +352,8 @@ NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache )
   mLoader( factoryCache.GetNPatchLoader() ),
   mImageUrl(),
   mId( NPatchLoader::UNINITIALIZED_ID ),
-  mBorderOnly( false )
+  mBorderOnly( false ),
+  mBorder()
 {
 }
 
@@ -473,7 +492,7 @@ void NPatchVisual::ApplyTextureAndUniforms()
   }
   else
   {
-    DALI_LOG_ERROR("The N patch image '%s' is not a valid N patch image\n", mImageUrl.c_str() );
+    DALI_LOG_ERROR("The N patch image '%s' is not a valid N patch image\n", mImageUrl.GetUrl().c_str() );
     TextureSet textureSet = TextureSet::New();
     mImpl->mRenderer.SetTextures( textureSet );
     Image croppedImage = VisualFactoryCache::GetBrokenVisualImage();
index 22b60d5..901211d 100644 (file)
@@ -29,6 +29,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
 
 namespace Dali
 {
@@ -50,7 +51,8 @@ typedef IntrusivePtr< NPatchVisual > NPatchVisualPtr;
  * | %Property Name           | Type             |
  * |--------------------------|------------------|
  * | url                      | STRING           |
- * | borderOnly               | BOOLEAN
+ * | borderOnly               | BOOLEAN          |
+ * | border                   | RECTANGLE        |
  *
  */
 class NPatchVisual: public Visual::Base
@@ -67,7 +69,7 @@ public:
    * @param[in] properties A Property::Map containing settings for this visual
    * @return A smart-pointer to the newly allocated visual.
    */
-  static NPatchVisualPtr New( VisualFactoryCache& factoryCache, const std::string& imageUrl, const Property::Map& properties );
+  static NPatchVisualPtr New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl, const Property::Map& properties );
 
   /**
    * @brief Create an N-patch visual using an image URL.
@@ -78,7 +80,7 @@ public:
    * @param[in] imageUrl The URL to 9 patch image resource to use
    * @return A smart-pointer to the newly allocated visual.
    */
-  static NPatchVisualPtr New( VisualFactoryCache& factoryCache, const std::string& imageUrl );
+  static NPatchVisualPtr New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl );
 
   /**
    * @brief Create an N-patch visual with a NinePatchImage resource.
@@ -201,10 +203,10 @@ private:
 private:
 
   NPatchLoader& mLoader;      ///< reference to N patch loader for fast access
-  std::string mImageUrl;      ///< The url to the N patch to load
+  VisualUrl mImageUrl;        ///< The url to the N patch to load
   std::size_t mId;            ///< id of the N patch (from loader/cache)
   bool mBorderOnly;           ///< if only border is desired
-
+  Rect< int > mBorder;        ///< The size of the border
 };
 
 } // namespace Internal
index 73d29e0..7fc1cf2 100644 (file)
@@ -53,7 +53,7 @@ namespace Toolkit
 namespace Internal
 {
 
-SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl, const Property::Map& properties )
+SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl, const Property::Map& properties )
 {
   SvgVisualPtr svgVisual( new SvgVisual( factoryCache ) );
   svgVisual->ParseFromUrl( imageUrl );
@@ -62,7 +62,7 @@ SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, const std::string
   return svgVisual;
 }
 
-SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl )
+SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl )
 {
   SvgVisualPtr svgVisual( new SvgVisual( factoryCache ) );
   svgVisual->ParseFromUrl( imageUrl );
@@ -73,7 +73,7 @@ SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, const std::string
 SvgVisual::SvgVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
   mAtlasRect( FULL_TEXTURE_RECT ),
-  mImageUrl(),
+  mImageUrl( ),
   mParsedImage( NULL ),
   mPlacementActor(),
   mVisualSize(Vector2::ZERO)
@@ -137,10 +137,10 @@ void SvgVisual::GetNaturalSize( Vector2& naturalSize )
 void SvgVisual::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
-  map.Insert( Toolkit::DevelVisual::Property::TYPE, Toolkit::Visual::IMAGE );
-  if( !mImageUrl.empty() )
+  map.Insert( Toolkit::DevelVisual::Property::TYPE, Toolkit::DevelVisual::SVG );
+  if( mImageUrl.IsValid() )
   {
-    map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl );
+    map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl.GetUrl() );
   }
 }
 
@@ -149,13 +149,15 @@ void SvgVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
   // Do nothing
 }
 
-void SvgVisual::ParseFromUrl( const std::string& imageUrl )
+void SvgVisual::ParseFromUrl( const VisualUrl& imageUrl )
 {
   mImageUrl = imageUrl;
-
-  Vector2 dpi = Stage::GetCurrent().GetDpi();
-  float meanDpi = (dpi.height + dpi.width) * 0.5f;
-  mParsedImage = nsvgParseFromFile( imageUrl.c_str(), UNITS, meanDpi );
+  if( mImageUrl.IsLocal() )
+  {
+    Vector2 dpi = Stage::GetCurrent().GetDpi();
+    float meanDpi = (dpi.height + dpi.width) * 0.5f;
+    mParsedImage = nsvgParseFromFile( mImageUrl.GetUrl().c_str(), UNITS, meanDpi );
+  }
 }
 
 void SvgVisual::AddRasterizationTask( const Vector2& size )
index 3369901..0d5dcf8 100644 (file)
@@ -24,6 +24,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
 
 struct NSVGimage;
 
@@ -64,7 +65,7 @@ public:
    * @param[in] properties A Property::Map containing settings for this visual
    * @return A smart-pointer to the newly allocated visual.
    */
-  static SvgVisualPtr New( VisualFactoryCache& factoryCache, const std::string& imageUrl, const Property::Map& properties );
+  static SvgVisualPtr New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl, const Property::Map& properties );
 
   /**
    * @brief Create the SVG Visual using the image URL.
@@ -76,7 +77,7 @@ public:
    * @param[in] imageUrl The URL to svg resource to use
    * @return A smart-pointer to the newly allocated visual.
    */
-  static SvgVisualPtr New( VisualFactoryCache& factoryCache, const std::string& imageUrl );
+  static SvgVisualPtr New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl );
 
 public:  // from Visual
 
@@ -145,7 +146,7 @@ private:
    *
    * @param[in] imageUrl The URL of the image to parse the SVG from.
    */
-  void ParseFromUrl( const std::string& imageUrl );
+  void ParseFromUrl( const VisualUrl& imageUrl );
 
   /**
    * @bried Rasterize the svg with the given size, and add it to the visual.
@@ -163,7 +164,7 @@ private:
 
 private:
   Vector4              mAtlasRect;
-  std::string          mImageUrl;
+  VisualUrl            mImageUrl;
   NSVGimage*           mParsedImage;
   WeakHandle<Actor>    mPlacementActor;
   Vector2              mVisualSize;
index 19c2c74..f79afe6 100644 (file)
@@ -59,6 +59,11 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Align, BOTTOM_CENTER )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Align, BOTTOM_END )
 DALI_ENUM_TO_STRING_TABLE_END( ALIGN )
 
+DALI_ENUM_TO_STRING_TABLE_BEGIN( POLICY )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelVisual::Transform::Policy, RELATIVE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelVisual::Transform::Policy, ABSOLUTE )
+DALI_ENUM_TO_STRING_TABLE_END( POLICY )
+
 Dali::Vector2 PointToVector2( Toolkit::Align::Type point, Toolkit::Direction::Type direction )
 {
   static const float pointToVector2[] = { 0.0f,0.0f,
@@ -80,6 +85,33 @@ Dali::Vector2 PointToVector2( Toolkit::Align::Type point, Toolkit::Direction::Ty
   return result;
 }
 
+bool GetPolicyFromValue( const Property::Value& value, Vector2& policy )
+{
+  bool success = false;
+  if( value.Get( policy ) )
+  {
+    success = true;
+  }
+  else
+  {
+    Property::Array* array = value.GetArray();
+    if( array && array->Size() == 2 )
+    {
+      DevelVisual::Transform::Policy::Type xPolicy = static_cast< DevelVisual::Transform::Policy::Type >( -1 ); // Assign an invalid value so definitely changes
+      DevelVisual::Transform::Policy::Type yPolicy = static_cast< DevelVisual::Transform::Policy::Type >( -1 ); // Assign an invalid value so definitely changes
+
+      if( Scripting::GetEnumerationProperty< DevelVisual::Transform::Policy::Type >( array->GetElementAt( 0 ), POLICY_TABLE, POLICY_TABLE_COUNT, xPolicy ) &&
+          Scripting::GetEnumerationProperty< DevelVisual::Transform::Policy::Type >( array->GetElementAt( 1 ), POLICY_TABLE, POLICY_TABLE_COUNT, yPolicy ) )
+      {
+        policy.x = xPolicy;
+        policy.y = yPolicy;
+        success = true;
+      }
+    }
+  }
+  return success;
+}
+
 } // unnamed namespace
 
 Internal::Visual::Base::Impl::Impl()
@@ -253,9 +285,24 @@ void Internal::Visual::Base::Impl::Transform::UpdatePropertyMap( const Property:
           Scripting::GetEnumerationProperty< Toolkit::Align::Type >( keyValue.second, ALIGN_TABLE, ALIGN_TABLE_COUNT, mAnchorPoint );
           break;
         }
-        case Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE:
+        case Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY:
+        {
+          Vector2 policy;
+          if( GetPolicyFromValue( keyValue.second, policy ) )
+          {
+            mOffsetSizeMode.x = policy.x;
+            mOffsetSizeMode.y = policy.y;
+          }
+          break;
+        }
+        case Toolkit::DevelVisual::Transform::Property::SIZE_POLICY:
         {
-          keyValue.second.Get( mOffsetSizeMode );
+          Vector2 policy;
+          if( GetPolicyFromValue( keyValue.second, policy ) )
+          {
+            mOffsetSizeMode.z = policy.x;
+            mOffsetSizeMode.w = policy.y;
+          }
           break;
         }
       }
@@ -272,23 +319,29 @@ void Internal::Visual::Base::Impl::Transform::UpdatePropertyMap( const Property:
       }
       else if( keyValue.first == "origin" )
       {
-        Toolkit::Align::Type align(Toolkit::Align::CENTER);
-        if( Scripting::GetEnumerationProperty< Toolkit::Align::Type >( keyValue.second, ALIGN_TABLE, ALIGN_TABLE_COUNT, align ) )
-        {
-          mOrigin = align;
-        }
+        Scripting::GetEnumerationProperty< Toolkit::Align::Type >( keyValue.second, ALIGN_TABLE, ALIGN_TABLE_COUNT, mOrigin );
       }
       else if( keyValue.first == "anchorPoint" )
       {
-        Toolkit::Align::Type align(Toolkit::Align::CENTER);
-        if( Scripting::GetEnumerationProperty< Toolkit::Align::Type >( keyValue.second, ALIGN_TABLE, ALIGN_TABLE_COUNT, align ) )
+        Scripting::GetEnumerationProperty< Toolkit::Align::Type >( keyValue.second, ALIGN_TABLE, ALIGN_TABLE_COUNT, mAnchorPoint );
+      }
+      else if( keyValue.first == "offsetPolicy" )
+      {
+        Vector2 policy;
+        if( GetPolicyFromValue( keyValue.second, policy ) )
         {
-          mAnchorPoint = align;
+          mOffsetSizeMode.x = policy.x;
+          mOffsetSizeMode.y = policy.y;
         }
       }
-      else if( keyValue.first == "offsetSizeMode" )
+      else if( keyValue.first == "sizePolicy" )
       {
-        keyValue.second.Get( mOffsetSizeMode );
+        Vector2 policy;
+        if( GetPolicyFromValue( keyValue.second, policy ) )
+        {
+          mOffsetSizeMode.z = policy.x;
+          mOffsetSizeMode.w = policy.y;
+        }
       }
     }
   }
@@ -301,7 +354,8 @@ void Internal::Visual::Base::Impl::Transform::GetPropertyMap( Property::Map& map
      .Add( Toolkit::DevelVisual::Transform::Property::SIZE, mSize )
      .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, mOrigin )
      .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, mAnchorPoint )
-     .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, mOffsetSizeMode );
+     .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( mOffsetSizeMode.x, mOffsetSizeMode.y ) )
+     .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( mOffsetSizeMode.z, mOffsetSizeMode.w ) );
 }
 
 void Internal::Visual::Base::Impl::Transform::RegisterUniforms( Dali::Renderer renderer, Toolkit::Direction::Type direction )
index 909cfcc..8a5d245 100644 (file)
@@ -27,6 +27,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/internal/visuals/border/border-visual.h>
@@ -41,7 +42,7 @@
 #include <dali-toolkit/internal/visuals/animated-image/animated-image-visual.h>
 #include <dali-toolkit/internal/visuals/wireframe/wireframe-visual.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
-#include <dali-toolkit/internal/visuals/visual-factory-resolve-url.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
 
 namespace Dali
@@ -120,26 +121,32 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
       std::string imageUrl;
       if( imageURLValue && imageURLValue->Get( imageUrl ) )
       {
-        // first resolve url type to know which visual to create
-        UrlType::Type type = ResolveUrlType( imageUrl );
-        if( UrlType::N_PATCH == type )
-        {
-          visualPtr = NPatchVisual::New( *( mFactoryCache.Get() ), imageUrl, propertyMap );
-        }
-        else if( UrlType::SVG == type )
-        {
-          visualPtr = SvgVisual::New( *( mFactoryCache.Get() ), imageUrl, propertyMap );
-        }
-        else if( UrlType::GIF == type )
-        {
-          visualPtr = AnimatedImageVisual::New( *( mFactoryCache.Get() ), imageUrl, propertyMap );
-        }
-        else // Regular image
+        VisualUrl visualUrl( imageUrl );
+
+        switch( visualUrl.GetType() )
         {
-          visualPtr = ImageVisual::New( *( mFactoryCache.Get() ), imageUrl, propertyMap );
+          case VisualUrl::N_PATCH:
+          {
+            visualPtr = NPatchVisual::New( *( mFactoryCache.Get() ), visualUrl, propertyMap );
+            break;
+          }
+          case VisualUrl::SVG:
+          {
+            visualPtr = SvgVisual::New( *( mFactoryCache.Get() ), visualUrl, propertyMap );
+            break;
+          }
+          case VisualUrl::GIF:
+          {
+            visualPtr = AnimatedImageVisual::New( *( mFactoryCache.Get() ), visualUrl, propertyMap );
+            break;
+          }
+          case VisualUrl::REGULAR_IMAGE:
+          {
+            visualPtr = ImageVisual::New( *( mFactoryCache.Get() ), visualUrl, propertyMap );
+            break;
+          }
         }
       }
-
       break;
     }
 
@@ -166,6 +173,39 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
       visualPtr = TextVisual::New( *( mFactoryCache.Get() ), propertyMap );
       break;
     }
+
+    case Toolkit::DevelVisual::N_PATCH:
+    {
+      Property::Value* imageURLValue = propertyMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME );
+      std::string imageUrl;
+      if( imageURLValue && imageURLValue->Get( imageUrl ) )
+      {
+        visualPtr = NPatchVisual::New( *( mFactoryCache.Get() ), imageUrl, propertyMap );
+      }
+      break;
+    }
+
+    case Toolkit::DevelVisual::SVG:
+    {
+      Property::Value* imageURLValue = propertyMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME );
+      std::string imageUrl;
+      if( imageURLValue && imageURLValue->Get( imageUrl ) )
+      {
+        visualPtr = SvgVisual::New( *( mFactoryCache.Get() ), imageUrl, propertyMap );
+      }
+      break;
+    }
+
+    case Toolkit::DevelVisual::ANIMATED_IMAGE:
+    {
+      Property::Value* imageURLValue = propertyMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME );
+      std::string imageUrl;
+      if( imageURLValue && imageURLValue->Get( imageUrl ) )
+      {
+        visualPtr = AnimatedImageVisual::New( *( mFactoryCache.Get() ), imageUrl, propertyMap );
+      }
+      break;
+    }
   }
 
   if( !visualPtr )
@@ -220,22 +260,29 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const std::string& url, Image
   Visual::BasePtr visualPtr;
 
   // first resolve url type to know which visual to create
-  UrlType::Type type = ResolveUrlType( url );
-  if( UrlType::N_PATCH == type )
-  {
-    visualPtr = NPatchVisual::New( *( mFactoryCache.Get() ), url );
-  }
-  else if( UrlType::SVG == type )
-  {
-    visualPtr = SvgVisual::New( *( mFactoryCache.Get() ), url );
-  }
-  else if( UrlType::GIF == type )
-  {
-    visualPtr = AnimatedImageVisual::New( *( mFactoryCache.Get() ), url );
-  }
-  else // Regular image
+  VisualUrl visualUrl( url );
+  switch( visualUrl.GetType() )
   {
-    visualPtr = ImageVisual::New( *( mFactoryCache.Get() ), url, size );
+    case VisualUrl::N_PATCH:
+    {
+      visualPtr = NPatchVisual::New( *( mFactoryCache.Get() ), visualUrl );
+      break;
+    }
+    case VisualUrl::SVG:
+    {
+      visualPtr = SvgVisual::New( *( mFactoryCache.Get() ), visualUrl );
+      break;
+    }
+    case VisualUrl::GIF:
+    {
+      visualPtr = AnimatedImageVisual::New( *( mFactoryCache.Get() ), visualUrl );
+      break;
+    }
+    case VisualUrl::REGULAR_IMAGE:
+    {
+      visualPtr = ImageVisual::New( *( mFactoryCache.Get() ), visualUrl, size );
+      break;
+    }
   }
 
   if( mDebugEnabled )
diff --git a/dali-toolkit/internal/visuals/visual-factory-resolve-url.h b/dali-toolkit/internal/visuals/visual-factory-resolve-url.h
deleted file mode 100644 (file)
index 2c1c45b..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-#ifndef DALI_TOOLKIT_VISUAL_FACTORY_URL_RESOLVE_H
-#define DALI_TOOLKIT_VISUAL_FACTORY_URL_RESOLVE_H
-
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <ctype.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace UrlType
-{
-  /**
-   * The type of the URL based on the string contents
-   */
-  enum Type
-  {
-    REGULAR_IMAGE,
-    N_PATCH,
-    SVG,
-    GIF
-  };
-}
-
-/**
- * Helper to resolve URL type from the string
- * @param[in] url to check
- * @return UrlType
- */
-inline UrlType::Type ResolveUrlType( const std::string& url )
-{
-  // if only one char in string, can only be regular image
-  const std::size_t count = url.size();
-  if( count > 0 )
-  {
-    // parsing from the end for better chance of early outs
-    enum { SUFFIX, HASH, HASH_DOT } state = SUFFIX;
-    char SVG[ 4 ] = { 'g', 'v', 's', '.' };
-    char GIF[ 4 ] = { 'f', 'i', 'g', '.' };
-    unsigned int svgScore = 0;
-    unsigned int gifScore = 0;
-    int index = count;
-    while( --index >= 0 )
-    {
-      const char currentChar = url[ index ];
-      const std::size_t offsetFromEnd = count - index - 1u;
-      if( ( offsetFromEnd < sizeof(SVG) )&&( tolower( currentChar ) == SVG[ offsetFromEnd ] ) )
-      {
-        // early out if SVG as can't be used in N patch for now
-        if( ++svgScore == sizeof(SVG) )
-        {
-          return UrlType::SVG;
-        }
-      }
-      if( ( offsetFromEnd < sizeof(GIF) )&&( tolower( currentChar ) == GIF[ offsetFromEnd ] ) )
-      {
-        // early out if GIF
-        if( ++gifScore == sizeof(GIF) )
-        {
-          return UrlType::GIF;
-        }
-      }
-      switch( state )
-      {
-        case SUFFIX:
-        {
-          if( '.' == currentChar )
-          {
-            state = HASH;
-          }
-          break;
-        }
-        case HASH:
-        {
-          if( ( '#' == currentChar ) || ( '9' == currentChar ) )
-          {
-            state = HASH_DOT;
-          }
-          else
-          {
-            // early out, not a valid N/9-patch URL
-            return UrlType::REGULAR_IMAGE;
-          }
-          break;
-        }
-        case HASH_DOT:
-        {
-          if( '.' == currentChar )
-          {
-            return UrlType::N_PATCH;
-          }
-          else
-          {
-            // early out, not a valid N/9-patch URL
-            return UrlType::REGULAR_IMAGE;
-          }
-          break;
-        }
-      }
-    }
-  }
-  // if we got here it is a regular image
-  return UrlType::REGULAR_IMAGE;
-}
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif /* DALI_TOOLKIT_VISUAL_FACTORY_URL_RESOLVE_H */
index c57a8cf..a7a3e2c 100644 (file)
@@ -39,6 +39,9 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, IMAGE )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, MESH )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, PRIMITIVE )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelVisual, TEXT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelVisual, N_PATCH )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelVisual, SVG )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelVisual, ANIMATED_IMAGE )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, WIREFRAME )
 DALI_ENUM_TO_STRING_TABLE_END( VISUAL_TYPE )
 
@@ -75,6 +78,7 @@ const char * const PIXEL_AREA_UNIFORM_NAME( "pixelArea" );
 const char * const WRAP_MODE_UNIFORM_NAME( "wrapMode" );
 const char * const IMAGE_WRAP_MODE_U("wrapModeU");
 const char * const IMAGE_WRAP_MODE_V("wrapModeV");
+const char * const IMAGE_BORDER( "border" );
 
 // Text visual
 const char * const TEXT_PROPERTY( "text" );
index 1a8df73..9817b7a 100644 (file)
@@ -65,6 +65,7 @@ extern const char * const PIXEL_AREA_UNIFORM_NAME;
 extern const char * const WRAP_MODE_UNIFORM_NAME;
 extern const char * const IMAGE_WRAP_MODE_U;
 extern const char * const IMAGE_WRAP_MODE_V;
+extern const char * const IMAGE_BORDER;
 
 // Text visual
 extern const char * const TEXT_PROPERTY;
diff --git a/dali-toolkit/internal/visuals/visual-url.cpp b/dali-toolkit/internal/visuals/visual-url.cpp
new file mode 100644 (file)
index 0000000..c3c675d
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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/visuals/visual-url.h>
+
+// EXTERNAL HEADERS
+#include <cstring> // for toupper()
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+namespace
+{
+
+VisualUrl::Location ResolveLocation( const std::string& url)
+{
+  const char FTP[] = { 'f', 't', 'p', ':', '/', '/' };
+  const char SSH[] = { 's', 's', 'h', ':', '/', '/' };
+  const char HTTP[] = { 'h', 't', 't', 'p', ':', '/', '/' };
+  const char HTTPS[] = { 'h', 't', 't', 'p', 's', ':', '/', '/' };
+
+  const int MATCH_FTP = 0x01;
+  const int MATCH_SSH = 0x02;
+  const int MATCH_HTTP = 0x04;
+  const int MATCH_HTTPS = 0x08;
+
+  const char* urlCStr = url.c_str();
+  if( url.size() > 6 )
+  {
+    if( urlCStr[3] == ':' || urlCStr[4] == ':' || urlCStr[5] == ':' )
+    {
+      int flags = 0x0F;
+      for( unsigned int i=0; i < sizeof(HTTPS); ++i )
+      {
+        char c = tolower( urlCStr[i] );
+        if( i < sizeof(FTP) && (flags & MATCH_FTP) && c != FTP[i] )
+        {
+          flags &= ~MATCH_FTP;
+        }
+        if( i < sizeof(SSH) && (flags & MATCH_SSH) && c != SSH[i] )
+        {
+          flags &= ~MATCH_SSH;
+        }
+        if( i < sizeof(HTTP) && (flags & MATCH_HTTP) && c != HTTP[i] )
+        {
+          flags &= ~MATCH_HTTP;
+        }
+        if( i < sizeof(HTTPS) && (flags & MATCH_HTTPS) && c != HTTPS[i] )
+        {
+          flags &= ~MATCH_HTTPS;
+        }
+
+        if( (flags & (MATCH_FTP | MATCH_SSH | MATCH_HTTP | MATCH_HTTPS )) == 0 )
+        {
+          break;
+        }
+      }
+
+      if( flags )
+      {
+        return VisualUrl::REMOTE;
+      }
+    }
+  }
+  return VisualUrl::LOCAL;
+}
+
+
+VisualUrl::Type ResolveType( const std::string& url )
+{
+  // if only one char in string, can only be regular image
+  const std::size_t count = url.size();
+  if( count > 0 )
+  {
+    // parsing from the end for better chance of early outs
+    enum { SUFFIX, HASH, HASH_DOT } state = SUFFIX;
+    char SVG[ 4 ] = { 'g', 'v', 's', '.' };
+    char GIF[ 4 ] = { 'f', 'i', 'g', '.' };
+    unsigned int svgScore = 0;
+    unsigned int gifScore = 0;
+    int index = count;
+    while( --index >= 0 )
+    {
+      const char currentChar = url[ index ];
+      const std::size_t offsetFromEnd = count - index - 1u;
+      if( ( offsetFromEnd < sizeof(SVG) )&&( tolower( currentChar ) == SVG[ offsetFromEnd ] ) )
+      {
+        // early out if SVG as can't be used in N patch for now
+        if( ++svgScore == sizeof(SVG) )
+        {
+          return VisualUrl::SVG;
+        }
+      }
+      if( ( offsetFromEnd < sizeof(GIF) )&&( tolower( currentChar ) == GIF[ offsetFromEnd ] ) )
+      {
+        // early out if GIF
+        if( ++gifScore == sizeof(GIF) )
+        {
+          return VisualUrl::GIF;
+        }
+      }
+      switch( state )
+      {
+        case SUFFIX:
+        {
+          if( '.' == currentChar )
+          {
+            state = HASH;
+          }
+          break;
+        }
+        case HASH:
+        {
+          if( ( '#' == currentChar ) || ( '9' == currentChar ) )
+          {
+            state = HASH_DOT;
+          }
+          else
+          {
+            // early out, not a valid N/9-patch URL
+            return VisualUrl::REGULAR_IMAGE;
+          }
+          break;
+        }
+        case HASH_DOT:
+        {
+          if( '.' == currentChar )
+          {
+            return VisualUrl::N_PATCH;
+          }
+          else
+          {
+            // early out, not a valid N/9-patch URL
+            return VisualUrl::REGULAR_IMAGE;
+          }
+          break;
+        }
+      }
+    }
+  }
+  // if we got here it is a regular image
+  return VisualUrl::REGULAR_IMAGE;
+}
+
+}
+
+
+VisualUrl::VisualUrl()
+: mUrl(),
+  mType( VisualUrl::REGULAR_IMAGE ),
+  mLocation( VisualUrl::LOCAL )
+{
+}
+
+VisualUrl::VisualUrl( const std::string& url )
+: mUrl( url ),
+  mType( VisualUrl::REGULAR_IMAGE ),
+  mLocation( VisualUrl::LOCAL )
+{
+  if( ! url.empty() )
+  {
+    mLocation = ResolveLocation( url );
+    mType = ResolveType( url );
+  }
+}
+
+VisualUrl::VisualUrl( const VisualUrl& url )
+: mUrl( url.mUrl ),
+  mType( url.mType ),
+  mLocation( url.mLocation )
+{
+}
+
+VisualUrl& VisualUrl::operator=( const VisualUrl& url )
+{
+  if( &url != this )
+  {
+    mUrl = url.mUrl;
+    mType = url.mType;
+    mLocation = url.mLocation;
+  }
+  return *this;
+}
+
+const std::string& VisualUrl::GetUrl() const
+{
+  return mUrl;
+}
+
+VisualUrl::Type VisualUrl::GetType() const
+{
+  return mType;
+}
+
+VisualUrl::Location VisualUrl::GetLocation() const
+{
+  return mLocation;
+}
+
+bool VisualUrl::IsValid() const
+{
+  return mUrl.size() > 0u;
+}
+
+bool VisualUrl::IsLocal() const
+{
+  return mLocation == VisualUrl::LOCAL;
+}
+
+
+
+} // Internal
+} // Toolkit
+} // Dali
diff --git a/dali-toolkit/internal/visuals/visual-url.h b/dali-toolkit/internal/visuals/visual-url.h
new file mode 100644 (file)
index 0000000..d9ed48a
--- /dev/null
@@ -0,0 +1,119 @@
+#ifndef DALI_TOOLKIT_INTERNAL_VISUAL_URL_H
+#define DALI_TOOLKIT_INTERNAL_VISUAL_URL_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class VisualUrl
+{
+public:
+
+  /**
+   * The type of the URL based on the string contents
+   */
+  enum Type
+  {
+    REGULAR_IMAGE,
+    N_PATCH,
+    SVG,
+    GIF
+  };
+
+  enum Location
+  {
+    LOCAL,
+    REMOTE
+  };
+
+  /**
+   * Default Constructor.
+   * Resulting URL is not valid
+   */
+  VisualUrl();
+
+  /**
+   * Constructor.
+   * Determines type of visual and whether the url is local or remote
+   * @param[in] url The URL to store and resolve
+   */
+  VisualUrl( const std::string& url );
+
+  /**
+   * Copy constructor
+   * @param[in] url The VisualUrl to copy
+   */
+  VisualUrl( const VisualUrl& url );
+
+  /**
+   * Assignment operator
+   * @param[in] url The VisualUrl to copy
+   */
+  VisualUrl& operator=( const VisualUrl& url );
+
+  /**
+   * Get the full URL
+   * @return The url
+   */
+  const std::string& GetUrl() const;
+
+  /**
+   * Get the visual type of the URL
+   * @return The visual type of the URL
+   */
+  Type GetType() const;
+
+  /**
+   * Is the URL is local to the device, or remote?
+   * @return the location of the resource
+   */
+  Location GetLocation() const;
+
+  /**
+   * Is the URL valid?
+   * @return true if the URL has length
+   */
+  bool IsValid() const;
+
+  /**
+   * @return true if the location is LOCAL
+   */
+  bool IsLocal() const;
+
+private:
+  std::string mUrl;
+  Type mType;
+  Location mLocation;
+};
+
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* DALI_TOOLKIT_INTERNAL_VISUAL_URL_H */
index a31e003..414fb07 100755 (executable)
@@ -1,3 +1,7 @@
+#: Used to know if the language is using a right to left script
+msgid "IDS_LTR"
+msgstr "RTL"
+
 msgid "IDS_COM_BODY_SELECT_ALL"
 msgstr "اختيار Ø§Ù„كل"
 
index 4996205..5e8369b 100644 (file)
@@ -1,3 +1,7 @@
+#: Used to know if the language is using a right to left script
+msgid "IDS_LTR"
+msgstr "RTL"
+
 msgid "IDS_COM_BODY_SELECT_ALL"
 msgstr "انتخاب Ù‡Ù…Ù‡"
 
index 7872070..b4bf3be 100644 (file)
@@ -1,3 +1,7 @@
+#: Used to know if the language is using a right to left script
+msgid "IDS_LTR"
+msgstr "RTL"
+
 msgid "IDS_COM_BODY_SELECT_ALL"
 msgstr "تمام Ù…نتخب Ú©Ø±ÛŒÚº"
 
index 26e020a..c4ee219 100644 (file)
@@ -686,10 +686,10 @@ public:
     }
   }
 
-  Toolkit::Visual::Type GetVisualTypeFromMap( const Property::Map& map )
+  Toolkit::DevelVisual::Type GetVisualTypeFromMap( const Property::Map& map )
   {
-    Property::Value* typeValue = map.Find( Toolkit::Visual::Property::TYPE, VISUAL_TYPE  );
-    Toolkit::Visual::Type type = Toolkit::Visual::IMAGE;
+    Property::Value* typeValue = map.Find( Toolkit::DevelVisual::Property::TYPE, VISUAL_TYPE  );
+    Toolkit::DevelVisual::Type type = Toolkit::DevelVisual::IMAGE;
     if( typeValue )
     {
       Scripting::GetEnumerationProperty( *typeValue, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT, type );
@@ -721,8 +721,8 @@ public:
         Property::Map fromMap;
         visual.CreatePropertyMap( fromMap );
 
-        Toolkit::Visual::Type fromType = GetVisualTypeFromMap( fromMap );
-        Toolkit::Visual::Type toType = GetVisualTypeFromMap( toMap );
+        Toolkit::DevelVisual::Type fromType = GetVisualTypeFromMap( fromMap );
+        Toolkit::DevelVisual::Type toType = GetVisualTypeFromMap( toMap );
 
         if( fromType != toType )
         {
@@ -730,7 +730,8 @@ public:
         }
         else
         {
-          if( fromType == Toolkit::Visual::IMAGE )
+          if( fromType == Toolkit::DevelVisual::IMAGE || fromType == Toolkit::DevelVisual::N_PATCH
+              || fromType == Toolkit::DevelVisual::SVG || fromType == Toolkit::DevelVisual::ANIMATED_IMAGE )
           {
             Property::Value* fromUrl = fromMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME );
             Property::Value* toUrl = toMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME );
@@ -1499,8 +1500,8 @@ void Control::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Ty
   if( styleManager && change == StyleChange::THEME_CHANGE )
   {
     GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+    RelayoutRequest();
   }
-  RelayoutRequest();
 }
 
 void Control::OnPinch(const PinchGesture& pinch)
index 2f4b7a3..0b257b2 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 31;
+const unsigned int TOOLKIT_MICRO_VERSION = 32;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 71c45ef..17abb35 100644 (file)
@@ -26,23 +26,26 @@ This is required to avoid ambiguity as multiple visuals may be capable of render
 
 Visuals have a **transform** field in the property map to allow layouting within a control. If this field is not set, then the visual defaults to filling the control. The **transform** field has a property map with the following keys:
 
-| Property                                        | String   | Type    | Required | Description               |
-|-------------------------------------------------|----------|:-------:|:--------:|---------------------------|
-| Dali::Toolkit::Visual::Transform::Property::OFFSET | offset | VECTOR2 | No      | The offset of the visual. |
-| Dali::Toolkit::Visual::Transform::Property::SIZE | size | VECTOR2 | No      | The size of the visual. |
-| Dali::Toolkit::Visual::Transform::Property::OFFSET_SIZE_MODE | offsetSizeMode | VECTOR4 | No      | Whether the size or offset components are Relative or Absolute [More info](@ref offset-size-mode)|
-| Dali::Toolkit::Visual::Transform::Property::ORIGIN | origin | INTEGER or STRING | No      | The origin of the visual within the control's area. [More info](@ref align-type) |
-| Dali::Toolkit::Visual::Transform::Property::ANCHOR_POINT | anchorPoint | INTEGER or STRING | No      | The anchor point of the visual. [More info](@ref align-type)|
+| Property                                                       | String       | Type              | Required | Description                                                                                 |
+|----------------------------------------------------------------|--------------|:-----------------:|:--------:|---------------------------------------------------------------------------------------------|
+| Dali::Toolkit::DevelVisual::Transform::Property::OFFSET        | offset       | VECTOR2           | No       | The offset of the visual.                                                                   |
+| Dali::Toolkit::DevelVisual::Transform::Property::SIZE          | size         | VECTOR2           | No       | The size of the visual.                                                                     |
+| Dali::Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY | offsetPolicy | VECTOR4           | No       | Whether the offset components are Relative or Absolute [More info](@ref offset-size-policy) |
+| Dali::Toolkit::DevelVisual::Transform::Property::SIZE_POLICY   | sizePolicy   | VECTOR4           | No       | Whether the size components are Relative or Absolute [More info](@ref offset-size-policy)   |
+| Dali::Toolkit::DevelVisual::Transform::Property::ORIGIN        | origin       | INTEGER or STRING | No       | The origin of the visual within the control's area. [More info](@ref align-type)            |
+| Dali::Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT  | anchorPoint  | INTEGER or STRING | No       | The anchor point of the visual. [More info](@ref align-type)                                |
  
 
-## Offset & size modes  {#offset-size-mode}
-
-The offset and size modes can be either Relative or Absolute. The offset modes are in the x and y components of the offsetSizeMode property, and map to the offset's x and y components respectively. The size modes are in the z and w components of the offsetSizeMode property, and map to the size's x and y components, respectively.
+## Offset & Size Policy  {#offset-size-policy}
 
-A mode value of 0 represents a Relative mode, in which case the size or offset value represents a ratio of the control's size. A mode value of 1 represents an Absolute mode, in which case the size or offset value represents world units (pixels).
+The offset and size policies can be either Relative or Absolute.
 
-For example, an offsetSizeMode of [0, 0, 1, 1], an offset of (0, 0.25) and a size of (20, 20) means the visual will be 20 pixels by 20 pixels in size, positioned 25% above the center of the control.
+| Enumeration                                             | String   | Description                                                                   |
+|---------------------------------------------------------|----------|-------------------------------------------------------------------------------|
+| Dali::Toolkit::DevelVisual::Transform::Policy::RELATIVE | RELATIVE | *Default*. The size or offset value represents a ratio of the control's size  |
+| Dali::Toolkit::DevelVisual::Transform::Policy::ABSOLUTE | ABSOLUTE | The size or offset value represents world units (pixels)                      |
 
+For example, an offsetPolicy of [ RELATIVE, RELATIVE ], a sizePolicy of [ ABSOLUTE, ABSOLUTE ], an offset of ( 0, 0.25 ) and a size of ( 20, 20 ) means the visual will be 20 pixels by 20 pixels in size, positioned 25% above the center of the control.
 
 ## Alignment  {#align-type}
 | Enumeration                                          | String  | Description                                                                                          |
index 6e66054..bde72c9 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.2.31
+Version:    1.2.32
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-2-Clause and MIT
diff --git a/plugins/dali-swig/SWIG/adaptor/window.i b/plugins/dali-swig/SWIG/adaptor/window.i
new file mode 100755 (executable)
index 0000000..5870e36
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ *
+ */
+
+%typemap(cscode) Dali::Window %{
+    public void Show()
+    {
+      NDalicPINVOKE.Show(swigCPtr);
+      if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+    }
+
+    public void Hide()
+    {
+      NDalicPINVOKE.Hide(swigCPtr);
+      if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+    }
+
+    public void IsVisible()
+    {
+      NDalicPINVOKE.IsVisible(swigCPtr);
+      if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+    }
+%}
index 3ce308e..5834e10 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
 %include <dali/devel-api/adaptor-framework/drag-and-drop-detector.h>
 %include <dali/devel-api/adaptor-framework/application-extensions.h>
 %include <dali/public-api/adaptor-framework/window.h>
+%include <dali/devel-api/adaptor-framework/window-devel.h>
 
 #if defined(SWIGCSHARP)
 
index 7d83bf8..e420c95 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 %rename(AlignType) Dali::Toolkit::Align::Type;
 %rename(VisualType) Dali::Toolkit::Visual::Type;
 %rename(VisualTransformPropertyType) Dali::Toolkit::DevelVisual::Transform::Property::Type;
+%rename(VisualTransformPolicyType) Dali::Toolkit::DevelVisual::Transform::Policy::Type;
 %rename(VISUAL_SHADER_VERTEX) Dali::Toolkit::Visual::Shader::Property::VERTEX_SHADER;
 %rename(VISUAL_SHADER_FRAGMENT) Dali::Toolkit::Visual::Shader::Property::FRAGMENT_SHADER;
 %rename(VISUAL_SHADER_SUBDIVIDE_GRID_X) Dali::Toolkit::Visual::Shader::Property::SUBDIVIDE_GRID_X;
@@ -298,6 +299,8 @@ typedef Dali::IntrusivePtr<Dali::Toolkit::Ruler> RulerPtr;
 %include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
 %include <dali-toolkit/public-api/text/rendering-backend.h>
 
+%include <dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h>
+
 %template(ItemIdContainer) std::vector<unsigned int>;
 %template(Item) std::pair<unsigned int, Dali::Actor>;
 %template(ItemContainer) std::vector<std::pair<unsigned int, Dali::Actor>>;
index 1cd7ef8..4e3fdb5 100755 (executable)
 #include <dali/public-api/adaptor-framework/style-change.h>
 #include <dali/devel-api/adaptor-framework/drag-and-drop-detector.h>
 #include <dali/devel-api/adaptor-framework/application-extensions.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
 
 #include <dali/devel-api/images/nine-patch-image.h>
 
 #include <dali-toolkit/devel-api/builder/builder.h>
 
 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
+#include <dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h>
 
 #include <dali-toolkit/devel-api/controls/popup/popup.h>
 #include <dali-toolkit/devel-api/controls/progress-bar/progress-bar.h>
@@ -244,6 +246,8 @@ using namespace Dali::Toolkit;
 %feature("notabstract") Dali::Toolkit::FixedRuler;
 %feature("notabstract") Dali::Toolkit::DefaultRuler;
 
+%feature("director") Dali::Toolkit::DevelKeyboardFocusManager::CustomAlgorithmInterface;
+
 // Note... all the typemap declarations have to be included before the DALi C++ head files are include otherwise
 // they have no effect.
 
@@ -302,7 +306,8 @@ using namespace Dali::Toolkit;
 %include gestures/touch.i
 %include gestures/key.i
 
+%include adaptor/window.i
+
 %include dali-core.i
 %include dali-adaptor.i
 %include dali-toolkit.i
-
index a392996..d775fbe 100755 (executable)
@@ -49,6 +49,7 @@ namespace MyCSharpExample
       _text.PointSize = 32.0f;
       _text.TextColor = Color.Magenta;
       stage.Add(_text);
+
     }
 
     // Callback for _animation finished signal handling
index f659b70..ad9bc2d 100644 (file)
@@ -158,7 +158,8 @@ namespace VisualsUsingCustomView
             // Configure the transform and size of Image visual.
             Dali.Property.Map imageVisualTransform = new Dali.Property.Map();
             imageVisualTransform.Add((int)VisualTransformPropertyType.OFFSET, new Dali.Property.Value(new Vector2(10.0f, 0.0f)))
-                .Add((int)VisualTransformPropertyType.OFFSET_SIZE_MODE, new Dali.Property.Value(new Vector4(1.0f, 1.0f, 1.0f, 1.0f)))
+                .Add((int)VisualTransformPropertyType.OFFSET_POLICY, new Dali.Property.Value(new Vector2((int)VisualTransformPolicyType.ABSOLUTE, (int)VisualTransformPolicyType.ABSOLUTE)))
+                .Add((int)VisualTransformPropertyType.SIZE_POLICY, new Dali.Property.Value(new Vector2((int)VisualTransformPolicyType.ABSOLUTE, (int)VisualTransformPolicyType.ABSOLUTE)))
                 .Add((int)VisualTransformPropertyType.SIZE, new Dali.Property.Value(new Vector2(40.0f, 40.0f)))
                 .Add((int)VisualTransformPropertyType.ORIGIN, new Dali.Property.Value((int)AlignType.CENTER_BEGIN))
                 .Add((int)VisualTransformPropertyType.ANCHOR_POINT, new Dali.Property.Value((int)AlignType.CENTER_BEGIN));
@@ -167,7 +168,8 @@ namespace VisualsUsingCustomView
             // Configure the transform and size of Text visual.
             Dali.Property.Map textVisualTransform = new Dali.Property.Map();
             textVisualTransform.Add((int)VisualTransformPropertyType.OFFSET, new Dali.Property.Value(new Vector2(0.0f, 0.0f)))
-                .Add((int)VisualTransformPropertyType.OFFSET_SIZE_MODE, new Dali.Property.Value(new Vector4(0.0f, 0.0f, 1.0f, 1.0f)))
+                .Add((int)VisualTransformPropertyType.OFFSET_POLICY, new Dali.Property.Value(new Vector2((int)VisualTransformPolicyType.RELATIVE, (int)VisualTransformPolicyType.RELATIVE)))
+                .Add((int)VisualTransformPropertyType.SIZE_POLICY, new Dali.Property.Value(new Vector2((int)VisualTransformPolicyType.ABSOLUTE, (int)VisualTransformPolicyType.ABSOLUTE)))
                 .Add((int)VisualTransformPropertyType.SIZE, new Dali.Property.Value(new Vector2(size.X - 100.0f, 50.0f)))
                 .Add((int)VisualTransformPropertyType.ORIGIN, new Dali.Property.Value((int)Align.Type.Center))
                 .Add((int)VisualTransformPropertyType.ANCHOR_POINT, new Dali.Property.Value((int)Align.Type.Center));
@@ -176,7 +178,8 @@ namespace VisualsUsingCustomView
             // Configure the transform and size of Primitive visual.
             Dali.Property.Map primitiveVisualTransform = new Dali.Property.Map();
             primitiveVisualTransform.Add((int)VisualTransformPropertyType.OFFSET, new Dali.Property.Value(new Vector2(size.X - 60.0f, 0.0f)))
-                .Add((int)VisualTransformPropertyType.OFFSET_SIZE_MODE, new Dali.Property.Value(new Vector4(1.0f, 1.0f, 1.0f, 1.0f)))
+                .Add((int)VisualTransformPropertyType.OFFSET_POLICY, new Dali.Property.Value(new Vector2((int)VisualTransformPolicyType.ABSOLUTE, (int)VisualTransformPolicyType.ABSOLUTE)))
+                .Add((int)VisualTransformPropertyType.SIZE_POLICY, new Dali.Property.Value(new Vector2((int)VisualTransformPolicyType.ABSOLUTE, (int)VisualTransformPolicyType.ABSOLUTE)))
                 .Add((int)VisualTransformPropertyType.SIZE, new Dali.Property.Value(new Vector2(40.0f, 40.0f)))
                 .Add((int)VisualTransformPropertyType.ORIGIN, new Dali.Property.Value((int)AlignType.CENTER_BEGIN))
                 .Add((int)VisualTransformPropertyType.ANCHOR_POINT, new Dali.Property.Value((int)AlignType.CENTER_BEGIN));
@@ -185,7 +188,8 @@ namespace VisualsUsingCustomView
             // Configure the transform and size of Color visual. This is also the default value.
             Dali.Property.Map colorVisualTransform = new Dali.Property.Map();
             colorVisualTransform.Add( (int)VisualTransformPropertyType.OFFSET, new Dali.Property.Value(new Vector2(0.0f,0.0f)))
-                .Add((int)VisualTransformPropertyType.OFFSET_SIZE_MODE, new Dali.Property.Value(new Vector4(0.0f, 0.0f, 0.0f, 0.0f)))
+                .Add((int)VisualTransformPropertyType.OFFSET_POLICY, new Dali.Property.Value(new Vector2((int)VisualTransformPolicyType.RELATIVE, (int)VisualTransformPolicyType.RELATIVE)))
+                .Add((int)VisualTransformPropertyType.SIZE_POLICY, new Dali.Property.Value(new Vector2((int)VisualTransformPolicyType.RELATIVE, (int)VisualTransformPolicyType.RELATIVE)))
                 .Add( (int)VisualTransformPropertyType.SIZE, new Dali.Property.Value(new Vector2(1.0f, 1.0f)) )
                 .Add( (int)VisualTransformPropertyType.ORIGIN, new Dali.Property.Value((int)AlignType.TOP_BEGIN) )
                 .Add( (int)VisualTransformPropertyType.ANCHOR_POINT, new Dali.Property.Value((int)AlignType.TOP_BEGIN) );
index cb7ae8f..ec64610 100755 (executable)
@@ -22,6 +22,7 @@ using System.Runtime.InteropServices;
 
 public class FocusManager : BaseHandle {
   private global::System.Runtime.InteropServices.HandleRef swigCPtr;
+  private CustomAlgorithmInterfaceWrapper _customAlgorithmInterfaceWrapper;
 
   internal FocusManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(NDalicManualPINVOKE.FocusManager_SWIGUpcast(cPtr), cMemoryOwn) {
     swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
@@ -533,6 +534,14 @@ public class PreFocusChangeEventArgs : EventArgs
     return ret;
   }
 
+  public void SetCustomAlgorithm(ICustomFocusAlgorithm arg0) {
+    _customAlgorithmInterfaceWrapper = new CustomAlgorithmInterfaceWrapper();
+    _customAlgorithmInterfaceWrapper.SetFocusAlgorithm(arg0);
+
+    NDalicPINVOKE.SetCustomAlgorithm(swigCPtr, CustomAlgorithmInterface.getCPtr(_customAlgorithmInterfaceWrapper));
+    if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+  }
+
   public PreFocusChangeSignal PreFocusChangeSignal() {
     PreFocusChangeSignal ret = new PreFocusChangeSignal(NDalicManualPINVOKE.FocusManager_PreFocusChangeSignal(swigCPtr), false);
     if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
@@ -567,7 +576,31 @@ public class PreFocusChangeEventArgs : EventArgs
       }
   }
 
+  public interface ICustomFocusAlgorithm
+  {
+      View GetNextFocusableActor(View current, View proposed, View.KeyboardFocus.Direction direction);
+  }
+
+  private class CustomAlgorithmInterfaceWrapper : CustomAlgorithmInterface
+  {
+      private FocusManager.ICustomFocusAlgorithm _customFocusAlgorithm;
 
+      public CustomAlgorithmInterfaceWrapper()
+      {
+      }
+
+      public void SetFocusAlgorithm(FocusManager.ICustomFocusAlgorithm customFocusAlgorithm)
+      {
+          _customFocusAlgorithm = customFocusAlgorithm;
+      }
+
+      public override Actor GetNextFocusableActor(Actor current, Actor proposed, View.KeyboardFocus.Direction direction)
+      {
+          View currentView = View.DownCast<View>(current);
+          View proposedView = View.DownCast<View>(proposed);
+          return _customFocusAlgorithm.GetNextFocusableActor(currentView, proposedView, direction);
+      }
+  }
 }
 
 }