[dali_1.2.14] Merge branch 'devel/master' 64/97264/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 11 Nov 2016 18:41:05 +0000 (18:41 +0000)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 11 Nov 2016 18:41:05 +0000 (18:41 +0000)
Change-Id: I3bbf18b3f11e44ed5ab56742ac954d3e222e68a9

77 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-video-player.h
automated-tests/src/dali-toolkit/utc-Dali-AsyncImageLoader.cpp
automated-tests/src/dali-toolkit/utc-Dali-DebugRendering.cpp
automated-tests/src/dali-toolkit/utc-Dali-EffectsView.cpp
automated-tests/src/dali-toolkit/utc-Dali-Popup.cpp
automated-tests/src/dali-toolkit/utc-Dali-SuperBlurView.cpp
automated-tests/src/dali-toolkit/utc-Dali-SyncImageLoader.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-ToolBar.cpp
automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp
build/tizen/dali-toolkit/Makefile.am
build/tizen/docs/dali.doxy.in
dali-toolkit/dali-toolkit.h
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/visual-factory/visual-base.cpp
dali-toolkit/devel-api/visual-factory/visual-base.h
dali-toolkit/devel-api/visual-factory/visual-factory.h
dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp
dali-toolkit/internal/controls/effects-view/effects-view-impl.h
dali-toolkit/internal/controls/magnifier/magnifier-impl.cpp
dali-toolkit/internal/controls/popup/popup-impl.cpp
dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/controls/video-view/video-view-impl.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/filters/emboss-filter.cpp
dali-toolkit/internal/image-loader/async-image-loader-impl.cpp
dali-toolkit/internal/image-loader/async-image-loader-impl.h
dali-toolkit/internal/image-loader/image-atlas-impl.h
dali-toolkit/internal/image-loader/image-load-thread.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-scroller-data.cpp [deleted file]
dali-toolkit/internal/text/text-scroller-data.h [deleted file]
dali-toolkit/internal/text/text-scroller.cpp
dali-toolkit/internal/text/text-scroller.h
dali-toolkit/internal/visuals/gradient/gradient-visual.cpp
dali-toolkit/internal/visuals/gradient/gradient-visual.h
dali-toolkit/internal/visuals/image/batch-image-visual.cpp
dali-toolkit/internal/visuals/image/batch-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 [new file with mode: 0644]
dali-toolkit/internal/visuals/npatch-loader.h [new file with mode: 0644]
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.h
dali-toolkit/internal/visuals/primitive/primitive-visual.cpp
dali-toolkit/internal/visuals/primitive/primitive-visual.h
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.h
dali-toolkit/internal/visuals/text/text-visual.cpp
dali-toolkit/internal/visuals/text/text-visual.h
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.h
dali-toolkit/internal/visuals/visual-factory-cache.cpp
dali-toolkit/internal/visuals/visual-factory-cache.h
dali-toolkit/internal/visuals/visual-factory-impl.h
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/public-api/file.list
dali-toolkit/public-api/image-loader/async-image-loader.cpp [moved from dali-toolkit/devel-api/image-loader/async-image-loader.cpp with 70% similarity]
dali-toolkit/public-api/image-loader/async-image-loader.h [moved from dali-toolkit/devel-api/image-loader/async-image-loader.h with 52% similarity]
dali-toolkit/public-api/image-loader/sync-image-loader.cpp [new file with mode: 0644]
dali-toolkit/public-api/image-loader/sync-image-loader.h [new file with mode: 0644]
docs/content/images/creating-custom-controls/control-handle-body.png
docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md
docs/content/shared-javascript-and-cpp-documentation/visuals.md
packaging/dali-addon.spec
packaging/dali-csharp-wrapper.spec
packaging/dali-toolkit.spec

index f2e761f..cdb29f9 100644 (file)
@@ -26,7 +26,6 @@
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
-#include <dali-toolkit/internal/text/text-scroller-data.h>
 
 using namespace Dali;
 using namespace Toolkit;
@@ -403,122 +402,3 @@ int UtcDaliTextControllerSetGetAutoScrollEnabled(void)
   tet_result(TET_PASS);
   END_TEST;
 }
-
-int UtcDaliTextControllerSetGetAutoScrollSpeed(void)
-{
-  tet_infoline(" UtcDaliTextControllerSetGetAutoScrollSpeed");
-  ToolkitTestApplication application;
-
-  // Creates a text controller.
-  ControllerPtr controller = Controller::New();
-
-  DALI_TEST_CHECK( controller );
-
-  // Check the default value.
-  DALI_TEST_EQUALS( 0, controller->GetAutoScrollSpeed(), TEST_LOCATION );
-
-  // Set the auto scroll speed.
-  controller->SetAutoscrollSpeed( 10 );
-
-  DALI_TEST_EQUALS( 10, controller->GetAutoScrollSpeed(), TEST_LOCATION );
-
-  tet_result(TET_PASS);
-  END_TEST;
-}
-
-int UtcDaliTextControllerSetGetAutoScrollLoopCount(void)
-{
-  tet_infoline(" UtcDaliTextControllerSetGetAutoScrollLoopCount");
-  ToolkitTestApplication application;
-
-  // Creates a text controller.
-  ControllerPtr controller = Controller::New();
-
-  DALI_TEST_CHECK( controller );
-
-  // Check the default value.
-  DALI_TEST_EQUALS( 0, controller->GetAutoScrollLoopCount(), TEST_LOCATION );
-
-  // Set the auto scroll loop count.
-  controller->SetAutoScrollLoopCount( 5 );
-
-  DALI_TEST_EQUALS( 5, controller->GetAutoScrollLoopCount(), TEST_LOCATION );
-
-  tet_result(TET_PASS);
-  END_TEST;
-}
-
-int UtcDaliTextControllerSetGetAutoScrollWrapGap(void)
-{
-  tet_infoline(" UtcDaliTextControllerSetGetAutoScrollWrapGap");
-  ToolkitTestApplication application;
-
-  // Creates a text controller.
-  ControllerPtr controller = Controller::New();
-
-  DALI_TEST_CHECK( controller );
-
-  // Check the default value.
-  DALI_TEST_EQUALS( 0.f, controller->GetAutoScrollWrapGap(), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
-  // Set the auto scroll loop count.
-  controller->SetAutoScrollWrapGap( 25.f );
-
-  DALI_TEST_EQUALS( 25.f, controller->GetAutoScrollWrapGap(), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
-  tet_result(TET_PASS);
-  END_TEST;
-}
-
-int UtcDaliTextControllerGetAutoScrollData(void)
-{
-  tet_infoline(" UtcDaliTextControllerGetAutoScrollData");
-  ToolkitTestApplication application;
-
-  // Load some fonts to get the same metrics on different platforms.
-  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
-  fontClient.SetDpi( 96u, 96u );
-
-  char* pathNamePtr = get_current_dir_name();
-  const std::string pathName( pathNamePtr );
-  free( pathNamePtr );
-
-  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
-
-  // Creates a text controller.
-  ControllerPtr controller = Controller::New();
-
-  DALI_TEST_CHECK( controller );
-
-  DALI_TEST_CHECK( NULL == controller->GetAutoScrollData() );
-
-  // Set and check some values.
-  controller->SetAutoscrollSpeed( 10 );
-  controller->SetAutoScrollLoopCount( 5 );
-  controller->SetAutoScrollWrapGap( 25.f );
-
-  const ScrollerData* scrollerData = controller->GetAutoScrollData();
-  DALI_TEST_CHECK( NULL != controller->GetAutoScrollData() );
-
-  DALI_TEST_EQUALS( Size::ZERO, scrollerData->mControlSize, TEST_LOCATION );
-  DALI_TEST_EQUALS( Size::ZERO, scrollerData->mOffscreenSize, TEST_LOCATION );
-  DALI_TEST_EQUALS( 10, scrollerData->mScrollSpeed, TEST_LOCATION );
-  DALI_TEST_EQUALS( 5, scrollerData->mLoopCount, TEST_LOCATION );
-  DALI_TEST_EQUALS( 25.f, scrollerData->mWrapGap, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-  DALI_TEST_EQUALS( 0.f, scrollerData->mAlignmentOffset, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-  DALI_TEST_CHECK( !scrollerData->mAutoScrollDirectionRTL );
-
-  // Set some text and layout.
-  controller->SetMarkupProcessorEnabled( true );
-  controller->SetHorizontalAlignment( LayoutEngine::HORIZONTAL_ALIGN_END );
-  controller->SetText( "<font family='TizenSans' size='12'>Hello world</font>" );
-  controller->Relayout( Size( 100.f, 20.f ) );
-
-  scrollerData = controller->GetAutoScrollData();
-  DALI_TEST_EQUALS( Size( 100.f, 20.f ), scrollerData->mControlSize, TEST_LOCATION );
-  DALI_TEST_EQUALS( Size( 80.f, 20.f ), scrollerData->mOffscreenSize, TEST_LOCATION );
-  DALI_TEST_EQUALS( 20.f, scrollerData->mAlignmentOffset, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
-  tet_result(TET_PASS);
-  END_TEST;
-}
index 1c6f3c9..f30e3d1 100644 (file)
@@ -57,6 +57,7 @@ SET(TC_SOURCES
    utc-Dali-ImageAtlas.cpp
    utc-Dali-VideoView.cpp
    utc-Dali-AsyncImageLoader.cpp
+   utc-Dali-SyncImageLoader.cpp
 )
 
 # Append list of test harness files (Won't get parsed for test cases)
index a71f953..6fcc10d 100644 (file)
@@ -56,6 +56,17 @@ void DummyControlImpl::CustomSlot1( Actor actor )
   mCustomSlot1Called = true;
 }
 
+namespace {
+
+BaseHandle Create()
+{
+  return DummyControlImpl::New();
+}
+
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::DummyControl, Toolkit::Control, Create );
+DALI_TYPE_REGISTRATION_END()
+}
+
 DummyControl DummyControlImpl::New()
 {
   IntrusivePtr< DummyControlImpl > impl = new DummyControlImpl;
index 2351839..04847d1 100644 (file)
@@ -75,7 +75,7 @@ public:
   void RegisterVisual( Property::Index index, Toolkit::Visual::Base visual, bool enabled );
   void UnregisterVisual( Property::Index index );
   void EnableVisual( Property::Index index, bool enabled );
-  bool IsVisualEnabled( Property::Index index );
+  bool IsVisualEnabled( Property::Index indepx );
 
   Toolkit::Visual::Base GetVisual( Property::Index index );
   Animation CreateTransition( const Toolkit::TransitionData& transition );
index f33a68c..717a243 100644 (file)
@@ -49,7 +49,7 @@ public:
 
   VideoPlayer();
 
-  virtual ~VideoPlayer();
+  ~VideoPlayer();
 
   static VideoPlayer New();
 
@@ -102,4 +102,3 @@ private:
 } // namespace Dali;
 
 #endif
-
index 3ee9a77..74dcc73 100644 (file)
@@ -19,7 +19,7 @@
 #include <dali/dali.h>
 #include <dali-toolkit-test-suite-utils.h>
 #include <toolkit-event-thread-callback.h>
-#include <dali-toolkit/devel-api/image-loader/async-image-loader.h>
+#include <dali-toolkit/dali-toolkit.h>
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -139,6 +139,28 @@ int UtcDaliAsyncImageLoaderAssignmentOperator(void)
   END_TEST;
 }
 
+int UtcDaliAsyncImageLoaderDownCastP(void)
+{
+  AsyncImageLoader asyncImageLoader = AsyncImageLoader::New();
+  BaseHandle object(asyncImageLoader);
+
+  AsyncImageLoader asyncImageLoader2 = AsyncImageLoader::DownCast( object );
+
+  DALI_TEST_CHECK( asyncImageLoader2 );
+
+  END_TEST;
+}
+
+int UtcDaliAsyncImageLoaderDownCastN(void)
+{
+  BaseHandle unInitializedObject;
+  AsyncImageLoader asyncImageLoader = AsyncImageLoader::DownCast( unInitializedObject );
+
+  DALI_TEST_CHECK( !asyncImageLoader );
+
+  END_TEST;
+}
+
 int UtcDaliAsyncImageLoaderLoadAndLoadedSignal(void)
 {
   ToolkitTestApplication application;
@@ -169,6 +191,7 @@ int UtcDaliAsyncImageLoaderLoadAndLoadedSignal(void)
   END_TEST;
 }
 
+// Note: This is not an ideal test, but we cannot guarantee we can call Cancel() before the image has finished loading.
 int UtcDaliAsyncImageLoaderCancel(void)
 {
   ToolkitTestApplication application;
@@ -182,31 +205,28 @@ int UtcDaliAsyncImageLoaderCancel(void)
   uint32_t id02 = loader.Load( gImage_50_RGBA, ImageDimensions( 25, 25 ) );
   uint32_t id03 = loader.Load( gImage_128_RGB, ImageDimensions( 100, 100 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, true );
 
-  // cancel the loading of the second image
-  DALI_TEST_CHECK( loader.Cancel( id02 ) );
-
   EventThreadCallback* eventTrigger = EventThreadCallback::Get();
   CallbackBase* callback = eventTrigger->GetCallback();
 
-  eventTrigger->WaitingForTrigger( 2 );// waiting until first and third images are loaded
+  eventTrigger->WaitingForTrigger( 3 ); // waiting until images are loaded
 
   CallbackBase::Execute( *callback );
 
-  DALI_TEST_CHECK( ! loader.Cancel( id03 ) ); // can not cancel a task that is already implemeted
-
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_CHECK( loadedSignalVerifier.LoadedImageCount() == 2 );
+  DALI_TEST_CHECK( loadedSignalVerifier.LoadedImageCount() == 3 );
+
+  DALI_TEST_CHECK( !loader.Cancel( id03 ) ); // Cannot cancel a task that is already implemeted
 
-  DALI_TEST_CHECK( loadedSignalVerifier.Verify( id01, 34, 34 ) );  // first image is successfully loaded
-  DALI_TEST_CHECK( !loadedSignalVerifier.Verify( id02, 25, 25 ) ); // second image is not loaded
-  DALI_TEST_CHECK( loadedSignalVerifier.Verify( id03, 100, 100 ) ); // third image is successfully loaded
+  DALI_TEST_CHECK( loadedSignalVerifier.Verify( id01, 34, 34 ) );   // first image is loaded
+  DALI_TEST_CHECK( loadedSignalVerifier.Verify( id02, 25, 25 ) );   // second image is loaded
+  DALI_TEST_CHECK( loadedSignalVerifier.Verify( id03, 100, 100 ) ); // third image is loaded
 
   END_TEST;
 }
 
-int UtcDaliAsncImageLoaderCancelAll01(void)
+int UtcDaliAsyncImageLoaderCancelAll(void)
 {
   ToolkitTestApplication application;
 
@@ -229,38 +249,3 @@ int UtcDaliAsncImageLoaderCancelAll01(void)
   END_TEST;
 }
 
-int UtcDaliAsyncImageLoaderCancelAll02(void)
-{
-  ToolkitTestApplication application;
-
-  AsyncImageLoader loader = AsyncImageLoader::New();
-  ImageLoadedSignalVerifier loadedSignalVerifier;
-
-  loader.ImageLoadedSignal().Connect( &loadedSignalVerifier, &ImageLoadedSignalVerifier::ImageLoaded );
-
-  loader.Load( gImage_34_RGBA, ImageDimensions( 34, 34 ) );
-  uint32_t id02 = loader.Load( gImage_50_RGBA, ImageDimensions( 25, 25 ) );
-
-  // try to cancel the loading of the first and second image, however the cancellation of the first image is not guaranteed
-  loader.CancelAll();
-
-  uint32_t id03 = loader.Load( gImage_128_RGB, ImageDimensions( 100, 100 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, true );
-  loader.Load( gImage_128_RGB, ImageDimensions( 128, 128 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, true );
-
-  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
-  CallbackBase* callback = eventTrigger->GetCallback();
-
-  eventTrigger->WaitingForTrigger( 2 );// waiting until the third images is loaded
-
-  CallbackBase::Execute( *callback );
-
-  application.SendNotification();
-  application.Render();
-
-  DALI_TEST_CHECK( !loadedSignalVerifier.Verify( id02, 25, 25 ) ); // second image is not loaded
-  DALI_TEST_CHECK( loadedSignalVerifier.Verify( id03, 100, 100 ) ); // third image is successfully loaded
-
-  END_TEST;
-}
-
-
index b2cb02c..096bf4d 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali-toolkit/dali-toolkit.h>
 
 #include <toolkit-environment-variable.h> // for setting environment variable: DALI_DEBUG_RENDERING
+#include "dummy-control.h"
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -45,10 +46,17 @@ bool IsDebugVisual( Visual::Base& visual )
     isDebugVisualType = ( typeValue->Get<int>() == Visual::WIREFRAME ); // Debug Rendering uses the WireframeVisual
   }
 
-  Actor actor = Actor::New();
-  visual.SetOnStage( actor );
-  Geometry geometry = actor.GetRendererAt( 0 ).GetGeometry();
-  isGeometryLineType = ( geometry.GetType() == Geometry::LINES );
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+  Stage::GetCurrent().Add( actor );
+
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1, TEST_LOCATION );
+  if( actor.GetRendererCount() > 0 )
+  {
+    Geometry geometry = actor.GetRendererAt( 0 ).GetGeometry();
+    isGeometryLineType = ( geometry.GetType() == Geometry::LINES );
+  }
 
   return isDebugVisualType && isGeometryLineType;
 }
index 09b51f2..363f2b1 100644 (file)
@@ -97,10 +97,10 @@ int UtcDaliEffectsViewDownCast(void)
 }
 
 // Positive test case for a method
-int UtcDaliEffectsViewAddRemove(void)
+int UtcDaliEffectsViewAddRemoveDropShadow(void)
 {
   ToolkitTestApplication application;
-  tet_infoline("UtcDaliGaussianBlurViewAddRemove");
+  tet_infoline("UtcDaliEffectsViewAddRemoveDropShadow");
 
   EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW );
   DALI_TEST_CHECK( view );
@@ -124,6 +124,70 @@ int UtcDaliEffectsViewAddRemove(void)
   END_TEST;
 }
 
+
+int UtcDaliEffectsViewAddRemoveEmboss(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliEffectsViewAddRemoveEmboss");
+
+  tet_infoline("Checking number of render tasks = 1");
+  application.SendNotification();
+  application.Render();
+  Stage stage = Stage::GetCurrent();
+  DALI_TEST_EQUALS( stage.GetRenderTaskList().GetTaskCount(), 1, TEST_LOCATION );
+
+  tet_infoline("Create effects view");
+
+  EffectsView view = EffectsView::New( EffectsView::EMBOSS );
+  Vector3 offsetSet( 2.f, 3.f, 4.f );
+  Vector4 colorSet( 0.2f, 0.3f, 0.4f, 0.5f );
+  view.SetProperty( EffectsView::Property::EFFECT_OFFSET, offsetSet);
+  view.SetProperty( EffectsView::Property::EFFECT_COLOR, colorSet);
+  Vector3 offsetAnimate( 4.f, 6.f, 8.f );
+  float durationSeconds(0.05f);
+  Animation animation = Animation::New( durationSeconds );
+  animation.AnimateTo( Property(view,EffectsView::Property::EFFECT_OFFSET ), offsetAnimate );
+  animation.Play();
+
+  DALI_TEST_CHECK( view );
+
+  Actor actor = Actor::New();
+  actor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+  DALI_TEST_CHECK( !actor.OnStage() );
+
+  view.SetParentOrigin(ParentOrigin::CENTER);
+
+  view.Add(actor);
+  view.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+
+  stage.Add(view);
+
+  DALI_TEST_CHECK( actor.OnStage() );
+
+  application.SendNotification();
+  application.Render();
+
+  tet_infoline("Removing view from stage disables view");
+  stage.Remove(view);
+
+  tet_infoline("Checking number of render tasks = 1");
+  DALI_TEST_EQUALS( stage.GetRenderTaskList().GetTaskCount(), 1, TEST_LOCATION );
+
+  tet_infoline("Adding view to stage again re-enables view");
+  stage.Add(view);
+
+  tet_infoline("Removing view from stage disables view");
+  DALI_TEST_GREATER( stage.GetRenderTaskList().GetTaskCount(), 1u, TEST_LOCATION );
+  stage.Remove(view);
+  view.Reset();
+
+  tet_infoline("Checking number of render tasks = 1");
+  DALI_TEST_EQUALS( stage.GetRenderTaskList().GetTaskCount(), 1, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
 int UtcDaliEffectsViewGetTypeP(void)
 {
   ToolkitTestApplication application;
index c3eaa4b..1cd8ad6 100644 (file)
@@ -1014,11 +1014,11 @@ int UtcDaliPopupPropertyBackgroundImage(void)
   Popup popup = Popup::New();
   Stage::GetCurrent().Add( popup );
 
-  // Check setting an invalid image.
+  // Check setting an image
   popup.SetProperty( Toolkit::Popup::Property::POPUP_BACKGROUND_IMAGE, "invalid-image.png" );
   std::string resultString;
   popup.GetProperty( Toolkit::Popup::Property::POPUP_BACKGROUND_IMAGE ).Get( resultString );
-  DALI_TEST_EQUALS( resultString, std::string(""), TEST_LOCATION );
+  DALI_TEST_EQUALS( resultString, "invalid-image.png", TEST_LOCATION );
 
   END_TEST;
 }
index 3c121c0..20d5f44 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -223,14 +223,71 @@ int UtcDaliSuperBlurViewSetImage(void)
     Wait(application);
     DALI_TEST_EQUALS(blurView.GetRendererCount(), BLUR_LEVELS+1, TEST_LOCATION );
 
-    application.SendNotification();
-    application.Render();
+    Wait(application);
+    Stage::GetCurrent().Remove( blurView );
+  }
+
+  END_TEST;
+}
+
+int UtcDaliSuperBlurViewSetImage2(void)
+{
+  ToolkitTestApplication application;
+  Stage stage = Stage::GetCurrent();
+
+  tet_infoline(" UtcDaliSuperBlurViewSetImage2 - test setting a second image ");
+
+  SuperBlurView blurView = SuperBlurView::New( BLUR_LEVELS );
+  blurView.SetSize( 100.f, 100.f );
+
+  tet_infoline("Call SetImage and add blurview to stage");
+  Image inputImage = CreateSolidColorImage( application, Color::GREEN, 50, 50 );
+  blurView.SetImage( inputImage );
+
+  // start multiple guassian blur call, each guassian blur creates two render tasks
+  DALI_TEST_CHECK( Stage::GetCurrent().GetRenderTaskList().GetTaskCount() == 1+BLUR_LEVELS*2);
+  {
+    // create image renderers for the original image and each blurred image
+    stage.Add( blurView );
+    Wait(application);
+    DALI_TEST_EQUALS(blurView.GetRendererCount(), BLUR_LEVELS+1, TEST_LOCATION );
+
+    tet_infoline("Wait for a second to allow blur to finish");
+    Wait(application, 1000);
+
+    tet_infoline("Remove from stage");
     Stage::GetCurrent().Remove( blurView );
   }
 
+  tet_infoline("Test that there are no render tasks remaining");
+  DALI_TEST_EQUALS(blurView.GetRendererCount(), 0, TEST_LOCATION );
+
+  tet_infoline("Call SetImage a second time and add blurview back to stage");
+  Image inputImage2 = CreateSolidColorImage( application, Color::CYAN, 50, 50 );
+  blurView.SetImage( inputImage2 );
+  // start multiple guassian blur call, each guassian blur creates two render tasks
+  DALI_TEST_CHECK( Stage::GetCurrent().GetRenderTaskList().GetTaskCount() == 1+BLUR_LEVELS*2);
+
+  {
+    // create image renderers for the original image and each blurred image
+    Stage::GetCurrent().Add( blurView );
+    Wait(application);
+    DALI_TEST_EQUALS(blurView.GetRendererCount(), BLUR_LEVELS+1, TEST_LOCATION );
+
+    tet_infoline("Wait for a second to allow blur to finish");
+    Wait(application, 1000);
+
+    tet_infoline("Remove from stage");
+    Stage::GetCurrent().Remove( blurView );
+  }
+
+  tet_infoline("Test that there are no render tasks remaining");
+  DALI_TEST_EQUALS(blurView.GetRendererCount(), 0, TEST_LOCATION );
+
   END_TEST;
 }
 
+
 int UtcDaliSuperBlurViewSetProperty(void)
 {
   ToolkitTestApplication application;
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-SyncImageLoader.cpp b/automated-tests/src/dali-toolkit/utc-Dali-SyncImageLoader.cpp
new file mode 100644 (file)
index 0000000..d37c5fc
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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 <stdlib.h>
+#include <unistd.h>
+#include <dali/dali.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+namespace
+{
+
+// Resolution: 50*50, pixel format: RGBA8888
+static const char* gImage_50_RGBA = TEST_RESOURCE_DIR "/icon-delete.png";
+
+// Resolution: 128*128, pixel format: RGB888
+static const char* gImage_128_RGB = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
+
+
+void VerifyLoad( PixelData pixelData, uint32_t width, uint32_t height )
+{
+  DALI_TEST_CHECK( pixelData );
+  DALI_TEST_EQUALS<unsigned int>( pixelData.GetWidth(), width, TEST_LOCATION );
+  DALI_TEST_EQUALS<unsigned int>( pixelData.GetHeight(), height, TEST_LOCATION );
+}
+
+} // anonymous namespace
+
+
+int UtcDaliSyncImageLoaderLoad(void)
+{
+  PixelData pixelData = Toolkit::SyncImageLoader::Load( gImage_50_RGBA );
+
+  DALI_TEST_EQUALS<bool>( pixelData, true, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliSyncImageLoaderLoadWithDimensions(void)
+{
+  PixelData pixelData = Toolkit::SyncImageLoader::Load( gImage_50_RGBA, ImageDimensions( 25, 25 ) );
+
+  VerifyLoad( pixelData, 25u, 25u );
+
+  END_TEST;
+}
+
+int UtcDaliSyncImageLoaderLoadWithAllOptions(void)
+{
+  PixelData pixelData = Toolkit::SyncImageLoader::Load( gImage_128_RGB, ImageDimensions( 100, 100 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, true );
+
+  VerifyLoad( pixelData, 100u, 100u );
+
+  END_TEST;
+}
+
+
index 2232cd3..3bb7da1 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/integration-api/events/touch-event-integ.h>
 #include <dali-toolkit/devel-api/controls/tool-bar/tool-bar.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include "dummy-control.h"
 
 using namespace Dali;
 using namespace Toolkit;
@@ -37,14 +38,15 @@ static void TestCallback(BaseHandle handle)
 
 Actor CreateColorActor( const Vector4& color )
 {
-  Actor solidColorActor = Actor::New();
+  DummyControl solidColorActor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(solidColorActor.GetImplementation());
 
   VisualFactory factory = VisualFactory::Get();
   Dali::Property::Map map;
   map[ Visual::Property::TYPE ] = Visual::COLOR;
   map[ ColorVisual::Property::MIX_COLOR ] = color;
   Visual::Base colorVisual = factory.CreateVisual( map );
-  colorVisual.SetOnStage( solidColorActor );
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, colorVisual );
 
   return solidColorActor;
 }
index cc76ea3..d6128c5 100644 (file)
@@ -113,6 +113,41 @@ int UtcDaliVideoViewProperty1(void)
   END_TEST;
 }
 
+// Positive test case for a method
+int UtcDaliVideoViewProperty1b(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliVideoViewProperty1");
+
+  Toolkit::VideoView view = Toolkit::VideoView::New();
+  DALI_TEST_CHECK( view );
+  Stage stage = Stage::GetCurrent();
+
+  std::string file;
+  Property::Map map;
+
+  view.SetProperty( VideoView::Property::VIDEO, Property::Map()
+                    .Add("rendererType", "IMAGE")
+                    .Add("url", "video.mpg") // Note, videoView doesn't use this url
+                    .Add("RENDERING_TARGET", "windowSurfaceTarget" )
+                    .Add("width", 100)
+                    .Add("height", 100) );
+
+  stage.Add( view );
+
+  Property::Value val = view.GetProperty( VideoView::Property::VIDEO );
+  Property::Map* resultMap = val.GetMap();
+
+  DALI_TEST_CHECK( resultMap );
+  Property::Value* value = resultMap->Find("url");
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "video.mpg", TEST_LOCATION );
+
+  stage.Remove( view );
+
+  END_TEST;
+}
+
 int UtcDaliVideoViewProperty2(void)
 {
   ToolkitTestApplication application;
@@ -150,6 +185,7 @@ int UtcDaliVideoViewProperty3(void)
   val = view.GetProperty( VideoView::Property::MUTED );
   DALI_TEST_CHECK( val.Get( muted ) );
   DALI_TEST_CHECK( muted );
+
   END_TEST;
 }
 
index 779f808..8a70c7d 100644 (file)
@@ -147,17 +147,20 @@ int UtcDaliVisualSetGetDepthIndex(void)
 
   visual.SetDepthIndex( 1.f );
 
-  Actor actor = Actor::New();
-  actor.SetSize(200.f, 200.f);
-  Stage::GetCurrent().Add( actor );
-  visual.SetOnStage( actor );
+  DummyControl dummyControl = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(dummyControl.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+
+  dummyControl.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( dummyControl );
 
-  int depthIndex = actor.GetRendererAt(0u).GetProperty<int>( Renderer::Property::DEPTH_INDEX );
+
+  int depthIndex = dummyControl.GetRendererAt(0u).GetProperty<int>( Renderer::Property::DEPTH_INDEX );
   DALI_TEST_EQUALS( depthIndex, 1, TEST_LOCATION );
   DALI_TEST_EQUALS( visual.GetDepthIndex(), 1.f, TEST_LOCATION );
 
   visual.SetDepthIndex( -1.f );
-  depthIndex = actor.GetRendererAt(0u).GetProperty<int>( Renderer::Property::DEPTH_INDEX );
+  depthIndex = dummyControl.GetRendererAt(0u).GetProperty<int>( Renderer::Property::DEPTH_INDEX );
   DALI_TEST_EQUALS( depthIndex, -1, TEST_LOCATION );
   DALI_TEST_EQUALS( visual.GetDepthIndex(), -1.f, TEST_LOCATION );
 
@@ -191,16 +194,7 @@ int UtcDaliVisualSize(void)
   imageVisual.GetNaturalSize(naturalSize);
   DALI_TEST_EQUALS( naturalSize, Vector2(100.f, 200.f), TEST_LOCATION );
 
-  // n patch visual
-  TestPlatformAbstraction& platform = application.GetPlatform();
-  Vector2 testSize(80.f, 160.f);
-  platform.SetClosestImageSize(testSize);
-  image = ResourceImage::New(TEST_NPATCH_FILE_NAME);
-  Visual::Base nPatchVisual = factory.CreateVisual( image );
-  nPatchVisual.SetSize( visualSize );
-  DALI_TEST_EQUALS( nPatchVisual.GetSize(), visualSize, TEST_LOCATION );
-  nPatchVisual.GetNaturalSize(naturalSize);
-  DALI_TEST_EQUALS( naturalSize, testSize, TEST_LOCATION );
+  // n patch visual is tested in the utc-Dali-VisualFactory.cpp
 
   // border visual
   float borderSize = 5.f;
@@ -250,6 +244,9 @@ int UtcDaliVisualSize(void)
   DALI_TEST_EQUALS( naturalSize, Vector2(100.f, 100.f), TEST_LOCATION ); // Natural size should still be 100, 100
 
   // Batch Image visual
+  TestPlatformAbstraction& platform = application.GetPlatform();
+  Vector2 testSize(80.f, 160.f);
+  platform.SetClosestImageSize(testSize);
   propertyMap.Clear();
   propertyMap.Insert( Visual::Property::TYPE, Visual::IMAGE );
   propertyMap.Insert( ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME );
@@ -299,68 +296,32 @@ int UtcDaliVisualSetOnOffStage(void)
   propertyMap.Insert(ColorVisual::Property::MIX_COLOR,  Color::BLUE);
   Visual::Base visual = factory.CreateVisual( propertyMap );
 
-  Actor actor = Actor::New();
-  actor.SetSize(200.f, 200.f);
-  Stage::GetCurrent().Add( actor );
-
-  application.SendNotification();
-  application.Render(0);
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
 
-  visual.SetOnStage( actor );
-  application.SendNotification();
-  application.Render(0);
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  actor.SetSize(200.f, 200.f);
 
-  visual.SetOffStage( actor );
   application.SendNotification();
   application.Render(0);
   DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
 
-  END_TEST;
-}
-
-int UtcDaliVisualRemoveAndReset(void)
-{
-  ToolkitTestApplication application;
-  tet_infoline( "intUtcDaliVisualRemoveAndReset" );
-
-  VisualFactory factory = VisualFactory::Get();
-
-  Actor actor = Actor::New();
-  actor.SetSize(200.f, 200.f);
   Stage::GetCurrent().Add( actor );
 
-  Visual::Base imageVisual;
-  // test calling RemoveAndReset with an empty handle
-  try
-  {
-    imageVisual.RemoveAndReset( actor );
-    tet_result(TET_PASS);
-  }
-  catch (DaliException& exception)
-  {
-    tet_result(TET_FAIL);
-  }
-
-  Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME, ImageDimensions(100, 200));
-  imageVisual = factory.CreateVisual(image);
-  DALI_TEST_CHECK( imageVisual );
-
-  imageVisual.SetOnStage( actor );
   application.SendNotification();
   application.Render(0);
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
 
-  imageVisual.RemoveAndReset( actor );
+  Stage::GetCurrent().Remove( actor );
+
   application.SendNotification();
   application.Render(0);
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); // visual is removed from actor
-  DALI_TEST_CHECK( !imageVisual ); // visual is reset
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
 
   END_TEST;
 }
 
+
 int UtcDaliVisualGetPropertyMap1(void)
 {
   ToolkitTestApplication application;
@@ -384,8 +345,6 @@ int UtcDaliVisualGetPropertyMap1(void)
   DALI_TEST_CHECK( colorValue->Get<Vector4>() == Color::BLUE );
 
   // change the blend color
-  Actor actor;
-  colorVisual.RemoveAndReset( actor );
   propertyMap[ColorVisual::Property::MIX_COLOR] = Color::CYAN;
   colorVisual = factory.CreateVisual( propertyMap  );
   colorVisual.CreatePropertyMap( resultMap );
@@ -662,19 +621,6 @@ int UtcDaliVisualGetPropertyMap5(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_CHECK( value->Get<bool>() == true );
 
-  // Test the properties..
-  Property::Value imageValue = imageVisual.GetProperty( ImageVisual::Property::URL );
-  DALI_TEST_CHECK( imageValue.Get<std::string>() == TEST_IMAGE_FILE_NAME );
-
-  // Other Properties for Image Visual can be tested here once implemented in the Visual
-
-  tet_infoline( "UtcDaliVisualGetPropertyMap5 Ensuring Property without a Getter is not problematic" );
-  imageValue = imageVisual.GetProperty( ImageVisual::Property::DESIRED_HEIGHT );
-  DALI_TEST_CHECK( imageValue.Get<int>()  != 30 );
-
-
-  // Rest of test uses Image not an url ( legacy )
-
   // Get an image visual with an image handle, and test the default property values
   Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME, ImageDimensions(100, 200));
   imageVisual = factory.CreateVisual(image);
@@ -728,13 +674,11 @@ int UtcDaliVisualGetPropertyMap6(void)
   ToolkitTestApplication application;
   tet_infoline( "UtcDaliVisualGetPropertyMap6: NPatchVisual" );
 
-  bool BORDER_ONLY_SETTING = true;
-
   VisualFactory factory = VisualFactory::Get();
   Property::Map propertyMap;
   propertyMap.Insert( Visual::Property::TYPE,  Visual::IMAGE );
   propertyMap.Insert( ImageVisual::Property::URL,  TEST_NPATCH_FILE_NAME );
-  propertyMap.Insert( ImageVisual::Property::BORDER_ONLY,  BORDER_ONLY_SETTING );
+  propertyMap.Insert( ImageVisual::Property::BORDER_ONLY,  true );
   Visual::Base nPatchVisual = factory.CreateVisual( propertyMap );
 
   Property::Map resultMap;
@@ -753,19 +697,6 @@ int UtcDaliVisualGetPropertyMap6(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_CHECK( value->Get<bool>() );
 
-  // Test the properties via Index.
-  nPatchVisual.SetProperty( ImageVisual::Property::URL, TEST_NPATCH_FILE_NAME ); // May not able to change URL in future using SetProperty
-  Property::Value nPatchValue = nPatchVisual.GetProperty( ImageVisual::Property::URL );
-  DALI_TEST_CHECK( nPatchValue.Get<std::string>() == TEST_NPATCH_FILE_NAME );
-
-  nPatchValue = nPatchVisual.GetProperty( ImageVisual::Property::BORDER_ONLY );
-  DALI_TEST_CHECK( nPatchValue.Get<bool>() == BORDER_ONLY_SETTING );
-
-  // Other Properties for N-Patch Visual can be tested here once implemented in the Visual
-
-  tet_infoline( "UtcDaliVisualGetPropertyMap6 Ensuring Property without a Getter is not problematic" );
-  nPatchValue = nPatchVisual.GetProperty( ImageVisual::Property::DESIRED_HEIGHT );
-  DALI_TEST_CHECK( nPatchValue.Get<int>()  != 30 );
 
   END_TEST;
 }
@@ -1081,8 +1012,7 @@ int UtcDaliVisualGetPropertyMap10(void)
   DALI_TEST_CHECK( !value->Get<bool>() );
 
   value = resultMap.Find( TextVisual::Property::ENABLE_AUTO_SCROLL, Property::BOOLEAN );
-  DALI_TEST_CHECK( value );
-  DALI_TEST_CHECK( !value->Get<bool>() );
+  DALI_TEST_CHECK( !value );
 
   value = resultMap.Find( TextVisual::Property::LINE_SPACING, Property::FLOAT );
   DALI_TEST_CHECK( value );
@@ -1115,10 +1045,12 @@ int UtcDaliVisualGetPropertyMapBatchImageVisualNoAtlas(void)
 
   DALI_TEST_CHECK( batchImageVisual );
 
-  Actor actor = Actor::New();
-  batchImageVisual.SetOnStage( actor );
+  DummyControl dummyControl = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(dummyControl.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, batchImageVisual );
+  Stage::GetCurrent().Add( dummyControl );
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  DALI_TEST_CHECK( dummyControl.GetRendererCount() == 1u );
 
   END_TEST;
 }
@@ -1135,11 +1067,12 @@ int UtcDaliVisualAnimateBorderVisual01(void)
   propertyMap.Insert(BorderVisual::Property::SIZE,  5.f);
   Visual::Base borderVisual = factory.CreateVisual( propertyMap );
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, borderVisual );
   actor.SetSize(2000, 2000);
   actor.SetParentOrigin(ParentOrigin::CENTER);
   Stage::GetCurrent().Add(actor);
-  borderVisual.SetOnStage( actor );
 
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
 
@@ -1181,11 +1114,12 @@ int UtcDaliVisualAnimateBorderVisual02(void)
   propertyMap.Insert(BorderVisual::Property::SIZE,  5.f);
   Visual::Base borderVisual = factory.CreateVisual( propertyMap );
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, borderVisual );
   actor.SetSize(2000, 2000);
   actor.SetParentOrigin(ParentOrigin::CENTER);
   Stage::GetCurrent().Add(actor);
-  borderVisual.SetOnStage( actor );
 
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
 
@@ -1224,11 +1158,12 @@ int UtcDaliVisualAnimateColorVisual(void)
   propertyMap.Insert(ColorVisual::Property::MIX_COLOR, Color::BLUE);
   Visual::Base borderVisual = factory.CreateVisual( propertyMap );
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, borderVisual );
   actor.SetSize(2000, 2000);
   actor.SetParentOrigin(ParentOrigin::CENTER);
   Stage::GetCurrent().Add(actor);
-  borderVisual.SetOnStage( actor );
 
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
 
@@ -1272,12 +1207,13 @@ int UtcDaliVisualAnimatePrimitiveVisual(void)
   propertyMap.Insert(ColorVisual::Property::MIX_COLOR, Color::BLUE);
   Visual::Base borderVisual = factory.CreateVisual( propertyMap );
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, borderVisual );
   actor.SetSize(2000, 2000);
   actor.SetParentOrigin(ParentOrigin::CENTER);
   actor.SetColor(Color::BLACK);
   Stage::GetCurrent().Add(actor);
-  borderVisual.SetOnStage( actor );
 
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
 
@@ -1421,10 +1357,13 @@ static void TestTransform( ToolkitTestApplication& application, Visual::Base vis
   }
 
   //Put the visual on the stage
-  Actor actor = Actor::New();
-  actor.SetSize(200.f, 200.f);
-  Stage::GetCurrent().Add( actor );
-  visual.SetOnStage( actor );
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+  actor.SetSize(2000, 2000);
+  actor.SetParentOrigin(ParentOrigin::CENTER);
+  Stage::GetCurrent().Add(actor);
+
   application.SendNotification();
   application.Render(0);
   Renderer renderer( actor.GetRendererAt(0) );
@@ -1617,4 +1556,77 @@ int UtcDaliVisualSetTransform7(void)
   END_TEST;
 }
 
+int UtcDaliNPatchVisualCustomShader(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "NPatchVisual with custom shader" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map properties;
+  Property::Map shader;
+  const std::string fragmentShader = "Foobar";
+  shader[Dali::Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = fragmentShader;
+  properties[Dali::Toolkit::Visual::Property::TYPE] = Dali::Toolkit::Visual::IMAGE;
+  properties[Dali::Toolkit::Visual::Property::SHADER]=shader;
+  properties[Dali::Toolkit::ImageVisual::Property::URL] = TEST_NPATCH_FILE_NAME;
+
+  Visual::Base visual = factory.CreateVisual( properties );
+
+  // trigger creation through setting on stage
+  DummyControl dummy = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(dummy.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+  dummy.SetSize(2000, 2000);
+  dummy.SetParentOrigin(ParentOrigin::CENTER);
+  Stage::GetCurrent().Add(dummy);
+
+  Renderer renderer = dummy.GetRendererAt( 0 );
+  Shader shader2 = renderer.GetShader();
+  Property::Value value = shader2.GetProperty( Shader::Property::PROGRAM );
+  Property::Map* map = value.GetMap();
+  DALI_TEST_CHECK( map );
+
+  Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp
+  // *map["vertex"]; is default here so not verifying it
+
+  DALI_TEST_EQUALS( fragmentShader, fragment->Get<std::string>(), TEST_LOCATION );
+
+  END_TEST;
+}
+int UtcDaliGradientVisualBlendMode(void)
+{
+  ToolkitTestApplication application;
+  VisualFactory factory = VisualFactory::Get();
 
+  Visual::Base opaqueGradientVisual = factory.CreateVisual(
+      Property::Map().Add( Visual::Property::TYPE, Visual::GRADIENT )
+                     .Add( GradientVisual::Property::START_POSITION, Vector2( -0.5f, -0.5f ) )
+                     .Add( GradientVisual::Property::END_POSITION, Vector2( 0.5f, 0.5f ) )
+                     .Add( GradientVisual::Property::STOP_COLOR, Property::Array().Add( Color::RED )
+                                                                                  .Add( Color::GREEN ) ) );
+
+  Visual::Base alphaGradientVisual = factory.CreateVisual(
+      Property::Map().Add( Visual::Property::TYPE, Visual::GRADIENT )
+                     .Add( GradientVisual::Property::START_POSITION, Vector2( -0.5f, -0.5f ) )
+                     .Add( GradientVisual::Property::END_POSITION, Vector2( 0.5f, 0.5f ) )
+                     .Add( GradientVisual::Property::STOP_COLOR, Property::Array().Add( Color::RED )
+                                                                                  .Add( Vector4( 1.0f, 1.0f, 1.0f, 0.5f ) ) ) );
+
+  DummyControl control = DummyControl::New();
+  control.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+  Stage::GetCurrent().Add( control );
+
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>( control.GetImplementation() );
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, opaqueGradientVisual );
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 2, alphaGradientVisual );
+
+  application.SendNotification();
+  application.Render();
+
+  // Control should have two renderers, the first one is opaque so our blending mode should be off, the second one has some alpha so should be set to automatic
+  DALI_TEST_EQUALS( 2u, control.GetRendererCount(), TEST_LOCATION );
+  DALI_TEST_EQUALS( control.GetRendererAt( 0 ).GetProperty( Renderer::Property::BLEND_MODE ).Get<int>(), (int)BlendMode::OFF, TEST_LOCATION );
+  DALI_TEST_EQUALS( control.GetRendererAt( 1 ).GetProperty( Renderer::Property::BLEND_MODE ).Get<int>(), (int)BlendMode::AUTO, TEST_LOCATION );
+
+  END_TEST;
+}
index 3fe52b4..7d36ae6 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali/devel-api/images/nine-patch-image.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/dali-toolkit.h>
+#include "dummy-control.h"
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -181,12 +182,15 @@ Integration::ResourcePointer CustomizeNinePatch( TestApplication& application,
 }
 
 void TestVisualRender( ToolkitTestApplication& application,
-                                Actor& actor,
-                                Visual::Base& visual,
-                                std::size_t expectedSamplers = 0,
-                                ImageDimensions imageDimensions = ImageDimensions(),
-                                Integration::ResourcePointer resourcePtr = Integration::ResourcePointer())
+                       DummyControl& actor,
+                       Visual::Base& visual,
+                       std::size_t expectedSamplers = 0,
+                       ImageDimensions imageDimensions = ImageDimensions(),
+                       Integration::ResourcePointer resourcePtr = Integration::ResourcePointer())
 {
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+
   if( resourcePtr )
   {
     // set the image size, for test case, this needs to be set before loading started
@@ -194,11 +198,9 @@ void TestVisualRender( ToolkitTestApplication& application,
   }
 
   actor.SetSize( 200.f, 200.f );
-  Stage::GetCurrent().Add( actor );
-  visual.SetSize( Vector2(200.f, 200.f) );
-  visual.SetOnStage( actor );
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  Stage::GetCurrent().Add( actor );
 
   application.SendNotification();
   application.Render();
@@ -217,11 +219,11 @@ void TestVisualRender( ToolkitTestApplication& application,
 
   if( resourcePtr )
   {
-    DALI_TEST_CHECK( application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc) ||
-                     application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceSynchronouslyFunc ));
+    DALI_TEST_EQUALS( application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc) ||
+                      application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceSynchronouslyFunc ), true, TEST_LOCATION);
   }
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
 
 }
 
@@ -307,7 +309,7 @@ int UtcDaliVisualFactoryGetColorVisual1(void)
   Visual::Base visual = factory.CreateVisual(propertyMap);
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
   TestVisualRender( application, actor, visual );
 
   Vector4 actualValue(Vector4::ZERO);
@@ -333,7 +335,7 @@ int UtcDaliVisualFactoryGetColorVisual2(void)
   Visual::Base visual = factory.CreateVisual( map );
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
   TestVisualRender( application, actor, visual );
 
   Vector4 actualValue(Vector4::ZERO);
@@ -341,7 +343,7 @@ int UtcDaliVisualFactoryGetColorVisual2(void)
   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "mixColor", actualValue ) );
   DALI_TEST_EQUALS( actualValue, testColor, TEST_LOCATION );
 
-  visual.SetOffStage( actor );
+  Stage::GetCurrent().Remove(actor);
   DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
 
   END_TEST;
@@ -365,11 +367,12 @@ int UtcDaliVisualFactoryGetBorderVisual1(void)
   Visual::Base visual = factory.CreateVisual(propertyMap);
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   actor.SetSize(200.f, 200.f);
   Stage::GetCurrent().Add( actor );
   visual.SetSize(Vector2(200.f, 200.f));
-  visual.SetOnStage( actor );
 
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
   int blendMode = actor.GetRendererAt(0u).GetProperty<int>( Renderer::Property::BLEND_MODE );
@@ -388,7 +391,7 @@ int UtcDaliVisualFactoryGetBorderVisual1(void)
   DALI_TEST_CHECK( gl.GetUniformValue<float>( "borderSize", actualSize ) );
   DALI_TEST_EQUALS( actualSize, testSize, TEST_LOCATION );
 
-  visual.SetOffStage( actor );
+  actor.Unparent();
   DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
 
   END_TEST;
@@ -412,11 +415,12 @@ int UtcDaliVisualFactoryGetBorderVisual2(void)
   Visual::Base visual = factory.CreateVisual( propertyMap );
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   actor.SetSize(200.f, 200.f);
   Stage::GetCurrent().Add( actor );
   visual.SetSize(Vector2(200.f, 200.f));
-  visual.SetOnStage( actor );
 
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
 
@@ -436,7 +440,7 @@ int UtcDaliVisualFactoryGetBorderVisual2(void)
   DALI_TEST_CHECK( gl.GetUniformValue<float>( "borderSize", actualSize ) );
   DALI_TEST_EQUALS( actualSize, testSize, TEST_LOCATION );
 
-  visual.SetOffStage( actor );
+  actor.Unparent();
 
   // enable the anti-aliasing
   Dali::Property::Map map;
@@ -445,10 +449,10 @@ int UtcDaliVisualFactoryGetBorderVisual2(void)
   map[ BorderVisual::Property::SIZE   ] = testSize;
   map[ BorderVisual::Property::ANTI_ALIASING   ] = true;
   visual = factory.CreateVisual( map );
-  visual.SetOnStage( actor );
 
-  application.SendNotification();
-  application.Render(0);
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+  Stage::GetCurrent().Add( actor );
+
   blendMode = actor.GetRendererAt(0u).GetProperty<int>( Renderer::Property::BLEND_MODE );
   DALI_TEST_EQUALS( static_cast<BlendMode::Type>(blendMode), BlendMode::ON, TEST_LOCATION );
 
@@ -486,11 +490,8 @@ int UtcDaliVisualFactoryGetLinearGradientVisual(void)
   DALI_TEST_CHECK( visual );
 
   // A lookup texture is generated and pass to shader as sampler
-  Actor actor = Actor::New();
-  TestVisualRender( application, actor, visual, 1u );
-
-  visual.SetOffStage( actor );
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  DummyControl actor = DummyControl::New();
+  TestVisualRender( application, actor, visual, 1u);
 
   END_TEST;
 }
@@ -526,7 +527,7 @@ int UtcDaliVisualFactoryGetRadialGradientVisual(void)
   DALI_TEST_CHECK( visual );
 
   // A lookup texture is generated and pass to shader as sampler
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
   TestVisualRender( application, actor, visual, 1u );
 
   Matrix3 alignMatrix( radius, 0.f, 0.f, 0.f, radius, 0.f, center.x, center.y, 1.f );
@@ -566,10 +567,10 @@ int UtcDaliVisualFactoryDefaultOffsetsGradientVisual(void)
   DALI_TEST_CHECK( visual );
 
   // A lookup texture is generated and pass to shader as sampler
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
   TestVisualRender( application, actor, visual, 1u );
 
-  visual.SetOffStage( actor );
+  Stage::GetCurrent().Remove( actor );
   DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
 
   END_TEST;
@@ -590,7 +591,6 @@ int UtcDaliVisualFactoryGetImageVisual1(void)
   Visual::Base visual = factory.CreateVisual( propertyMap );
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
   // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied.
   // Image with a size smaller than 512*512 will be uploaded as a part of the atlas.
 
@@ -603,13 +603,14 @@ int UtcDaliVisualFactoryGetImageVisual1(void)
   Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, width, height,width, height );
 
+  DummyControl actor = DummyControl::New();
   TestVisualRender( application, actor, visual, 1u,
-                             ImageDimensions(width, height),
-                             Integration::ResourcePointer( bitmap ) );
+                    ImageDimensions(width, height),
+                    Integration::ResourcePointer( bitmap ) );
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
-  visual.SetOffStage( actor );
+  Stage::GetCurrent().Remove( actor );
   DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
 
   END_TEST;
@@ -626,7 +627,6 @@ int UtcDaliVisualFactoryGetImageVisual2(void)
   Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME);
   Visual::Base visual = factory.CreateVisual( image );
 
-  Actor actor = Actor::New();
   // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied.
   // Image with a size smaller than 512*512 will be uploaded as a part of the atlas.
 
@@ -640,12 +640,12 @@ int UtcDaliVisualFactoryGetImageVisual2(void)
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
 
+  DummyControl actor = DummyControl::New();
   TestVisualRender( application, actor, visual, 1u,
-                             ImageDimensions(width, height),
-                             Integration::ResourcePointer(bitmap) );
+                    ImageDimensions(width, height),
+                    Integration::ResourcePointer(bitmap) );
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
-
   END_TEST;
 }
 
@@ -675,16 +675,18 @@ int UtcDaliVisualFactoryGetImageVisual3(void)
   Visual::Base visual = factory.CreateVisual( propertyMap );
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
   TestGlAbstraction& gl = application.GetGlAbstraction();
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
   TraceCallStack& texParameterTrace = gl.GetTexParameterTrace();
   texParameterTrace.Enable( true );
 
-  actor.SetSize( 200.f, 200.f );
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+  actor.SetSize(2000, 2000);
+  actor.SetParentOrigin(ParentOrigin::CENTER);
   Stage::GetCurrent().Add( actor );
-  visual.SetOnStage( actor );
 
   // loading started
   application.SendNotification();
@@ -725,7 +727,7 @@ int UtcDaliVisualFactoryGetImageVisual3(void)
   DALI_TEST_CHECK( gl.GetUniformValue<Vector2>( "wrapMode", wrapModeUniform ) );
   DALI_TEST_EQUALS( wrapMode, wrapModeUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION );
 
-  visual.SetOffStage( actor );
+  actor.Unparent( );
   DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
 
   END_TEST;
@@ -757,16 +759,18 @@ int UtcDaliVisualFactoryGetImageVisual4(void)
   Visual::Base visual = factory.CreateVisual( propertyMap );
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
   TestGlAbstraction& gl = application.GetGlAbstraction();
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
   TraceCallStack& texParameterTrace = gl.GetTexParameterTrace();
   texParameterTrace.Enable( true );
 
-  actor.SetSize( 200.f, 200.f );
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+  actor.SetSize(2000, 2000);
+  actor.SetParentOrigin(ParentOrigin::CENTER);
   Stage::GetCurrent().Add( actor );
-  visual.SetOnStage( actor );
 
   // loading started
   application.SendNotification();
@@ -803,7 +807,7 @@ int UtcDaliVisualFactoryGetImageVisual4(void)
   Property::Index wrapModeIndex = renderer.GetPropertyIndex( "wrapMode" );
   DALI_TEST_CHECK(wrapModeIndex == Property::INVALID_INDEX);
 
-  visual.SetOffStage( actor );
+  actor.Unparent();
   DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
 
   END_TEST;
@@ -833,15 +837,15 @@ int UtcDaliVisualFactoryGetNPatchVisual1(void)
     Visual::Base visual = factory.CreateVisual( propertyMap );
     DALI_TEST_CHECK( visual );
 
-    Actor actor = Actor::New();
 
     TestGlAbstraction& gl = application.GetGlAbstraction();
     TraceCallStack& textureTrace = gl.GetTextureTrace();
     textureTrace.Enable(true);
 
+    DummyControl actor = DummyControl::New();
     TestVisualRender( application, actor, visual, 1u,
-                               ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
-                               ninePatchResource );
+                      ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
+                      ninePatchResource );
 
     DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
   }
@@ -852,15 +856,14 @@ int UtcDaliVisualFactoryGetNPatchVisual1(void)
     Visual::Base visual = factory.CreateVisual( propertyMap );
     DALI_TEST_CHECK( visual );
 
-    Actor actor = Actor::New();
-
     TestGlAbstraction& gl = application.GetGlAbstraction();
     TraceCallStack& textureTrace = gl.GetTextureTrace();
     textureTrace.Enable(true);
 
+    DummyControl actor = DummyControl::New();
     TestVisualRender( application, actor, visual, 1u,
-                               ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
-                               ninePatchResource );
+                      ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
+                      ninePatchResource );
 
     DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
   }
@@ -896,19 +899,18 @@ int UtcDaliVisualFactoryGetNPatchVisual2(void)
     Visual::Base visual = factory.CreateVisual( propertyMap );
     DALI_TEST_CHECK( visual );
 
-    Actor actor = Actor::New();
     TestGlAbstraction& gl = application.GetGlAbstraction();
     TraceCallStack& textureTrace = gl.GetTextureTrace();
     textureTrace.Enable(true);
 
+    DummyControl actor = DummyControl::New();
     TestVisualRender( application, actor, visual, 1u,
-                               ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
-                               ninePatchResource );
-
+                      ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
+                      ninePatchResource );
 
     DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
-    visual.SetOffStage( actor );
+    Stage::GetCurrent().Remove( actor );
     DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
   }
 
@@ -921,15 +923,15 @@ int UtcDaliVisualFactoryGetNPatchVisual2(void)
     TestGlAbstraction& gl = application.GetGlAbstraction();
     TraceCallStack& textureTrace = gl.GetTextureTrace();
     textureTrace.Enable(true);
-    Actor actor = Actor::New();
+    DummyControl actor = DummyControl::New();
     TestVisualRender( application, actor, visual, 1u,
-                               ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
-                               ninePatchResource );
+                      ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
+                      ninePatchResource );
 
 
     DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
-    visual.SetOffStage( actor );
+    Stage::GetCurrent().Remove( actor );
     DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
   }
 
@@ -955,18 +957,26 @@ int UtcDaliVisualFactoryGetNPatchVisual3(void)
   Visual::Base visual = factory.CreateVisual( TEST_NPATCH_FILE_NAME, ImageDimensions() );
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
-
   TestGlAbstraction& gl = application.GetGlAbstraction();
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
 
+  DummyControl actor = DummyControl::New();
   TestVisualRender( application, actor, visual, 1u,
-                             ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
-                             ninePatchResource );
+                    ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
+                    ninePatchResource );
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
+
+  ResourceImage image = ResourceImage::New(TEST_NPATCH_FILE_NAME);
+  Visual::Base nPatchVisual = factory.CreateVisual( image );
+  Vector2 visualSize( 20.f, 30.f ), naturalSize(0,0);
+  nPatchVisual.SetSize( visualSize );
+  DALI_TEST_EQUALS( nPatchVisual.GetSize(), visualSize, TEST_LOCATION );
+  nPatchVisual.GetNaturalSize( naturalSize );
+  DALI_TEST_EQUALS( naturalSize, Vector2( ninePatchImageWidth-2, ninePatchImageHeight-2 ), TEST_LOCATION );
+
   END_TEST;
 }
 
@@ -994,15 +1004,14 @@ int UtcDaliVisualFactoryGetNPatchVisual4(void)
   Visual::Base visual = factory.CreateVisual( TEST_NPATCH_FILE_NAME, ImageDimensions() );
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
-
   TestGlAbstraction& gl = application.GetGlAbstraction();
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
 
+  DummyControl actor = DummyControl::New();
   TestVisualRender( application, actor, visual, 1u,
-                             ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
-                             ninePatchResource );
+                    ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
+                    ninePatchResource );
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
@@ -1022,8 +1031,6 @@ int UtcDaliVisualFactoryGetNPatchVisualN1(void)
   Visual::Base visual = factory.CreateVisual( "ERROR.9.jpg", ImageDimensions() );
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
-
   //The testkit still has to load a bitmap for the broken renderer image
   Integration::Bitmap* bitmap = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 100, 100, 100, 100 );
@@ -1032,9 +1039,10 @@ int UtcDaliVisualFactoryGetNPatchVisualN1(void)
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
 
+  DummyControl actor = DummyControl::New();
   TestVisualRender( application, actor, visual, 1u,
-                             ImageDimensions(),
-                             Integration::ResourcePointer(bitmap) );
+                    ImageDimensions(),
+                    Integration::ResourcePointer(bitmap) );
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
@@ -1058,8 +1066,6 @@ int UtcDaliVisualFactoryGetNPatchVisualN2(void)
   Visual::Base visual = factory.CreateVisual( propertyMap );
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
-
   //The testkit still has to load a bitmap for the broken renderer image
   Integration::Bitmap* bitmap = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 100, 100, 100, 100 );
@@ -1067,10 +1073,13 @@ int UtcDaliVisualFactoryGetNPatchVisualN2(void)
   TestGlAbstraction& gl = application.GetGlAbstraction();
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
+  TraceCallStack& drawTrace = gl.GetDrawTrace();
+  drawTrace.Enable(true);
 
+  DummyControl actor = DummyControl::New();
   TestVisualRender( application, actor, visual, 1u,
-                             ImageDimensions(),
-                             Integration::ResourcePointer(bitmap) );
+                    ImageDimensions(),
+                    Integration::ResourcePointer(bitmap) );
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
@@ -1110,11 +1119,13 @@ int UtcDaliVisualFactoryGetSvgVisual(void)
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   actor.SetSize( 200.f, 200.f );
   Stage::GetCurrent().Add( actor );
   visual.SetSize( Vector2(200.f, 200.f) );
-  visual.SetOnStage( actor );
+
   application.SendNotification();
   application.Render();
 
@@ -1152,9 +1163,11 @@ int UtcDaliVisualFactoryGetSvgVisualLarge(void)
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   Stage::GetCurrent().Add( actor );
-  visual.SetOnStage( actor );
+
   application.SendNotification();
   application.Render();
 
@@ -1191,11 +1204,12 @@ void MeshVisualLoadsCorrectlyTest( Property::Map& propertyMap, ToolkitTestApplic
   DALI_TEST_CHECK( visual );
 
   //Create an actor on stage to house the visual.
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   actor.SetSize( 200.f, 200.f );
   Stage::GetCurrent().Add( actor );
   visual.SetSize( Vector2( 200.f, 200.f ) );
-  visual.SetOnStage( actor );
 
   //Ensure set on stage.
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
@@ -1221,7 +1235,7 @@ void MeshVisualLoadsCorrectlyTest( Property::Map& propertyMap, ToolkitTestApplic
   DALI_TEST_EQUALS( actualScaleMatrix, testScaleMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION );
 
   //Finish by setting off stage, and ensuring this was successful.
-  visual.SetOffStage( actor );
+  actor.Unparent();
   DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
 }
 
@@ -1237,11 +1251,12 @@ void MeshVisualDoesNotLoadCorrectlyTest( Property::Map& propertyMap, ToolkitTest
   DALI_TEST_CHECK( visual );
 
   //Create an actor on stage to house the visual.
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   actor.SetSize( 200.f, 200.f );
   Stage::GetCurrent().Add( actor );
   visual.SetSize( Vector2( 200.f, 200.f ) );
-  visual.SetOnStage( actor );
 
   //Ensure set on stage.
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
@@ -1263,7 +1278,7 @@ void MeshVisualDoesNotLoadCorrectlyTest( Property::Map& propertyMap, ToolkitTest
   DALI_TEST_CHECK( !application.GetGlAbstraction().GetUniformValue<Matrix>( "uObjectMatrix", scaleMatrix ) );
 
   //Finish by setting off stage, and ensuring this was successful.
-  visual.SetOffStage( actor );
+  actor.Unparent();
   DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
 }
 
@@ -1517,11 +1532,13 @@ void TestPrimitiveVisualWithProperties( Property::Map& propertyMap, ToolkitTestA
   DALI_TEST_CHECK( visual );
 
   //Create an actor on stage to house the visual.
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+
   actor.SetSize( 200.f, 200.f );
   Stage::GetCurrent().Add( actor );
   visual.SetSize( Vector2( 200.f, 200.f ) );
-  visual.SetOnStage( actor );
 
   //Ensure set on stage.
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
@@ -1539,7 +1556,7 @@ void TestPrimitiveVisualWithProperties( Property::Map& propertyMap, ToolkitTestA
   DALI_TEST_EQUALS( actualScaleMatrix, testScaleMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION );
 
   //Finish by setting off stage, and ensuring this was successful.
-  visual.SetOffStage( actor );
+  actor.Unparent();
   DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
 }
 
@@ -1936,21 +1953,22 @@ int UtcDaliVisualFactoryGetBatchImageVisual1(void)
   Visual::Base visual = factory.CreateVisual( propertyMap );
   DALI_TEST_CHECK( visual );
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
 
   actor.SetSize( 200.0f, 200.0f );
   Stage::GetCurrent().Add( actor );
   visual.SetSize( Vector2( 200.0f, 200.0f ) );
 
   // Test SetOnStage().
-  visual.SetOnStage( actor );
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
 
   application.SendNotification();
   application.Render();
 
   // Test SetOffStage().
-  visual.SetOffStage( actor );
+  actor.Unparent();
   DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
 
   END_TEST;
@@ -1984,21 +2002,22 @@ int UtcDaliVisualFactoryGetBatchImageVisual2(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_EQUALS( value->Get<int>(), (int)Visual::IMAGE, TEST_LOCATION );
 
-  Actor actor = Actor::New();
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
 
   actor.SetSize( 200.0f, 200.0f );
   Stage::GetCurrent().Add( actor );
   visual.SetSize( Vector2( 200.0f, 200.0f ) );
 
   // Test SetOnStage().
-  visual.SetOnStage( actor );
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
 
   application.SendNotification();
   application.Render();
 
   // Test SetOffStage().
-  visual.SetOffStage( actor );
+  actor.Unparent();
   DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
 
   END_TEST;
index fd09527..166feb4 100644 (file)
@@ -111,7 +111,7 @@ develapiprogressbardir =        $(develapicontrolsdir)/progress-bar
 develapishadowviewdir =         $(develapicontrolsdir)/shadow-view
 develapisuperblurviewdir =      $(develapicontrolsdir)/super-blur-view
 develapifocusmanagerdir =       $(develapidir)/focus-manager
-develapiimageloaderdir =         $(develapidir)/image-loader
+develapiimageloaderdir =        $(develapidir)/image-loader
 develapiscriptingdir =          $(develapidir)/scripting
 develapishadereffectsdir =      $(develapidir)/shader-effects
 develapitransitioneffectsdir =  $(develapidir)/transition-effects
@@ -146,6 +146,7 @@ develapitextselectionpopup_HEADERS = $(devel_api_text_controls_header_files)
 # public api source
 publicapidir =                     $(topleveldir)/public-api
 publicapicontrolsdir =             $(publicapidir)/controls
+publicapiimageloaderdir =          $(publicapidir)/image-loader
 publicapiaccessibilitymanagerdir = $(publicapidir)/accessibility-manager
 publicapialignmentdir =            $(publicapicontrolsdir)/alignment
 publicapibuttonsdir =              $(publicapicontrolsdir)/buttons
@@ -169,6 +170,7 @@ publicapivisualsdir =              $(publicapidir)/visuals
 # public api headers
 publicapi_HEADERS =                     $(public_api_header_files)
 publicapicontrols_HEADERS =             $(public_api_controls_header_files)
+publicapiimageloader_HEADERS =          $(public_api_image_loader_header_files)
 publicapiaccessibilitymanager_HEADERS = $(public_api_accessibility_manager_header_files)
 publicapialignment_HEADERS =            $(public_api_alignment_header_files)
 publicapibuttons_HEADERS =              $(public_api_buttons_header_files)
index 6cdabe4..6007065 100644 (file)
@@ -351,6 +351,7 @@ ALIASES += SINCE_1_2_2="@since 1.2.2"
 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 += DEPRECATED_1_0="@deprecated Deprecated since 1.0"
 ALIASES += DEPRECATED_1_1="@deprecated Deprecated since 1.1"
@@ -375,6 +376,7 @@ ALIASES += REMARK_INTERNET=""
 #ALIASES += SINCE_1_2_4="\par Since:\n 3.0, DALi version 1.2.4"
 #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"
 
 ## 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 be46ddd..ba7e85b 100644 (file)
@@ -47,6 +47,9 @@
 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
 #include <dali-toolkit/public-api/controls/video-view/video-view.h>
 
+#include <dali-toolkit/public-api/image-loader/async-image-loader.h>
+#include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
+
 #include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
 
 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
index 78e96e5..8af4766 100755 (executable)
@@ -21,7 +21,6 @@ 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)/image-loader/async-image-loader.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 \
@@ -88,7 +87,6 @@ devel_api_focus_manager_header_files = \
   $(devel_api_src_dir)/focus-manager/keyinput-focus-manager.h
 
 devel_api_image_loader_header_files = \
-  $(devel_api_src_dir)/image-loader/async-image-loader.h \
   $(devel_api_src_dir)/image-loader/atlas-upload-observer.h \
   $(devel_api_src_dir)/image-loader/image-atlas.h
 
index c40bc41..c5b822d 100644 (file)
@@ -76,7 +76,7 @@ float Visual::Base::GetHeightForWidth( float width ) const
   return GetImplementation( *this ).GetHeightForWidth( width );
 }
 
-void Visual::Base::GetNaturalSize(Vector2& naturalSize ) const
+void Visual::Base::GetNaturalSize(Vector2& naturalSize )
 {
   GetImplementation( *this ).GetNaturalSize( naturalSize );
 }
@@ -91,25 +91,6 @@ float Visual::Base::GetDepthIndex() const
   return GetImplementation( *this ).GetDepthIndex();
 }
 
-void Visual::Base::SetOnStage( Actor& actor )
-{
-  GetImplementation( *this ).SetOnStage( actor );
-}
-
-void Visual::Base::SetOffStage( Actor& actor )
-{
-  GetImplementation( *this ).SetOffStage( actor );
-}
-
-void Visual::Base::RemoveAndReset( Actor& actor )
-{
-  if( actor && *this )
-  {
-    SetOffStage( actor );
-  }
-  Reset();
-}
-
 void Visual::Base::CreatePropertyMap( Property::Map& map ) const
 {
   GetImplementation( *this ).CreatePropertyMap( map );
index 2cbb0b7..7cfadbf 100644 (file)
@@ -38,11 +38,47 @@ class Base;
 namespace Visual
 {
 /**
- * @brief Visual provides a renderer for rendering the controls. A control may have multiple visuals.
+ * @brief A Visual provides a renderer for drawing a control component. A control may have multiple visuals.
  *
- * Visuals reuses geometry, shader etc. across controls and manages the renderer and texture sets to exist only when control is on-stage.
- * It also responds to actor size and color change, and provides the clipping at the renderer level.
+ * Visuals reuse geometry, shader etc. across controls. They ensure that the renderer and texture sets exist only when control is on-stage.
+ * Each visual also responds to actor size and color change, and provides clipping at the renderer level.
  * Note: The visual responds to the the Actor::COLOR by blending it with the 'Multiply' operator.
+ *
+ * The following properties are optional, but can be supplied in the property map to Dali::Toolkit::VisualFactory::CreateVisual().
+ *
+ * | %Property Name          | Type             |
+ * |-------------------------|------------------|
+ * | customShader            | MAP              |
+ * | 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 |
+ *
+ * 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).
+ *
+ * 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.
+ *
+ * Absolute means that the component describes world units (equivalent to pixels)
+ *
  */
 class DALI_IMPORT_API Base : public BaseHandle
 {
@@ -121,7 +157,7 @@ public:
    *
    * @param[out] naturalSize The visual's natural size
    */
-  void GetNaturalSize( Vector2& naturalSize ) const;
+  void GetNaturalSize( Vector2& naturalSize );
 
   /**
    * @brief Set the depth index of this visual.
@@ -141,34 +177,6 @@ public:
   float GetDepthIndex() const;
 
   /**
-   * @brief Visual needs to know when the control is put on to the stage to add the renderer.
-   *
-   * This function should be called when the control is put on to the stage.
-   *
-   * @param[in] actor The actor using this visual.
-   * @post SetOffStage should be called with the same actor when the control is put off stage otherwise memory will be leaked
-   */
-  void SetOnStage( Actor& actor );
-
-  /**
-   * @brief Visual needs to know when the control is removed from the stage to remove the renderer.
-   *
-   * This function should be called when the control is removed from the stage
-   *
-   * @param[in] actor The actor using this visual.
-   */
-  void SetOffStage( Actor& actor );
-
-  /**
-   * @brief Remove the renderer from the actor and reset the visual self.
-   *
-   * This function can be called with an empty handle. If the visual is empty, this is a no-op.
-   *
-   * @param[in] actor The actor to be set off stage.
-   */
-  void RemoveAndReset( Actor& actor );
-
-  /**
    * @brief Create the property map representing this visual.
    *
    * @param[out] map The visual property map.
index 636147d..25c17cc 100644 (file)
@@ -123,49 +123,6 @@ private:
 
 };
 
-
-/**
- * @brief Template to allow discard old visual, get new one and set it on stage if possible
- *
- * @tparam ParameterType0 The type of first argument passed to the CreateVisual()
- * @tparam ParameterType1 The type of second argument passed to the CreateVisual()
- * @SINCE_1_0.39
- * @param[in] actor Actor for which the visual will be replaced
- * @param[in,out] visual The visual to be replaced
- * @param[in] param0 First template based argument passed to the visual factory
- * @param[in] param1 Second template based argument passed to the visual factory
- */
-template< class ParameterType0, class ParameterType1 >
-void InitializeVisual( Actor& actor, Visual::Base& visual, ParameterType0& param0, ParameterType1& param1 )
-{
-  visual.RemoveAndReset( actor );
-  visual = Toolkit::VisualFactory::Get().CreateVisual( param0, param1 );
-  if( visual && actor && actor.OnStage() )
-  {
-    visual.SetOnStage( actor );
-  }
-}
-
-/**
- * @brief Template to allow discard old visual, get new one and set it on stage if possible
- *
- * @tparam ParameterType The type of argument passed to the CreateVisual()
- * @SINCE_1_0.39
- * @param[in] actor Actor for which the visual will be replaced
- * @param[in,out] visual The visual to be replaced
- * @param[in] param Template based argument passed to the visual factory
- */
-template< class ParameterType >
-void InitializeVisual( Actor& actor, Visual::Base& visual, ParameterType& param )
-{
-  visual.RemoveAndReset( actor );
-  visual =  Toolkit::VisualFactory::Get().CreateVisual( param );
-  if( visual && actor && actor.OnStage() )
-  {
-    visual.SetOnStage( actor );
-  }
-}
-
 } // namespace Toolkit
 
 } // namespace Dali
index 24f82bc..44bc39b 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/public-api/animation/constraint.h>
 #include <dali/public-api/animation/constraints.h>
 #include <dali/public-api/common/stage.h>
+#include <dali/public-api/object/property.h>
 #include <dali/public-api/object/property-map.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/public-api/object/type-registry-helper.h>
@@ -37,6 +38,7 @@
 #include <dali-toolkit/internal/filters/emboss-filter.h>
 #include <dali-toolkit/internal/filters/spread-filter.h>
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
 
 namespace Dali
 {
@@ -66,6 +68,10 @@ const float         ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
 const Vector4       EFFECTS_VIEW_DEFAULT_BACKGROUND_COLOR( 1.0f, 1.0f, 1.0f, 0.0 );
 const bool          EFFECTS_VIEW_REFRESH_ON_DEMAND(false);
 
+// Visuals are not stylable or public
+const Property::Index CHILD_VISUAL( Toolkit::EffectsView::ANIMATABLE_PROPERTY_START_INDEX - 1);
+const Property::Index POST_FILTER_VISUAL( CHILD_VISUAL-1 );
+
 #define DALI_COMPOSE_SHADER(STR) #STR
 
 const char* EFFECTS_VIEW_VERTEX_SOURCE = DALI_COMPOSE_SHADER(
@@ -186,7 +192,9 @@ void EffectsView::SetType( Toolkit::EffectsView::EffectType type )
 
     FrameBufferImage dummyImage = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat );
 
-    InitializeVisual( self, mVisualPostFilter, dummyImage );
+    Internal::InitializeVisual( self, mVisualPostFilter, dummyImage );
+    RegisterVisual( POST_FILTER_VISUAL, mVisualPostFilter );
+
     Property::Map customShader;
     customShader[ Toolkit::Visual::Shader::Property::VERTEX_SHADER ] = EFFECTS_VIEW_VERTEX_SOURCE;
     customShader[ Toolkit::Visual::Shader::Property::FRAGMENT_SHADER ] = EFFECTS_VIEW_FRAGMENT_SOURCE;
@@ -214,6 +222,7 @@ void EffectsView::Disable()
   // stop render tasks processing
   // Note: render target resources are automatically freed since we set the Image::Unused flag
   RemoveRenderTasks();
+  mLastSize = Vector2::ZERO; // Ensure resources are reallocated on subsequent enable
   mEnabled = false;
 }
 
@@ -302,16 +311,6 @@ void EffectsView::OnStageConnection( int depth )
   Control::OnStageConnection( depth );
 
   Enable();
-
-  Actor self = Self();
-  if( mVisualPostFilter )
-  {
-    mVisualPostFilter.SetOnStage( self );
-  }
-  if( mVisualForChildren )
-  {
-    mVisualForChildren.SetOnStage( self );
-  }
 }
 
 void EffectsView::OnStageDisconnection()
@@ -324,16 +323,6 @@ void EffectsView::OnStageDisconnection()
     mFilters[i]->Disable();
   }
 
-  Actor self = Self();
-  if( mVisualPostFilter )
-  {
-    mVisualPostFilter.SetOffStage( self );
-  }
-  if( mVisualForChildren )
-  {
-    mVisualForChildren.SetOffStage( self );
-  }
-
   Control::OnStageDisconnection();
 }
 
@@ -437,7 +426,8 @@ void EffectsView::AllocateResources()
     Actor self( Self() );
 
     mImageForChildren = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat );
-    InitializeVisual( self, mVisualForChildren, mImageForChildren );
+    Internal::InitializeVisual( self, mVisualForChildren, mImageForChildren );
+    RegisterVisual( CHILD_VISUAL, mVisualForChildren );
     mVisualForChildren.SetDepthIndex( DepthIndex::CONTENT+1 );
 
     mImagePostFilter = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat );
index 8bf498e..9a5f6a2 100644 (file)
@@ -275,4 +275,3 @@ inline const Toolkit::Internal::EffectsView& GetImpl( const Toolkit::EffectsView
 } // namespace Dali
 
 #endif // __DALI_TOOLKIT_INTERNAL_EFFECTS_VIEW_H__
-
index 2a8cc3f..84af28f 100644 (file)
@@ -31,6 +31,7 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/border-visual-properties.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
 #include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.h>
 
 namespace Dali
@@ -271,7 +272,7 @@ void Magnifier::SetFrameVisibility(bool visible)
     map[ Toolkit::BorderVisual::Property::COLOR ] = Color::WHITE;
     map[ Toolkit::BorderVisual::Property::SIZE   ] = IMAGE_BORDER_INDENT;
     Toolkit::Visual::Base borderVisual = visualFactory.CreateVisual( map );
-    borderVisual.SetOnStage( mFrame );
+    Toolkit::GetImplementation(borderVisual).SetOnStage( mFrame );
 
     Constraint constraint = Constraint::New<Vector3>( mFrame, Actor::Property::POSITION, EqualToConstraint() );
     constraint.AddSource( ParentSource( Actor::Property::WORLD_POSITION ) );
index 74d5ee8..7ac2a28 100755 (executable)
@@ -28,7 +28,6 @@
 #include <dali/public-api/common/stage.h>
 #include <dali/public-api/events/key-event.h>
 #include <dali/public-api/events/touch-data.h>
-#include <dali/public-api/images/resource-image.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/public-api/size-negotiation/relayout-container.h>
@@ -305,7 +304,7 @@ void Popup::OnInitialize()
   mPopupLayout = Toolkit::TableView::New( 3, 1 );
 
   // Adds the default background image.
-  SetPopupBackgroundImage( Toolkit::ImageView::New( ResourceImage::New( DEFAULT_BACKGROUND_IMAGE_PATH ) ) );
+  SetPopupBackgroundImage( Toolkit::ImageView::New( DEFAULT_BACKGROUND_IMAGE_PATH ) );
 
   mPopupLayout.SetName( "popupLayoutTable" );
   mPopupLayout.SetParentOrigin( ParentOrigin::CENTER );
@@ -863,8 +862,7 @@ void Popup::LayoutTail()
   if( !image.empty() )
   {
     // Adds the tail actor.
-    Image tail = ResourceImage::New( image );
-    mTailImage = Toolkit::ImageView::New( tail );
+    mTailImage = Toolkit::ImageView::New( image );
     mTailImage.SetName( "tailImage" );
     const Vector3 anchorPoint = AnchorPoint::BOTTOM_RIGHT - position;
     mTailImage.SetParentOrigin( position );
@@ -1239,12 +1237,8 @@ void Popup::SetProperty( BaseObject* object, Property::Index propertyIndex, cons
         std::string valueString;
         if( value.Get( valueString ) )
         {
-          Image image = ResourceImage::New( valueString );
-          if( image )
-          {
-            Toolkit::ImageView actor = Toolkit::ImageView::New( image );
-            popupImpl.SetPopupBackgroundImage( actor );
-          }
+          Toolkit::ImageView actor = Toolkit::ImageView::New( valueString );
+          popupImpl.SetPopupBackgroundImage( actor );
         }
         break;
       }
@@ -1387,10 +1381,10 @@ Property::Value Popup::GetProperty( BaseObject* object, Property::Index property
       }
       case Toolkit::Popup::Property::POPUP_BACKGROUND_IMAGE:
       {
-        ResourceImage image = ResourceImage::DownCast( popupImpl.GetPopupBackgroundImage() );
-        if( image )
+        Toolkit::ImageView imageView = Toolkit::ImageView::DownCast( popupImpl.GetPopupBackgroundImage() );
+        if( imageView )
         {
-          value = image.GetUrl();
+          value = imageView.GetProperty( Toolkit::ImageView::Property::IMAGE );
         }
         break;
       }
index 28e4eec..3141edc 100644 (file)
@@ -31,6 +31,7 @@
 
 // INTERNAL_INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
 
 namespace //Unnamed namespace
 {
@@ -170,13 +171,11 @@ void SuperBlurView::SetImage(Image inputImage)
 
   mInputImage = inputImage;
   Actor self( Self() );
-  InitializeVisual( self, mVisuals[0], mInputImage );
+
+  mVisuals[0] = Toolkit::VisualFactory::Get().CreateVisual( mInputImage );
+  RegisterVisual( 0, mVisuals[0] ); // Will clean up previously registered visuals for this index.
   mVisuals[0].SetDepthIndex(0);
   SetShaderEffect( mVisuals[0] );
-  if( self.OnStage() )
-  {
-    mVisuals[0].SetOnStage( self );
-  }
 
   BlurImage( 0,  inputImage);
   for(unsigned int i=1; i<mBlurLevels;i++)
@@ -281,28 +280,23 @@ void SuperBlurView::OnSizeSet( const Vector3& targetSize )
       float exponent = static_cast<float>(i);
       mBlurredImage[i-1] = FrameBufferImage::New( mTargetSize.width/std::pow(2.f,exponent) , mTargetSize.height/std::pow(2.f,exponent),
                                                 GAUSSIAN_BLUR_RENDER_TARGET_PIXEL_FORMAT );
-      InitializeVisual( self, mVisuals[i], mBlurredImage[i - 1] );
-      mVisuals[ i ].SetDepthIndex( i );
-      SetShaderEffect( mVisuals[ i ] );
+
+      mVisuals[i] = Toolkit::VisualFactory::Get().CreateVisual( mBlurredImage[i - 1] );
+      RegisterVisual( i, mVisuals[i] ); // Will clean up existing visual with same index.
+      mVisuals[i].SetDepthIndex( i );
+      SetShaderEffect( mVisuals[i] );
     }
 
     if( mInputImage )
     {
       SetImage( mInputImage );
     }
-
-    if( self.OnStage() )
-    {
-      for( unsigned int i = 1; i <= mBlurLevels; i++ )
-      {
-        mVisuals[i].SetOnStage( self );
-      }
-    }
   }
 }
 
 void SuperBlurView::OnStageConnection( int depth )
 {
+  // Chaining up first ensures visuals have SetOnStage called to create their renderers
   Control::OnStageConnection( depth );
 
   if( mTargetSize == Vector2::ZERO )
@@ -311,17 +305,8 @@ void SuperBlurView::OnStageConnection( int depth )
   }
 
   Actor self = Self();
-  if( mVisuals[0] )
-  {
-    mVisuals[0].SetOnStage( self );
-  }
   for(unsigned int i=1; i<=mBlurLevels;i++)
   {
-    if( mVisuals[i] )
-    {
-      mVisuals[i].SetOnStage( self );
-    }
-
     Renderer renderer = self.GetRendererAt( i );
     Property::Index index = renderer.RegisterProperty( ALPHA_UNIFORM_NAME, 0.f );
     Constraint constraint = Constraint::New<float>( renderer, index, ActorOpacityConstraint(mBlurLevels, i-1) );
@@ -332,17 +317,6 @@ void SuperBlurView::OnStageConnection( int depth )
 
 void SuperBlurView::OnStageDisconnection( )
 {
-  if( mTargetSize == Vector2::ZERO )
-  {
-    return;
-  }
-
-  Actor self = Self();
-  for(unsigned int i=0; i<mBlurLevels+1;i++)
-  {
-    mVisuals[i].SetOffStage( self );
-  }
-
   Control::OnStageDisconnection();
 }
 
index 1d6af0f..094e755 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/text/rendering-backend.h>
-#include <dali-toolkit/public-api/visuals/text-visual-properties.h>
-#include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.h>
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/internal/text/property-string-parser.h>
+#include <dali-toolkit/internal/text/rendering/text-backend.h>
 #include <dali-toolkit/internal/text/text-effects-style.h>
+#include <dali-toolkit/internal/text/text-font-style.h>
+#include <dali-toolkit/internal/text/text-view.h>
+#include <dali-toolkit/internal/text/text-definitions.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 
 using Dali::Toolkit::Text::LayoutEngine;
@@ -52,6 +56,22 @@ namespace
   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
 #endif
 
+const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+{
+  { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
+  { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
+  { "END",    Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END    },
+};
+const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
+
+const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
+{
+  { "TOP",    Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP    },
+  { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
+  { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
+};
+const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
+
 // Type registration
 BaseHandle Create()
 {
@@ -88,34 +108,6 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "outline",              MAP,
 
 DALI_TYPE_REGISTRATION_END()
 
-const int TEXT_VISUAL_PROPERTY_TABLE[] = {
-  Dali::Toolkit::TextVisual::Property::RENDERING_BACKEND,
-  Dali::Toolkit::TextVisual::Property::TEXT,
-  Dali::Toolkit::TextVisual::Property::FONT_FAMILY,
-  Dali::Toolkit::TextVisual::Property::FONT_STYLE,
-  Dali::Toolkit::TextVisual::Property::POINT_SIZE,
-  Dali::Toolkit::TextVisual::Property::MULTI_LINE,
-  Dali::Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT,
-  Dali::Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT,
-  Dali::Toolkit::TextVisual::Property::TEXT_COLOR,
-  Dali::Toolkit::TextVisual::Property::SHADOW,
-  Dali::Toolkit::TextVisual::Property::SHADOW,
-  Dali::Toolkit::TextVisual::Property::UNDERLINE,
-  Dali::Toolkit::TextVisual::Property::UNDERLINE,
-  Dali::Toolkit::TextVisual::Property::UNDERLINE,
-  Dali::Toolkit::TextVisual::Property::ENABLE_MARKUP,
-  Dali::Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL,
-  Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED,
-  Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT,
-  Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_GAP,
-  Dali::Toolkit::TextVisual::Property::LINE_SPACING,
-  Dali::Toolkit::TextVisual::Property::UNDERLINE,
-  Dali::Toolkit::TextVisual::Property::SHADOW,
-  Dali::Toolkit::TextVisual::Property::EMBOSS,
-  Dali::Toolkit::TextVisual::Property::OUTLINE,
-  Dali::Toolkit::TextVisual::Property::BATCHING_ENABLED
-};
-
 } // namespace
 
 Toolkit::TextLabel TextLabel::New()
@@ -139,10 +131,298 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
 
   if( label )
   {
-    TextLabel& impl = GetImpl( label );
+    TextLabel& impl( GetImpl( label ) );
+    switch( index )
+    {
+      case Toolkit::TextLabel::Property::RENDERING_BACKEND:
+      {
+        int backend = value.Get< int >();
+
+#ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
+        if( Text::RENDERING_VECTOR_BASED == backend )
+        {
+          backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
+        }
+#endif
+        if( impl.mRenderingBackend != backend )
+        {
+          impl.mRenderingBackend = backend;
+          impl.mRenderer.Reset();
+
+          if( impl.mController )
+          {
+            // When using the vector-based rendering, the size of the GLyphs are different
+            TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
+            impl.mController->SetGlyphType( glyphType );
+          }
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::TEXT:
+      {
+        if( impl.mController )
+        {
+          impl.mController->SetText( value.Get< std::string >() );
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::FONT_FAMILY:
+      {
+        if( impl.mController )
+        {
+          const std::string fontFamily = value.Get< std::string >();
+
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str() );
+          impl.mController->SetDefaultFontFamily( fontFamily );
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::FONT_STYLE:
+      {
+        SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
+        break;
+      }
+      case Toolkit::TextLabel::Property::POINT_SIZE:
+      {
+        if( impl.mController )
+        {
+          const float pointSize = value.Get< float >();
+
+          if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
+          {
+            impl.mController->SetDefaultPointSize( pointSize );
+          }
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::MULTI_LINE:
+      {
+        if( impl.mController )
+        {
+          impl.mController->SetMultiLineEnabled( value.Get< bool >() );
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
+      {
+        if( impl.mController )
+        {
+          LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
+          if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
+                                                                                             HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                             HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                                             alignment ) )
+          {
+            impl.mController->SetHorizontalAlignment( alignment );
+          }
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
+      {
+        if( impl.mController )
+        {
+          LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
+          if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
+                                                                                           VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                           VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                                           alignment ) )
+          {
+            impl.mController->SetVerticalAlignment( alignment );
+          }
+        }
+        break;
+      }
+
+      case Toolkit::TextLabel::Property::TEXT_COLOR:
+      {
+        if( impl.mController )
+        {
+          const Vector4 textColor = value.Get< Vector4 >();
+          if( impl.mController->GetTextColor() != textColor )
+          {
+            impl.mController->SetTextColor( textColor );
+            impl.mRenderer.Reset();
+          }
+        }
+        break;
+      }
+
+      case Toolkit::TextLabel::Property::SHADOW_OFFSET:
+      {
+        if( impl.mController )
+        {
+          const Vector2 shadowOffset = value.Get< Vector2 >();
+          if ( impl.mController->GetShadowOffset() != shadowOffset )
+          {
+            impl.mController->SetShadowOffset( shadowOffset );
+            impl.mRenderer.Reset();
+          }
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::SHADOW_COLOR:
+      {
+        if( impl.mController )
+        {
+          const Vector4 shadowColor = value.Get< Vector4 >();
+          if ( impl.mController->GetShadowColor() != shadowColor )
+          {
+            impl.mController->SetShadowColor( shadowColor );
+            impl.mRenderer.Reset();
+          }
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
+      {
+        if( impl.mController )
+        {
+          const Vector4 color = value.Get< Vector4 >();
+          if ( impl.mController->GetUnderlineColor() != color )
+          {
+            impl.mController->SetUnderlineColor( color );
+            impl.mRenderer.Reset();
+          }
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
+      {
+        if( impl.mController )
+        {
+          const bool enabled = value.Get< bool >();
+          if ( impl.mController->IsUnderlineEnabled() != enabled )
+          {
+            impl.mController->SetUnderlineEnabled( enabled );
+            impl.mRenderer.Reset();
+          }
+        }
+        break;
+      }
 
-    // Sets the property to the to the text visual.
-    impl.mVisual.SetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX], value );
+      case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT:
+      {
+        if( impl.mController )
+        {
+          float height = value.Get< float >();
+          if( fabsf( impl.mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 )
+          {
+            impl.mController->SetUnderlineHeight( height );
+            impl.mRenderer.Reset();
+          }
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::ENABLE_MARKUP:
+      {
+        if( impl.mController )
+        {
+          const bool enableMarkup = value.Get<bool>();
+          impl.mController->SetMarkupProcessorEnabled( enableMarkup );
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
+      {
+        if( impl.mController )
+        {
+          const bool enableAutoScroll = value.Get<bool>();
+          // If request to auto scroll is the same as current state then do nothing.
+          if ( enableAutoScroll != impl.mController->IsAutoScrollEnabled() )
+          {
+             // If request is disable (false) and auto scrolling is enabled then need to stop it
+             if ( enableAutoScroll == false )
+             {
+               if( impl.mTextScroller )
+               {
+                 impl.mTextScroller->SetLoopCount( 0 ); // Causes the current animation to finish playing (0)
+               }
+             }
+             // If request is enable (true) then start autoscroll as not already running
+             else
+             {
+               impl.mController->GetLayoutEngine().SetTextEllipsisEnabled( false );
+               impl.mController->SetAutoScrollEnabled( enableAutoScroll );
+             }
+          }
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED:
+      {
+        if( !impl.mTextScroller )
+        {
+          impl.mTextScroller = Text::TextScroller::New( impl );
+        }
+        impl.mTextScroller->SetSpeed( value.Get<int>() );
+        break;
+      }
+      case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT:
+      {
+        if( !impl.mTextScroller )
+        {
+          impl.mTextScroller = Text::TextScroller::New( impl );
+        }
+        impl.mTextScroller->SetLoopCount( value.Get<int>() );
+        break;
+      }
+      case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
+      {
+        if( !impl.mTextScroller )
+        {
+          impl.mTextScroller = Text::TextScroller::New( impl );
+        }
+        impl.mTextScroller->SetGap( value.Get<float>() );
+        break;
+      }
+      case Toolkit::TextLabel::Property::LINE_SPACING:
+      {
+        if( impl.mController )
+        {
+          const float lineSpacing = value.Get<float>();
+          impl.mController->SetDefaultLineSpacing( lineSpacing );
+          impl.mRenderer.Reset();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::UNDERLINE:
+      {
+        const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
+        if( update )
+        {
+          impl.mRenderer.Reset();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::SHADOW:
+      {
+        const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
+        if( update )
+        {
+          impl.mRenderer.Reset();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::EMBOSS:
+      {
+        const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
+        if( update )
+        {
+          impl.mRenderer.Reset();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::OUTLINE:
+      {
+        const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
+        if( update )
+        {
+          impl.mRenderer.Reset();
+        }
+        break;
+      }
+    }
   }
 }
 
@@ -154,126 +434,203 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
 
   if( label )
   {
-    TextLabel& impl = GetImpl( label );
-
-    if( ( Toolkit::TextLabel::Property::SHADOW_OFFSET == index ) ||
-        ( Toolkit::TextLabel::Property::SHADOW_COLOR == index ) ||
-        ( Toolkit::TextLabel::Property::UNDERLINE_ENABLED == index ) ||
-        ( Toolkit::TextLabel::Property::UNDERLINE_COLOR == index ) ||
-        ( Toolkit::TextLabel::Property::UNDERLINE_HEIGHT == index ) )
+    TextLabel& impl( GetImpl( label ) );
+    switch( index )
     {
-      // TODO : Branch to be removed when the deprecated properties are finally removed.
-      value = impl.mVisual.GetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX] );
-
-      switch( index )
+      case Toolkit::TextLabel::Property::RENDERING_BACKEND:
+      {
+        value = impl.mRenderingBackend;
+        break;
+      }
+      case Toolkit::TextLabel::Property::TEXT:
       {
-        case Toolkit::TextLabel::Property::SHADOW_OFFSET: // Converts the deprecated property to the new one.
+        if( impl.mController )
         {
-          bool colorDefined = false;
-          Vector4 color;
-          bool offsetDefined = false;
-          Vector2 offset;
-          const bool empty = Text::ParseShadowProperties( value.Get<Property::Map>(),
-                                                          colorDefined,
-                                                          color,
-                                                          offsetDefined,
-                                                          offset );
-
-          if( !empty )
-          {
-            value = offset;
-          }
-          break;
+          std::string text;
+          impl.mController->GetText( text );
+          value = text;
         }
-        case Toolkit::TextLabel::Property::SHADOW_COLOR: // Converts the deprecated property to the new one.
+        break;
+      }
+      case Toolkit::TextLabel::Property::FONT_FAMILY:
+      {
+        if( impl.mController )
         {
-          bool colorDefined = false;
-          Vector4 color;
-          bool offsetDefined = false;
-          Vector2 offset;
-          const bool empty = Text::ParseShadowProperties( value.Get<Property::Map>(),
-                                                          colorDefined,
-                                                          color,
-                                                          offsetDefined,
-                                                          offset );
-
-          if( !empty )
-          {
-            value = color;
-          }
-          break;
-        }
-        case Toolkit::TextLabel::Property::UNDERLINE_ENABLED: // Converts the deprecated property to the new one.
-        {
-          bool enabled = false;
-          bool colorDefined = false;
-          Vector4 color;
-          bool heightDefined = false;
-          float height = 0.f;
-          const bool empty = Text::ParseUnderlineProperties( value.Get<Property::Map>(),
-                                                             enabled,
-                                                             colorDefined,
-                                                             color,
-                                                             heightDefined,
-                                                             height );
-
-          if( !empty )
+          value = impl.mController->GetDefaultFontFamily();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::FONT_STYLE:
+      {
+        GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
+        break;
+      }
+      case Toolkit::TextLabel::Property::POINT_SIZE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultPointSize();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::MULTI_LINE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsMultiLineEnabled();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
+      {
+        if( impl.mController )
+        {
+          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
+                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+          if( name )
           {
-            value = enabled;
+            value = std::string( name );
           }
-          break;
-        }
-        case Toolkit::TextLabel::Property::UNDERLINE_COLOR: // Converts the deprecated property to the new one.
-        {
-          bool enabled = false;
-          bool colorDefined = false;
-          Vector4 color;
-          bool heightDefined = false;
-          float height = 0.f;
-          const bool empty = Text::ParseUnderlineProperties( value.Get<Property::Map>(),
-                                                             enabled,
-                                                             colorDefined,
-                                                             color,
-                                                             heightDefined,
-                                                             height );
-
-          if( !empty && colorDefined )
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
+      {
+        if( impl.mController )
+        {
+          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
+                                                                                                              VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                                              VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+          if( name )
           {
-            value = color;
+            value = std::string( name );
           }
-          break;
-        }
-        case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT: // Converts the deprecated property to the new one.
-        {
-          bool enabled = false;
-          bool colorDefined = false;
-          Vector4 color;
-          bool heightDefined = false;
-          float height = 0.f;
-          const bool empty = Text::ParseUnderlineProperties( value.Get<Property::Map>(),
-                                                             enabled,
-                                                             colorDefined,
-                                                             color,
-                                                             heightDefined,
-                                                             height );
-
-          if( !empty && heightDefined )
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::TEXT_COLOR:
+      {
+        if ( impl.mController )
+        {
+          value = impl.mController->GetTextColor();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::SHADOW_OFFSET:
+      {
+        if ( impl.mController )
+        {
+          value = impl.mController->GetShadowOffset();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::SHADOW_COLOR:
+      {
+        if ( impl.mController )
+        {
+          value = impl.mController->GetShadowColor();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
+      {
+        if ( impl.mController )
+        {
+          value = impl.mController->GetUnderlineColor();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
+      {
+        if ( impl.mController )
+        {
+          value = impl.mController->IsUnderlineEnabled();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT:
+      {
+        if ( impl.mController )
+        {
+          value = impl.mController->GetUnderlineHeight();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::ENABLE_MARKUP:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsMarkupProcessorEnabled();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsAutoScrollEnabled();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED:
+      {
+        TextLabel& impl( GetImpl( label ) );
+        if ( impl.mTextScroller )
+        {
+          value = impl.mTextScroller->GetSpeed();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT:
+      {
+        if( impl.mController )
+        {
+          TextLabel& impl( GetImpl( label ) );
+          if ( impl.mTextScroller )
           {
-            value = height;
+            value = impl.mTextScroller->GetLoopCount();
           }
-          break;
         }
-        default:
+        break;
+      }
+      case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
+      {
+        TextLabel& impl( GetImpl( label ) );
+        if ( impl.mTextScroller )
         {
-          // Nothing to do.
-          break;
+          value = impl.mTextScroller->GetGap();
         }
+        break;
+      }
+      case Toolkit::TextLabel::Property::LINE_SPACING:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultLineSpacing();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::UNDERLINE:
+      {
+        GetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
+        break;
+      }
+      case Toolkit::TextLabel::Property::SHADOW:
+      {
+        GetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
+        break;
+      }
+      case Toolkit::TextLabel::Property::EMBOSS:
+      {
+        GetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
+        break;
+      }
+      case Toolkit::TextLabel::Property::OUTLINE:
+      {
+        GetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
+        break;
       }
-    }
-    else
-    {
-      // Retrieves the property from the text visual.
-      value = impl.mVisual.GetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX] );
     }
   }
 
@@ -284,23 +641,23 @@ void TextLabel::OnInitialize()
 {
   Actor self = Self();
 
-  // Creates the text's visual.
-  Property::Map visualMap;
-  visualMap[Toolkit::VisualProperty::TYPE] = Toolkit::Visual::TEXT;
-  visualMap[Toolkit::TextVisual::Property::RENDERING_BACKEND] = static_cast<int>( DEFAULT_RENDERING_BACKEND );
+  mController = Text::Controller::New( this );
 
-  mVisual =  Toolkit::VisualFactory::Get().CreateVisual( visualMap );
-  RegisterVisual( Toolkit::TextLabel::Property::TEXT, mVisual );
-
-  Internal::Visual::Base& visualBase = Toolkit::GetImplementation( mVisual );
-  TextVisual* textVisual = static_cast<TextVisual*>( &visualBase );
-
-  // Sets the text's control interface.
-  textVisual->SetTextControlInterface( this );
+  // When using the vector-based rendering, the size of the GLyphs are different
+  TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
+  mController->SetGlyphType( glyphType );
 
   // Use height-for-width negotiation by default
   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
   self.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
+
+  // Enable the text ellipsis.
+  LayoutEngine& engine = mController->GetLayoutEngine();
+
+  engine.SetTextEllipsisEnabled( true );   // If false then text larger than control will overflow
+  engine.SetCursorWidth( 0u ); // Do not layout space for the cursor.
+
+  self.OnStageSignal().Connect( this, &TextLabel::OnStageConnect );
 }
 
 void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
@@ -314,9 +671,7 @@ void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::
       // Property system did not set the font so should update it.
       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() );
-
-      const std::string fontString = "{\"family\":\"" + newFont + "\",\"type\":\"system\"}";
-      mVisual.SetProperty( Toolkit::TextVisual::Property::FONT_FAMILY, fontString );
+      mController->UpdateAfterFontChange( newFont );
       break;
     }
     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
@@ -334,22 +689,29 @@ void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::
 
 Vector3 TextLabel::GetNaturalSize()
 {
-  Vector2 naturalSize;
-  mVisual.GetNaturalSize( naturalSize );
-
-  return Vector3( naturalSize );
+  return mController->GetNaturalSize();
 }
 
 float TextLabel::GetHeightForWidth( float width )
 {
-  return mVisual.GetHeightForWidth( width );
+  return mController->GetHeightForWidth( width );
 }
 
 void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout\n" );
 
-  mVisual.SetSize( size );
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
+
+  if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) ||
+      !mRenderer )
+  {
+    if( !mRenderer )
+    {
+      mRenderer = Text::Backend::Get().NewRenderer( mRenderingBackend );
+    }
+    RenderText();
+  }
 }
 
 void TextLabel::RequestTextRelayout()
@@ -357,16 +719,95 @@ void TextLabel::RequestTextRelayout()
   RelayoutRequest();
 }
 
+void TextLabel::RenderText()
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::RenderText IsAutoScrollEnabled[%s] [%p]\n", ( mController->IsAutoScrollEnabled())?"true":"false", this );
+
+  Actor self = Self();
+  Actor renderableActor;
+
+  if( mRenderer )
+  {
+    renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
+  }
+
+  if( renderableActor != mRenderableActor )
+  {
+    UnparentAndReset( mRenderableActor );
+
+    if( renderableActor )
+    {
+      const Vector2& scrollOffset = mController->GetScrollPosition();
+      renderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
+
+      self.Add( renderableActor );
+    }
+    mRenderableActor = renderableActor;
+
+    if ( mController->IsAutoScrollEnabled() )
+    {
+      SetUpAutoScrolling();
+    }
+  }
+}
+
+void TextLabel::SetUpAutoScrolling()
+{
+  const Size& controlSize = mController->GetView().GetControlSize();
+  const Size offScreenSize = GetNaturalSize().GetVectorXY(); // As relayout of text may not be done at this point natural size is used to get size. Single line scrolling only.
+  const float alignmentOffset = mController->GetAutoScrollLineAlignment();
+  const Text::CharacterDirection direction = mController->GetAutoScrollDirection();
+
+  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling alignmentOffset[%f] offScreenSize[%f,%f] controlSize[%f,%f]\n",
+                 alignmentOffset, offScreenSize.x,offScreenSize.y , controlSize.x,controlSize.y );
+
+  if ( !mTextScroller )
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling Creating default TextScoller\n" );
+
+    // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults
+    mTextScroller = Text::TextScroller::New( *this );
+  }
+  mTextScroller->SetParameters( mRenderableActor, controlSize, offScreenSize, direction, alignmentOffset );
+
+  Actor self = Self();
+  self.Add( mTextScroller->GetScrollingText() );
+  self.Add( mTextScroller->GetSourceCamera() );
+}
+
+void TextLabel::OnStageConnect( Dali::Actor actor )
+{
+  if ( mHasBeenStaged )
+  {
+    RenderText();
+  }
+  else
+  {
+    mHasBeenStaged = true;
+  }
+}
+
 void TextLabel::OnStageConnection( int depth )
 {
   // Call the Control::OnStageConnection() to set the depth of the background.
   Control::OnStageConnection( depth );
 
-  // The depth of the text renderer is set by the text-visual called from OnRelayout().
+  // The depth of the text renderer is set in the RenderText() called from OnRelayout().
+}
+
+void TextLabel::ScrollingFinished()
+{
+  // Pure Virtual from TextScroller Interface
+  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::ScrollingFinished\n");
+  mController->SetAutoScrollEnabled( false );
+  mController->GetLayoutEngine().SetTextEllipsisEnabled( true );
+  RequestTextRelayout();
 }
 
 TextLabel::TextLabel()
-: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) )
+: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
+  mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
+  mHasBeenStaged( false )
 {
 }
 
index bdc587d..c928763 100644 (file)
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
-#include <dali-toolkit/internal/visuals/text/text-visual.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/text-scroller-interface.h>
+#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/text/text-scroller.h>
 
 namespace Dali
 {
@@ -36,7 +39,7 @@ namespace Internal
 /**
  * @brief A control which renders a short text string.
  */
-class TextLabel : public Control, public Text::ControlInterface
+class TextLabel : public Control, public Text::ControlInterface, public Text::ScrollerInterface
 {
 public:
 
@@ -104,6 +107,13 @@ private: // From Control
    */
   virtual void RequestTextRelayout();
 
+private: // from TextScroller
+
+  /**
+   * @copydoc Text::ScrollerInterface::ScrollingFinished()
+   */
+  virtual void ScrollingFinished();
+
 private: // Implementation
 
   /**
@@ -122,9 +132,27 @@ private:
   TextLabel(const TextLabel&);
   TextLabel& operator=(const TextLabel& rhs);
 
+  // Connection needed to re-render text, when a Text Label returns to the stage
+  void OnStageConnect( Dali::Actor actor );
+
+  /**
+   * @brief Render view, create and attach actor(s) to this Text Label
+   */
+  void RenderText();
+
+  /**
+   * @brief Set up Autoscrolling
+   */
+  void SetUpAutoScrolling();
+
 private: // Data
 
-  Toolkit::Visual::Base mVisual;
+  Text::ControllerPtr mController;
+  Text::RendererPtr mRenderer;
+  Text::TextScrollerPtr mTextScroller;
+  Actor mRenderableActor;
+  int mRenderingBackend;
+  bool mHasBeenStaged:1;
 };
 
 } // namespace Internal
index 1f66e86..51bf9a2 100644 (file)
@@ -29,6 +29,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/video-view/video-view.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
 
 namespace Dali
 {
@@ -120,7 +121,7 @@ void VideoView::SetPropertyMap( Property::Map map )
   mPropertyMap = map;
 
   Actor self( Self() );
-  InitializeVisual( self, mVisual, mPropertyMap );
+  Internal::InitializeVisual( self, mVisual, mPropertyMap );
 
   Property::Value* widthValue = mPropertyMap.Find( "width" );
   if( widthValue )
@@ -443,7 +444,7 @@ void VideoView::OnStageConnection( int depth )
   if( mVisual )
   {
     CustomActor self = Self();
-    mVisual.SetOnStage( self );
+    Toolkit::GetImplementation(mVisual).SetOnStage( self );
   }
 }
 
@@ -452,7 +453,7 @@ void VideoView::OnStageDisconnection()
   if( mVisual )
   {
     CustomActor self = Self();
-    mVisual.SetOffStage( self );
+    Toolkit::GetImplementation(mVisual).SetOffStage( self );
   }
 
   Control::OnStageDisconnection();
@@ -505,7 +506,12 @@ void VideoView::SetWindowSurfaceTarget()
   int curPos = mVideoPlayer.GetPlayPosition();
 
   mSetRenderingTarget = true;
-  mVisual.RemoveAndReset( self );
+
+  if( mVisual )
+  {
+    Toolkit::GetImplementation(mVisual).SetOffStage(self);
+    mVisual.Reset();
+  }
 
   mVideoPlayer.SetRenderingTarget( Dali::Adaptor::Get().GetNativeWindowHandle() );
   mVideoPlayer.SetUrl( mUrl );
@@ -538,7 +544,7 @@ void VideoView::SetNativeImageTarget()
   mVideoPlayer.SetUrl( mUrl );
   mVideoPlayer.FinishedSignal().Connect( this, &VideoView::EmitSignalFinish );
 
-  InitializeVisual( self, mVisual, mNativeImage );
+  Internal::InitializeVisual( self, mVisual, mNativeImage );
 
   if( mIsPlay )
   {
index 57b4dbf..1e78bf6 100644 (file)
@@ -13,6 +13,7 @@ toolkit_src_files = \
    $(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 \
@@ -114,7 +115,6 @@ toolkit_src_files = \
    $(toolkit_src_dir)/text/text-font-style.cpp \
    $(toolkit_src_dir)/text/text-io.cpp \
    $(toolkit_src_dir)/text/text-scroller.cpp \
-   $(toolkit_src_dir)/text/text-scroller-data.cpp \
    $(toolkit_src_dir)/text/text-scroller-interface.cpp \
    $(toolkit_src_dir)/text/text-view.cpp \
    $(toolkit_src_dir)/text/text-view-interface.cpp \
index 849e81b..660c86c 100644 (file)
@@ -31,6 +31,7 @@
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.h>
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
 
 namespace Dali
 {
@@ -127,10 +128,10 @@ void EmbossFilter::Enable()
 
   mRootActor.Add( mActorForComposite );
 
-  InitializeVisual( mActorForComposite, mVisualForEmboss1, mImageForEmboss1 );
+  Internal::InitializeVisual( mActorForComposite, mVisualForEmboss1, mImageForEmboss1 );
   Toolkit::GetImplementation( mVisualForEmboss1 ).SetCustomShader( customShader );
   mActorForComposite.GetRendererAt(0).RegisterProperty( COLOR_UNIFORM_NAME, Color::BLACK );
-  InitializeVisual( mActorForComposite, mVisualForEmboss2, mImageForEmboss2 );
+  Internal::InitializeVisual( mActorForComposite, mVisualForEmboss2, mImageForEmboss2 );
   Toolkit::GetImplementation( mVisualForEmboss2 ).SetCustomShader( customShader );
   mActorForComposite.GetRendererAt(1).RegisterProperty( COLOR_UNIFORM_NAME, Color::WHITE );
 
@@ -162,8 +163,8 @@ void EmbossFilter::Disable()
 
     if( mActorForComposite )
     {
-      mVisualForEmboss1.SetOffStage( mActorForComposite );
-      mVisualForEmboss2.SetOffStage( mActorForComposite );
+      Toolkit::GetImplementation(mVisualForEmboss1).SetOffStage( mActorForComposite );
+      Toolkit::GetImplementation(mVisualForEmboss2).SetOffStage( mActorForComposite );
       mVisualForEmboss1.Reset();
       mVisualForEmboss2.Reset();
       mRootActor.Remove( mActorForComposite );
@@ -181,6 +182,11 @@ void EmbossFilter::Disable()
       taskList.RemoveTask(mRenderTaskForEmboss2);
     }
 
+    if( mRenderTaskForOutput )
+    {
+      taskList.RemoveTask( mRenderTaskForOutput );
+    }
+
     mRootActor.Reset();
   }
 }
index d25ea5c..06065b7 100644 (file)
@@ -34,7 +34,7 @@ namespace Internal
 AsyncImageLoader::AsyncImageLoader()
 : mLoadedSignal(),
   mLoadThread( new EventThreadCallback( MakeCallback( this, &AsyncImageLoader::ProcessLoadedImage ) ) ),
-  mLoadTaskId( 0 ),
+  mLoadTaskId( 0u ),
   mIsLoadThreadStarted( false )
 {
 }
@@ -51,7 +51,7 @@ IntrusivePtr<AsyncImageLoader> AsyncImageLoader::New()
 }
 
 uint32_t AsyncImageLoader::Load( const std::string& url,
-                                 ImageDimensions size,
+                                 ImageDimensions dimensions,
                                  FittingMode::Type fittingMode,
                                  SamplingMode::Type samplingMode,
                                  bool orientationCorrection )
@@ -62,7 +62,7 @@ uint32_t AsyncImageLoader::Load( const std::string& url,
     mIsLoadThreadStarted = true;
   }
 
-  BitmapLoader loader = BitmapLoader::New( url, size, fittingMode, samplingMode, orientationCorrection );
+  BitmapLoader loader = BitmapLoader::New( url, dimensions, fittingMode, samplingMode, orientationCorrection );
 
   mLoadThread.AddTask( new LoadingTask( ++mLoadTaskId, loader ) );
 
index cb0311c..92a1652 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H__
-#define DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H__
+#ifndef DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H
+#define DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
@@ -22,7 +22,7 @@
 #include <dali/public-api/object/base-object.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/image-loader/async-image-loader.h>
+#include <dali-toolkit/public-api/image-loader/async-image-loader.h>
 #include <dali-toolkit/internal/image-loader/image-load-thread.h>
 
 namespace Dali
@@ -49,10 +49,10 @@ public:
   static IntrusivePtr<AsyncImageLoader> New();
 
   /**
-   * @copydoc Toolkit::AsyncImageLoader::Load( const std::string&, ImageDimensions,FittingMode::Type, SamplingMode::Type, bool )
+   * @copydoc Toolkit::AsyncImageLoader::Load( const std::string&, ImageDimensions, FittingMode::Type, SamplingMode::Type, bool )
    */
   uint32_t Load( const std::string& url,
-                 ImageDimensions size,
+                 ImageDimensions dimensions,
                  FittingMode::Type fittingMode,
                  SamplingMode::Type samplingMode,
                  bool orientationCorrection );
@@ -97,20 +97,20 @@ private:
 
 } // namespace Internal
 
-inline const Internal::AsyncImageLoader& GetImplementation( const Toolkit::AsyncImageLoader& loader )
+inline const Internal::AsyncImageLoader& GetImplementation( const Toolkit::AsyncImageLoader& handle )
 {
-  DALI_ASSERT_ALWAYS( loader && "AsyncImageLoader handle is empty" );
+  DALI_ASSERT_ALWAYS( handle && "AsyncImageLoader handle is empty" );
 
-  const BaseObject& object = loader.GetBaseObject();
+  const BaseObject& object = handle.GetBaseObject();
 
   return static_cast<const Internal::AsyncImageLoader&>( object );
 }
 
-inline Internal::AsyncImageLoader& GetImplementation( Toolkit::AsyncImageLoader& loader )
+inline Internal::AsyncImageLoader& GetImplementation( Toolkit::AsyncImageLoader& handle )
 {
-  DALI_ASSERT_ALWAYS( loader && "AsyncImageLoader handle is empty" );
+  DALI_ASSERT_ALWAYS( handle && "AsyncImageLoader handle is empty" );
 
-  BaseObject& object = loader.GetBaseObject();
+  BaseObject& object = handle.GetBaseObject();
 
   return static_cast<Internal::AsyncImageLoader&>( object );
 }
@@ -119,4 +119,4 @@ inline Internal::AsyncImageLoader& GetImplementation( Toolkit::AsyncImageLoader&
 
 } // namespace Dali
 
-#endif /* DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H__ */
+#endif // DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H
index a773ea7..4f735ef 100644 (file)
@@ -27,8 +27,8 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
-#include <dali-toolkit/devel-api/image-loader/async-image-loader.h>
 #include <dali-toolkit/internal/image-loader/atlas-packer.h>
+#include <dali-toolkit/public-api/image-loader/async-image-loader.h>
 
 namespace Dali
 {
index a27db14..11e251a 100644 (file)
@@ -50,7 +50,7 @@ ImageLoadThread::~ImageLoadThread()
 
 void ImageLoadThread::Run()
 {
-  while( LoadingTask* task =  NextTaskToProcess())
+  while( LoadingTask* task = NextTaskToProcess() )
   {
     task->loader.Load();
     AddCompletedTask( task );
@@ -68,7 +68,7 @@ void ImageLoadThread::AddTask( LoadingTask* task )
     mLoadQueue.PushBack( task );
   }
 
-  if( wasEmpty)
+  if( wasEmpty )
   {
     // wake up the image loading thread
     mConditionalWait.Notify();
@@ -97,7 +97,7 @@ bool ImageLoadThread::CancelTask( uint32_t loadingTaskId )
   // Lock while remove task from the queue
   ConditionalWait::ScopedLock lock( mConditionalWait );
 
-  for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); iter++ )
+  for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); ++iter )
   {
     if( (*iter)->id == loadingTaskId )
     {
@@ -116,9 +116,9 @@ void ImageLoadThread::CancelAll()
   // Lock while remove task from the queue
   ConditionalWait::ScopedLock lock( mConditionalWait );
 
-  for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); iter++ )
+  for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); ++iter )
   {
-    delete (*iter);
+    delete ( *iter );
   }
   mLoadQueue.Clear();
 }
index 608ea7d..3a89308 100644 (file)
@@ -26,7 +26,6 @@
 #include <dali-toolkit/internal/text/input-style.h>
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
 #include <dali-toolkit/internal/text/logical-model-impl.h>
-#include <dali-toolkit/internal/text/text-scroller-data.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/text-view.h>
 #include <dali-toolkit/internal/text/visual-model-impl.h>
@@ -298,7 +297,6 @@ struct Controller::Impl
     mEmbossDefaults( NULL ),
     mOutlineDefaults( NULL ),
     mEventData( NULL ),
-    mAutoScrollData( NULL ),
     mFontClient(),
     mClipboard(),
     mView(),
@@ -313,7 +311,8 @@ struct Controller::Impl
     mRecalculateNaturalSize( true ),
     mMarkupProcessorEnabled( false ),
     mClipboardHideEnabled( true ),
-    mIsAutoScrollEnabled( false )
+    mIsAutoScrollEnabled( false ),
+    mAutoScrollDirectionRTL( false )
   {
     mLogicalModel = LogicalModel::New();
     mVisualModel  = VisualModel::New();
@@ -340,7 +339,6 @@ struct Controller::Impl
     delete mEmbossDefaults;
     delete mOutlineDefaults;
     delete mEventData;
-    delete mAutoScrollData;
   }
 
   // Text Controller Implementation.
@@ -703,7 +701,6 @@ public:
   EmbossDefaults* mEmbossDefaults;         ///< Avoid allocating this when the user does not specify emboss parameters.
   OutlineDefaults* mOutlineDefaults;       ///< Avoid allocating this when the user does not specify outline parameters.
   EventData* mEventData;                   ///< Avoid allocating everything for text input until EnableTextInput().
-  ScrollerData* mAutoScrollData;           ///< Avoid allocating this when the user does not specify the auto text scrolling feature.
   TextAbstraction::FontClient mFontClient; ///< Handle to the font client.
   Clipboard mClipboard;                    ///< Handle to the system clipboard
   View mView;                              ///< The view interface to the rendering back-end.
@@ -722,8 +719,10 @@ public:
 
   bool mRecalculateNaturalSize:1;          ///< Whether the natural size needs to be recalculated.
   bool mMarkupProcessorEnabled:1;          ///< Whether the mark-up procesor is enabled.
-  bool mClipboardHideEnabled:1;            ///< Whether the ClipboardHide function work or not.
+  bool mClipboardHideEnabled:1;            ///< Whether the ClipboardHide function work or not
   bool mIsAutoScrollEnabled:1;             ///< Whether auto text scrolling is enabled.
+  CharacterDirection mAutoScrollDirectionRTL:1;  ///< Direction of auto scrolling, true if rtl
+
 };
 
 } // namespace Text
index 769d0e0..11a9161 100644 (file)
@@ -118,11 +118,6 @@ ControllerPtr Controller::New( ControlInterface* controlInterface,
                                         editableControlInterface ) );
 }
 
-void Controller::SetTextControlInterface( ControlInterface* controlInterface )
-{
-  mImpl->mControlInterface = controlInterface;
-}
-
 // public : Configure the text controller.
 
 void Controller::EnableTextInput( DecoratorPtr decorator )
@@ -170,10 +165,6 @@ void Controller::SetAutoScrollEnabled( bool enable )
                                                                UPDATE_DIRECTION          |
                                                                REORDER );
 
-      if( NULL == mImpl->mAutoScrollData )
-      {
-        mImpl->mAutoScrollData = new ScrollerData();
-      }
     }
     else
     {
@@ -202,87 +193,22 @@ bool Controller::IsAutoScrollEnabled() const
   return mImpl->mIsAutoScrollEnabled;
 }
 
-void Controller::SetAutoscrollSpeed( int scrollSpeed )
-{
-  if( NULL == mImpl->mAutoScrollData )
-  {
-    mImpl->mAutoScrollData = new ScrollerData();
-  }
-
-  mImpl->mAutoScrollData->mScrollSpeed = scrollSpeed;
-}
-
-int Controller::GetAutoScrollSpeed() const
-{
-  if( NULL != mImpl->mAutoScrollData )
-  {
-    return mImpl->mAutoScrollData->mScrollSpeed;
-  }
-
-  return 0;
-}
-
-void Controller::SetAutoScrollLoopCount( int loopCount )
-{
-  if( NULL == mImpl->mAutoScrollData )
-  {
-    mImpl->mAutoScrollData = new ScrollerData();
-  }
-
-  mImpl->mAutoScrollData->mLoopCount = loopCount;
-}
-
-int Controller::GetAutoScrollLoopCount() const
-{
-  if( NULL != mImpl->mAutoScrollData )
-  {
-    return mImpl->mAutoScrollData->mLoopCount;
-  }
-
-  return 0;
-}
-
-void Controller::SetAutoScrollWrapGap( float wrapGap )
+CharacterDirection Controller::GetAutoScrollDirection() const
 {
-  if( NULL == mImpl->mAutoScrollData )
-  {
-    mImpl->mAutoScrollData = new ScrollerData();
-  }
-
-  mImpl->mAutoScrollData->mWrapGap = wrapGap;
+  return mImpl->mAutoScrollDirectionRTL;
 }
 
-float Controller::GetAutoScrollWrapGap() const
+float Controller::GetAutoScrollLineAlignment() const
 {
-  if( NULL != mImpl->mAutoScrollData )
-  {
-    return mImpl->mAutoScrollData->mWrapGap;
-  }
-
-  return 0.f;
-}
+  float offset = 0.f;
 
-const ScrollerData* const Controller::GetAutoScrollData()
-{
-  if( NULL != mImpl->mAutoScrollData )
+  if( mImpl->mVisualModel &&
+      ( 0u != mImpl->mVisualModel->mLines.Count() ) )
   {
-    // Need to update the data with the latest layout.
-    if( mImpl->mVisualModel )
-    {
-      mImpl->mAutoScrollData->mControlSize = mImpl->mVisualModel->mControlSize;
-      mImpl->mAutoScrollData->mOffscreenSize = GetNaturalSize().GetVectorXY();
-
-      mImpl->mAutoScrollData->mAlignmentOffset = 0.f;
-      if( 0u != mImpl->mVisualModel->mLines.Count() )
-      {
-        mImpl->mAutoScrollData->mAlignmentOffset = ( *mImpl->mVisualModel->mLines.Begin() ).alignmentOffset;
-      }
-    }
-
-    return mImpl->mAutoScrollData;
+    offset = ( *mImpl->mVisualModel->mLines.Begin() ).alignmentOffset;
   }
 
-  return NULL;
+  return offset;
 }
 
 void Controller::SetHorizontalScrollEnabled( bool enable )
@@ -2202,17 +2128,6 @@ void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Butt
   }
 }
 
-// private : Inherit from TextScroller.
-
-void Controller::ScrollingFinished()
-{
-  // Pure Virtual from TextScroller Interface
-  SetAutoScrollEnabled( false );
-  GetLayoutEngine().SetTextEllipsisEnabled( true );
-
-  mImpl->RequestRelayout();
-}
-
 // private : Update.
 
 void Controller::InsertText( const std::string& text, Controller::InsertType type )
@@ -2678,10 +2593,7 @@ bool Controller::DoRelayout( const Size& size,
 
       if ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) )
       {
-        if( NULL != mImpl->mAutoScrollData )
-        {
-          mImpl->mAutoScrollData->mAutoScrollDirectionRTL = false;
-        }
+        mImpl->mAutoScrollDirectionRTL = false;
       }
 
       // Reorder the lines
@@ -2717,11 +2629,9 @@ bool Controller::DoRelayout( const Size& size,
           if ( ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) && ( numberOfLines > 0 ) )
           {
             const LineRun* const firstline = mImpl->mVisualModel->mLines.Begin();
-            if( firstline &&
-                mImpl->mIsAutoScrollEnabled &&
-                ( NULL != mImpl->mAutoScrollData ) )
+            if ( firstline )
             {
-              mImpl->mAutoScrollData->mAutoScrollDirectionRTL = firstline->direction;
+              mImpl->mAutoScrollDirectionRTL = firstline->direction;
             }
           }
         }
@@ -2753,7 +2663,7 @@ bool Controller::DoRelayout( const Size& size,
 #if defined(DEBUG_ENABLED)
   std::string currentText;
   GetText( currentText );
-  DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mAutoScrollDirectionRTL[%s] [%s]\n", this, ( ( NULL != mImpl->mAutoScrollData ) && mImpl->mAutoScrollData->mAutoScrollDirectionRTL)?"true":"false",  currentText.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mAutoScrollDirectionRTL[%s] [%s]\n", this, (mImpl->mAutoScrollDirectionRTL)?"true":"false",  currentText.c_str() );
 #endif
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout, view updated %s\n", ( viewUpdated ? "true" : "false" ) );
   return viewUpdated;
index ce5c51a..a78d0eb 100644 (file)
@@ -26,7 +26,6 @@
 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup-callback-interface.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
-#include <dali-toolkit/internal/text/text-scroller-interface.h>
 
 namespace Dali
 {
@@ -41,7 +40,6 @@ class Controller;
 class ControlInterface;
 class EditableControlInterface;
 class View;
-struct ScrollerData;
 
 typedef IntrusivePtr<Controller> ControllerPtr;
 
@@ -56,7 +54,7 @@ typedef IntrusivePtr<Controller> ControllerPtr;
  *
  * The text selection popup button callbacks are as well handled via the TextSelectionPopupCallbackInterface interface.
  */
-class Controller : public RefObject, public Decorator::ControllerInterface, public TextSelectionPopupCallbackInterface, public Text::ScrollerInterface
+class Controller : public RefObject, public Decorator::ControllerInterface, public TextSelectionPopupCallbackInterface
 {
 public: // Enumerated types.
 
@@ -149,13 +147,6 @@ public: // Constructor.
   static ControllerPtr New( ControlInterface* controlInterface,
                             EditableControlInterface* editableControlInterface );
 
-  /**
-   * @brief Sets the text-control interface.
-   *
-   * @param[in] controlInterface The text-control interface.
-   */
-  void SetTextControlInterface( ControlInterface* controlInterface );
-
 public: // Configure the text controller.
 
   /**
@@ -210,53 +201,17 @@ public: // Configure the text controller.
   bool IsAutoScrollEnabled() const;
 
   /**
-   * @brief Sets the speed the text should automatically scroll at.
-   *
-   * @param[in] scrollSpeed The speed of scrolling in pixels per second.
+   * @brief Get direction of the text from the first line of text,
+   * @return bool rtl (right to left) is true
    */
-  void SetAutoscrollSpeed( int scrollSpeed );
+  CharacterDirection GetAutoScrollDirection() const;
 
   /**
-   * @brief Retrieves the auto scroll speed.
+   * @brief Get the alignment offset of the first line of text.
    *
-   * @return The auto scroll speed in pixels per second.
+   * @return The alignment offset.
    */
-  int GetAutoScrollSpeed() const;
-
-  /**
-   * @brief Sets the number of loops the text should scroll.
-   *
-   * @param[in] loopCount The number of loops.
-   */
-  void SetAutoScrollLoopCount( int loopCount );
-
-  /**
-   * @brief Retrieves the number of loops the text should scroll.
-   *
-   * @return The numebr of loops.
-   */
-  int GetAutoScrollLoopCount() const;
-
-  /**
-   * @brief Sets the gap before text wraps around when scrolling.
-   *
-   * @param[in] wrapGap The gap in pixels.
-   */
-  void SetAutoScrollWrapGap( float wrapGap );
-
-  /**
-   * @brief Retrieves the gap before text wraps around when scrolling.
-   *
-   * @return The gap in pixels.
-   */
-  float GetAutoScrollWrapGap() const;
-
-  /**
-   * @brief Retrieves the text's autoscroll data.
-   *
-   * @return The text's autoscroll data.
-   */
-  const ScrollerData* const GetAutoScrollData();
+  float GetAutoScrollLineAlignment() const;
 
   /**
    * @brief Enables the horizontal scrolling.
@@ -956,13 +911,6 @@ protected: // Inherit from TextSelectionPopup::TextPopupButtonCallbackInterface.
    */
   virtual void TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Buttons button );
 
-private: // Inherit from TextScroller
-
-  /**
-   * @copydoc Text::ScrollerInterface::ScrollingFinished()
-   */
-  virtual void ScrollingFinished();
-
 private: // Update.
 
   /**
diff --git a/dali-toolkit/internal/text/text-scroller-data.cpp b/dali-toolkit/internal/text/text-scroller-data.cpp
deleted file mode 100644 (file)
index d938911..0000000
+++ /dev/null
@@ -1,47 +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.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/text/text-scroller-data.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Text
-{
-
-const int MINIMUM_SCROLL_SPEED = 1;
-
-ScrollerData::ScrollerData()
-: mScrollSpeed( MINIMUM_SCROLL_SPEED ),
-  mLoopCount( 1 ),
-  mWrapGap( 0.f ),
-  mAlignmentOffset( 0.f ),
-  mAutoScrollDirectionRTL( false )
-{}
-
-ScrollerData::~ScrollerData()
-{}
-
-} // namespace Text
-
-} // namespace Toolkit
-
-} // namespace Dali
diff --git a/dali-toolkit/internal/text/text-scroller-data.h b/dali-toolkit/internal/text/text-scroller-data.h
deleted file mode 100644 (file)
index 3ba08c9..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef DALI_TOOLKIT_TEXT_SCROLLER_DATA_H
-#define DALI_TOOLKIT_TEXT_SCROLLER_DATA_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.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/math/vector2.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/text-definitions.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Text
-{
-
-extern const int MINIMUM_SCROLL_SPEED; // Speed should be set by Property system.
-
-/**
- * @brief Stores the autoscroll data.
- */
-struct ScrollerData
-{
-  ScrollerData();
-  ~ScrollerData();
-
-  Size               mControlSize;            ///< The size of the control to scroll within.
-  Size               mOffscreenSize;          ///< The size of the sourceActor.
-  int                mScrollSpeed;            ///< Speed which text should automatically scroll at.
-  int                mLoopCount;              ///< Number of time the text should scroll.
-  float              mWrapGap;                ///< Gap before text wraps around when scrolling.
-  float              mAlignmentOffset;        ///< The alignment offset of the first line of text to be scrolled.
-  CharacterDirection mAutoScrollDirectionRTL; ///< Direction of auto scrolling, true if rtl.
-};
-
-} // namespace Text
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // DALI_TOOLKIT_TEXT_SCROLLER_H
-
index ee1d241..d2f9348 100644 (file)
@@ -31,7 +31,6 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/text-scroller-interface.h>
-#include <dali-toolkit/internal/text/text-scroller-data.h>
 
 namespace Dali
 {
@@ -39,11 +38,6 @@ namespace Dali
 namespace Toolkit
 {
 
-namespace Text
-{
-extern const int MINIMUM_SCROLL_SPEED;
-} // namespace
-
 namespace
 {
 
@@ -51,6 +45,8 @@ namespace
   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_SCROLLING");
 #endif
 
+const int MINIMUM_SCROLL_SPEED = 1; // Speed should be set by Property system.
+
 const char* VERTEX_SHADER_SCROLL = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   varying highp vec2 vTexCoord;\n
@@ -199,6 +195,50 @@ TextScrollerPtr TextScroller::New( ScrollerInterface& scrollerInterface )
   return textScroller;
 }
 
+void TextScroller::SetGap( int gap )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetGap gap[%d]\n", gap );
+  mWrapGap = static_cast<float>(gap);
+}
+
+int TextScroller::GetGap() const
+{
+  return static_cast<int>(mWrapGap);
+}
+
+void TextScroller::SetSpeed( int scrollSpeed )
+{
+  mScrollSpeed = std::max( MINIMUM_SCROLL_SPEED, scrollSpeed );
+}
+
+int TextScroller::GetSpeed() const
+{
+  return mScrollSpeed;
+}
+
+void TextScroller::SetLoopCount( int loopCount )
+{
+  if ( loopCount > 0 )
+  {
+    mLoopCount = loopCount;
+  }
+
+  if (  mScrollAnimation && mScrollAnimation.GetState() == Animation::PLAYING )
+  {
+    if ( loopCount == 0 ) // Request to stop looping
+    {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount Single loop forced\n" );
+      mScrollAnimation.SetLoopCount( 1 ); // As animation already playing this allows the current animation to finish instead of trying to stop mid-way
+    }
+  }
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount [%d] Status[%s]\n", mLoopCount, (loopCount)?"looping":"stop" );
+}
+
+int TextScroller::GetLoopCount() const
+{
+  return mLoopCount;
+}
+
 Actor TextScroller::GetSourceCamera() const
 {
   return mOffscreenCameraActor;
@@ -209,9 +249,11 @@ Actor TextScroller::GetScrollingText() const
   return mScrollingTextActor;
 }
 
-TextScroller::TextScroller( ScrollerInterface& scrollerInterface )
-: mScrollerInterface( scrollerInterface ),
-  mScrollDeltaIndex( Property::INVALID_INDEX )
+TextScroller::TextScroller( ScrollerInterface& scrollerInterface ) : mScrollerInterface( scrollerInterface ),
+                            mScrollDeltaIndex( Property::INVALID_INDEX ),
+                            mScrollSpeed( MINIMUM_SCROLL_SPEED ),
+                            mLoopCount( 1 ),
+                            mWrapGap( 0.0f )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller Default Constructor\n" );
 }
@@ -221,71 +263,49 @@ TextScroller::~TextScroller()
   CleanUp();
 }
 
-void TextScroller::StartScrolling( Actor sourceActor,
-                                   const ScrollerData& data )
+void TextScroller::SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset )
 {
-  DALI_LOG_INFO( gLogFilter,
-                 Debug::Verbose,
-                 "TextScroller::StartScrolling controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f]\n",
-                 data.mControlSize.x, data.mControlSize.y,
-                 data.mOffscreenSize.x, data.mOffscreenSize.y,
-                 data.mAutoScrollDirectionRTL,
-                 data.mAlignmentOffset );
-
-  FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( data.mOffscreenSize.width, data.mOffscreenSize.height, Pixel::RGBA8888 );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f]\n",
+                 controlSize.x, controlSize.y, offScreenSize.x, offScreenSize.y, direction, alignmentOffset );
+
+  FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( offScreenSize.width, offScreenSize.height, Pixel::RGBA8888 );
   Renderer renderer;
 
-  CreateCameraActor( data.mOffscreenSize, mOffscreenCameraActor );
+  CreateCameraActor( offScreenSize, mOffscreenCameraActor );
   CreateRenderer( offscreenRenderTargetForText, renderer );
   CreateRenderTask( sourceActor, mOffscreenCameraActor, offscreenRenderTargetForText, mRenderTask );
 
   // Reposition camera to match alignment of target, RTL text has direction=true
-  if( data.mAutoScrollDirectionRTL )
+  if ( direction )
   {
-    mOffscreenCameraActor.SetX( data.mAlignmentOffset + data.mOffscreenSize.width * 0.5f );
+    mOffscreenCameraActor.SetX( alignmentOffset + offScreenSize.width*0.5f );
   }
   else
   {
-    mOffscreenCameraActor.SetX( data.mOffscreenSize.width * 0.5f );
+    mOffscreenCameraActor.SetX( offScreenSize.width * 0.5f );
   }
 
-  mOffscreenCameraActor.SetY( data.mOffscreenSize.height * 0.5f );
+  mOffscreenCameraActor.SetY( offScreenSize.height * 0.5f );
 
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", data.mWrapGap )
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", mWrapGap )
 
   mScrollingTextActor = Actor::New();
   mScrollingTextActor.AddRenderer( renderer );
-  mScrollingTextActor.RegisterProperty( "uTextureSize", data.mOffscreenSize );
-  mScrollingTextActor.RegisterProperty( "uRtl", ( data.mAutoScrollDirectionRTL ? 1.f : 0.f ) );
-  mScrollingTextActor.RegisterProperty( "uGap", data.mWrapGap );
-  mScrollingTextActor.SetSize( data.mControlSize.width, std::min( data.mOffscreenSize.height, data.mControlSize.height ) );
+  mScrollingTextActor.RegisterProperty( "uTextureSize", offScreenSize );
+  mScrollingTextActor.RegisterProperty( "uRtl", ((direction)?1.0f:0.0f) );
+  mScrollingTextActor.RegisterProperty( "uGap", mWrapGap );
+  mScrollingTextActor.SetSize( controlSize.width, std::min( offScreenSize.height, controlSize.height ) );
   mScrollDeltaIndex = mScrollingTextActor.RegisterProperty( "uDelta", 0.0f );
 
-  float scrollAmount = std::max( data.mOffscreenSize.width + data.mWrapGap, data.mControlSize.width );
-  float scrollSpeed = std::max( MINIMUM_SCROLL_SPEED, data.mScrollSpeed );
-  float scrollDuration =  scrollAmount / scrollSpeed;
+  float scrollAmount = std::max( offScreenSize.width + mWrapGap, controlSize.width );
+  float scrollDuration =  scrollAmount / mScrollSpeed;
 
-  if( data.mAutoScrollDirectionRTL )
+  if ( direction  )
   {
      scrollAmount = -scrollAmount; // reverse direction of scrollung
   }
 
-  mScrollAnimation = Animation::New( scrollDuration );
-  mScrollAnimation.AnimateTo( Property( mScrollingTextActor, mScrollDeltaIndex ), scrollAmount );
-  mScrollAnimation.SetEndAction( Animation::Discard );
-  mScrollAnimation.SetLoopCount( data.mLoopCount );
-  mScrollAnimation.FinishedSignal().Connect( this, &TextScroller::AutoScrollAnimationFinished );
-  mScrollAnimation.Play();
-}
-
-void TextScroller::StopScrolling()
-{
-  if( mScrollAnimation &&
-      ( mScrollAnimation.GetState() == Animation::PLAYING ) )
-  {
-    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount Single loop forced\n" );
-    mScrollAnimation.SetLoopCount( 1 ); // As animation already playing this allows the current animation to finish instead of trying to stop mid-way
-  }
+  StartScrolling( scrollAmount, scrollDuration, mLoopCount );
 }
 
 void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation )
@@ -295,6 +315,18 @@ void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation )
   mScrollerInterface.ScrollingFinished();
 }
 
+void TextScroller::StartScrolling( float scrollAmount, float scrollDuration, int loopCount )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::StartScrolling scrollAmount[%f] scrollDuration[%f], loop[%d] speed[%d]\n", scrollAmount, scrollDuration, loopCount, mScrollSpeed );
+
+  mScrollAnimation = Animation::New( scrollDuration );
+  mScrollAnimation.AnimateTo( Property( mScrollingTextActor, mScrollDeltaIndex ), scrollAmount );
+  mScrollAnimation.SetEndAction( Animation::Discard );
+  mScrollAnimation.SetLoopCount( loopCount );
+  mScrollAnimation.FinishedSignal().Connect( this, &TextScroller::AutoScrollAnimationFinished );
+  mScrollAnimation.Play();
+}
+
 void TextScroller::CleanUp()
 {
   if ( Stage::IsInstalled() )
index a40be3f..17824b6 100644 (file)
@@ -37,7 +37,6 @@ namespace Text
 
 class TextScroller;
 class ScrollerInterface;
-struct ScrollerData;
 
 typedef IntrusivePtr<TextScroller> TextScrollerPtr;
 
@@ -47,6 +46,7 @@ typedef IntrusivePtr<TextScroller> TextScrollerPtr;
 class TextScroller : public RefObject, public ConnectionTracker
 {
 public:
+
   /**
    * @brief Text Scrolling helper, used to automatically scroll text, SetParameters should be called before scrolling is needed.
    * CleanUp removes the Scrolling actors from stage whilst keeping the Scroller object alive and preserving Speed, Gap and Loop count.
@@ -56,19 +56,52 @@ public:
   static TextScrollerPtr New( ScrollerInterface& scrollerInterface );
 
   /**
-   * @brief Starts the text scrolling.
+   * @brief Set parameters relating to source required for scrolling
    *
    * @param[in] sourceActor source actor to be scrolled
-   * @param[in] data Parameters needed to set up the text scrolling.
+   * @param[in] controlSize size of the control to scroll within
+   * @param[in] offScreenSize size of the sourceActor
+   * @param[in] direction text direction true for right to left text
+   * @param[in] alignmentOffset alignment of source text
    *
    */
-  void StartScrolling( Actor sourceActor,
-                       const ScrollerData& data );
+  void SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset );
+
+  /**
+   * @brief Set the gap distance to elapse before the text wraps around
+   * @param[in] gap distance to elapse
+   */
+  void SetGap( int gap );
+
+  /**
+   * @brief Get the distance before scrolling wraps
+   * @return gap distance to elapse
+   */
+  int GetGap() const;
+
+  /**
+   * @brief Set speed the text should scroll
+   * @param[in] scrollSpeed pixels per second
+   */
+  void SetSpeed( int scrollSpeed );
 
   /**
-   * @brief Stops the text scrolling.
+   * @brief Get the speed of text scrolling
+   * @return speed in pixels per second
    */
-  void StopScrolling();
+  int GetSpeed() const;
+
+  /**
+   * @brief Set the number of times the text scrolling should loop, can stop current scrolling by passing in 0;
+   * @param[in] loopCount number of times the scrolled text should loop, 0 to stop scrolling
+   */
+  void SetLoopCount( int loopCount );
+
+  /**
+   * @brief Get the number of loops
+   * @return int number of loops
+   */
+  int GetLoopCount() const;
 
   /**
    * @brief Get the camera used to look at source, should be added to the parent of target actor.
@@ -107,6 +140,14 @@ private: // Implementation
   void AutoScrollAnimationFinished( Dali::Animation& animation );
 
   /**
+   * @brief variables required to set up scrolling animation
+   * @param[in] scrollAmount distance to animate text for the given duration
+   * @param[in] scrollDuration duration of aninmation
+   * @param[in] loopCount number of times to loop the scrolling text
+   */
+  void StartScrolling( float scrollAmount, float scrollDuration, int loopCount );
+
+  /**
    * @brief When scrolling ended, the actors are cleaned up so no longer staged.
    */
   void CleanUp();
@@ -120,6 +161,10 @@ private:
   Property::Index    mScrollDeltaIndex;         // Property used by shader to represent distance to scroll
   Animation          mScrollAnimation;          // Animation used to update the mScrollDeltaIndex
 
+  int   mScrollSpeed;            ///< Speed which text should automatically scroll at
+  int   mLoopCount;              ///< Number of time the text should scroll
+  float mWrapGap;                ///< Gap before text wraps around when scrolling
+
 }; // TextScroller class
 
 } // namespace Text
index e0ae085..6f50a9a 100644 (file)
@@ -222,7 +222,8 @@ GradientVisualPtr GradientVisual::New( VisualFactoryCache& factoryCache )
 
 GradientVisual::GradientVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
-  mGradientType( LINEAR )
+  mGradientType( LINEAR ),
+  mIsOpaque( true )
 {
   mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
 }
@@ -362,6 +363,12 @@ void GradientVisual::InitializeRenderer()
   mImpl->mRenderer = Renderer::New( geometry, shader );
   mImpl->mRenderer.SetTextures( textureSet );
 
+  // If opaque then no need to have blending
+  if( mIsOpaque )
+  {
+    mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::OFF );
+  }
+
   mImpl->mRenderer.RegisterProperty( UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform );
 
   //Register transform properties
@@ -423,6 +430,10 @@ bool GradientVisual::NewGradient(Type gradientType, const Property::Map& propert
         {
           mGradient->AddStop( offsetArray[i], Vector4(color.r*color.a, color.g*color.a, color.b*color.a, color.a));
           numValidStop++;
+          if( ! Equals( color.a, 1.0f, Math::MACHINE_EPSILON_1 ) )
+          {
+            mIsOpaque = false;
+          }
         }
       }
     }
index e4920d1..bc131ae 100644 (file)
@@ -177,6 +177,7 @@ private:
   Matrix3 mGradientTransform;
   IntrusivePtr<Gradient> mGradient;
   Type mGradientType;
+  bool mIsOpaque; ///< Set to false if any of the stop colors are not opaque
 };
 
 } // namespace Internal
index fe803b2..90d2b53 100644 (file)
@@ -132,7 +132,7 @@ void BatchImageVisual::SetSize( const Vector2& size )
   Visual::Base::SetSize( size );
 }
 
-void BatchImageVisual::GetNaturalSize( Vector2& naturalSize ) const
+void BatchImageVisual::GetNaturalSize( Vector2& naturalSize )
 {
   if( mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0 )
   {
index d670c5d..85ef5b4 100644 (file)
@@ -57,7 +57,7 @@ public:  // from Visual
   /**
    * @copydoc Visual::Base::GetNaturalSize
    */
-  virtual void GetNaturalSize( Vector2& naturalSize ) const;
+  virtual void GetNaturalSize( Vector2& naturalSize );
 
   /**
    * @copydoc Visual::Base::CreatePropertyMap
index 44d9810..54527de 100644 (file)
@@ -332,7 +332,7 @@ void ImageVisual::DoSetProperties( const Property::Map& propertyMap )
   }
 }
 
-void ImageVisual::GetNaturalSize( Vector2& naturalSize ) const
+void ImageVisual::GetNaturalSize( Vector2& naturalSize )
 {
   if(mImage)
   {
@@ -700,27 +700,13 @@ void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const
 
 void ImageVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
 {
-  // This is where specific Properties can be set.
+  // TODO
 }
 
 Dali::Property::Value ImageVisual::DoGetProperty( Dali::Property::Index index )
 {
-  Dali::Property::Value value;
-
-  switch( index )
-  {
-    case Toolkit::ImageVisual::Property::URL:
-    {
-      value = mImageUrl;
-      break;
-    }
-    default:
-    {
-      break;
-    }
-  }
-
-  return value;
+  // TODO
+  return Dali::Property::Value();
 }
 
 void ImageVisual::OnSetTransform()
@@ -742,6 +728,7 @@ Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache, bool atlas
       if( !shader )
       {
         shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP );
+        shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
         factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP, shader );
       }
     }
@@ -751,6 +738,7 @@ Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache, bool atlas
       if( !shader )
       {
         shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP );
+        shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
         factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP, shader );
       }
     }
@@ -761,10 +749,11 @@ Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache, bool atlas
     if( !shader )
     {
       shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_NO_ATLAS );
+      shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
       factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER, shader );
     }
   }
-  shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+
   return shader;
 }
 
index 7ad511f..de25d60 100644 (file)
@@ -109,7 +109,7 @@ public:  // from Visual
   /**
    * @copydoc Visual::Base::GetNaturalSize
    */
-  virtual void GetNaturalSize( Vector2& naturalSize ) const;
+  virtual void GetNaturalSize( Vector2& naturalSize );
 
   /**
    * @copydoc Visual::Base::CreatePropertyMap
diff --git a/dali-toolkit/internal/visuals/npatch-loader.cpp b/dali-toolkit/internal/visuals/npatch-loader.cpp
new file mode 100644 (file)
index 0000000..026450d
--- /dev/null
@@ -0,0 +1,97 @@
+ /*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/visuals/npatch-loader.h>
+
+// EXTERNAL HEADER
+#include <dali/devel-api/common/hash.h>
+#include <dali/devel-api/images/texture-set-image.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+NPatchLoader::NPatchLoader()
+{
+}
+
+NPatchLoader::~NPatchLoader()
+{
+}
+
+std::size_t NPatchLoader::Load( const std::string& url )
+{
+  std::size_t hash = CalculateHash( url );
+  OwnerContainer< Data* >::SizeType index = UNINITIALIZED_ID;
+  const OwnerContainer< Data* >::SizeType count = mCache.Count();
+  for( ; index < count; ++index )
+  {
+    if( mCache[ index ]->hash == hash )
+    {
+      // hash match, check url as well in case of hash collision
+      if( mCache[ index ]->url == url )
+      {
+        return index+1u; // valid indices are from 1 onwards
+      }
+    }
+  }
+  // got to the end so no match, decode N patch and append new item to cache
+  NinePatchImage ninePatch = NinePatchImage::New( url );
+  if( ninePatch )
+  {
+    Data* data = new Data();
+    data->hash = hash;
+    data->url = url;
+    BufferImage croppedImage = ninePatch.CreateCroppedBufferImage();
+    if( croppedImage )
+    {
+      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
+    }
+  }
+  return 0u;
+}
+
+bool NPatchLoader::GetNPatchData( std::size_t id, const Data*& data )
+{
+  if( ( id > UNINITIALIZED_ID )&&( id <= mCache.Count() ) )
+  {
+    data = mCache[ id - 1u ]; // id's start from 1u
+    return true;
+  }
+  data = NULL;
+  return false;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/visuals/npatch-loader.h b/dali-toolkit/internal/visuals/npatch-loader.h
new file mode 100644 (file)
index 0000000..0d9a1c2
--- /dev/null
@@ -0,0 +1,119 @@
+#ifndef DALI_TOOLKIT_NPATCH_LOADER_H
+#define DALI_TOOLKIT_NPATCH_LOADER_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.
+ */
+
+// EXTERNAL INCLUDES
+#include <string>
+#include <dali/public-api/rendering/texture-set.h>
+#include <dali/devel-api/common/owner-container.h>
+#include <dali/devel-api/images/nine-patch-image.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/image-loader/image-atlas.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * The manager for loading Npatch textures.
+ * It caches them internally for better performance; i.e. to avoid loading and
+ * parsing the files over and over.
+ *
+ * Cache is not cleaned during app lifecycle as N patches take considerably
+ * small space and there's not usually a lot of them. Usually N patches are specified in
+ * toolkit default style and there is 1-2 per control that are shared across the whole application.
+ */
+class NPatchLoader
+{
+public:
+
+  enum
+  {
+    UNINITIALIZED_ID = 0 ///< uninitialised id, use to initialize ids
+  };
+
+  struct Data
+  {
+    std::string url;                              ///< Url of the N-Patch
+    TextureSet textureSet;                        ///< Texture containing the cropped image
+    NinePatchImage::StretchRanges stretchPixelsX; ///< X stretch pixels
+    NinePatchImage::StretchRanges stretchPixelsY; ///< Y stretch pixels
+    std::size_t hash;                             ///< Hash code for the Url
+    uint32_t croppedWidth;                        ///< Width of the cropped middle part of N-patch
+    uint32_t croppedHeight;                       ///< Height of the cropped middle part of N-patch
+  };
+
+public:
+
+  /**
+   * Constructor
+   */
+  NPatchLoader();
+
+  /**
+   * Destructor, non-virtual as not a base class
+   */
+  ~NPatchLoader();
+
+  /**
+   * @brief Retrieve a texture matching the n-patch url.
+   *
+   * @param [in] url to retrieve
+   * @return id of the texture.
+   */
+  std::size_t Load( const std::string& url );
+
+  /**
+   * @brief Retrieve N patch data matching to an id
+   * @param [in] id of data
+   * @param [out] data const pointer to the data
+   * @return true if data matching to id was really found
+   */
+  bool GetNPatchData( std::size_t id, const Data*& data );
+
+protected:
+
+  /**
+   * Undefined copy constructor.
+   */
+  NPatchLoader(const NPatchLoader&);
+
+  /**
+   * Undefined assignment operator.
+   */
+  NPatchLoader& operator=(const NPatchLoader& rhs);
+
+private:
+
+  OwnerContainer< Data* > mCache;
+
+};
+
+} // name Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_NPATCH_LOADER_H
index 9daf0eb..60fdf58 100644 (file)
@@ -27,6 +27,7 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.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>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -230,42 +231,38 @@ NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, const std::
   NPatchVisual* nPatchVisual = new NPatchVisual( factoryCache );
   nPatchVisual->mImageUrl = imageUrl;
 
-  NinePatchImage image = NinePatchImage::New( imageUrl );
-  nPatchVisual->InitializeFromImage( image );
-
   return nPatchVisual;
 }
 
 NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, NinePatchImage image )
 {
   NPatchVisual* nPatchVisual = new NPatchVisual( factoryCache );
-  nPatchVisual->mImage = image;
-
-  nPatchVisual->InitializeFromImage( image );
+  nPatchVisual->mImageUrl = image.GetUrl();
 
   return nPatchVisual;
 }
 
-NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache )
-: Visual::Base( factoryCache ),
-  mImage(),
-  mCroppedImage(),
-  mImageUrl(),
-  mStretchPixelsX(),
-  mStretchPixelsY(),
-  mImageSize(),
-  mBorderOnly( false )
-{
-}
-
-NPatchVisual::~NPatchVisual()
+void NPatchVisual::GetNaturalSize( Vector2& naturalSize )
 {
+  naturalSize.x = 0u;
+  naturalSize.y = 0u;
+  // load now if not already loaded
+  if( NPatchLoader::UNINITIALIZED_ID == mId )
+  {
+    mId = mLoader.Load( mImageUrl );
+  }
+  const NPatchLoader::Data* data;
+  if( mLoader.GetNPatchData( mId, data ) )
+  {
+    naturalSize.x = data->croppedWidth;
+    naturalSize.y = data->croppedHeight;
+  }
 }
 
 void NPatchVisual::DoSetProperties( const Property::Map& propertyMap )
 {
   // URL is already passed in via constructor
-  //Read the borderOnly property first since InitialiseFromImage relies on mBorderOnly to be properly set
+
   Property::Value* borderOnlyValue = propertyMap.Find( Toolkit::ImageVisual::Property::BORDER_ONLY, BORDER_ONLY );
   if( borderOnlyValue )
   {
@@ -273,77 +270,133 @@ void NPatchVisual::DoSetProperties( const Property::Map& propertyMap )
   }
 }
 
-void NPatchVisual::GetNaturalSize( Vector2& naturalSize ) const
+void NPatchVisual::DoSetOnStage( Actor& actor )
 {
-  if( mImage )
-  {
-    naturalSize.x = mImage.GetWidth();
-    naturalSize.y = mImage.GetHeight();
-  }
-  else if( !mImageUrl.empty() )
+  // load when first go on stage
+  if( NPatchLoader::UNINITIALIZED_ID == mId )
   {
-    ImageDimensions dimentions = ResourceImage::GetImageSize( mImageUrl );
-    naturalSize.x = dimentions.GetWidth();
-    naturalSize.y = dimentions.GetHeight();
+    mId = mLoader.Load( mImageUrl );
   }
-  else
+
+  Geometry geometry = CreateGeometry();
+  Shader shader = CreateShader();
+  mImpl->mRenderer = Renderer::New( geometry, shader );
+
+  ApplyTextureAndUniforms();
+
+  actor.AddRenderer( mImpl->mRenderer );
+}
+
+void NPatchVisual::DoSetOffStage( Actor& actor )
+{
+  actor.RemoveRenderer( mImpl->mRenderer );
+  mImpl->mRenderer.Reset();
+}
+
+void NPatchVisual::OnSetTransform()
+{
+  if( mImpl->mRenderer )
   {
-    naturalSize = Vector2::ZERO;
+    mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
   }
 }
 
+void NPatchVisual::DoCreatePropertyMap( Property::Map& map ) const
+{
+  map.Clear();
+  map.Insert( Toolkit::VisualProperty::TYPE, Toolkit::Visual::IMAGE );
+  map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl );
+  map.Insert( Toolkit::ImageVisual::Property::BORDER_ONLY, mBorderOnly );
+}
+
+void NPatchVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  // TODO
+}
+
+Dali::Property::Value NPatchVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
+
+NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache )
+: Visual::Base( factoryCache ),
+  mLoader( factoryCache.GetNPatchLoader() ),
+  mImageUrl(),
+  mId( NPatchLoader::UNINITIALIZED_ID ),
+  mBorderOnly( false )
+{
+}
+
+NPatchVisual::~NPatchVisual()
+{
+}
+
 Geometry NPatchVisual::CreateGeometry()
 {
   Geometry geometry;
-  if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
+  const NPatchLoader::Data* data;
+  if( mLoader.GetNPatchData( mId, data ) )
   {
-    if( !mBorderOnly )
+    if( data->stretchPixelsX.Size() == 1 && data->stretchPixelsY.Size() == 1 )
     {
-      geometry = mFactoryCache.GetGeometry( VisualFactoryCache::NINE_PATCH_GEOMETRY );
-      if( !geometry )
+      if( DALI_UNLIKELY( mBorderOnly ) )
       {
-        geometry = CreateGeometry( Uint16Pair( 3, 3 ) );
-        mFactoryCache.SaveGeometry( VisualFactoryCache::NINE_PATCH_GEOMETRY, geometry );
+        geometry = GetNinePatchGeometry( VisualFactoryCache::NINE_PATCH_BORDER_GEOMETRY );
       }
-    }
-    else
-    {
-      geometry = mFactoryCache.GetGeometry( VisualFactoryCache::NINE_PATCH_BORDER_GEOMETRY );
-      if( !geometry )
+      else
       {
-        geometry = CreateGeometryBorder( Uint16Pair( 3, 3 ) );
-        mFactoryCache.SaveGeometry( VisualFactoryCache::NINE_PATCH_BORDER_GEOMETRY, geometry );
+        geometry = GetNinePatchGeometry( VisualFactoryCache::NINE_PATCH_GEOMETRY );
       }
     }
+    else if( data->stretchPixelsX.Size() > 0 || data->stretchPixelsY.Size() > 0)
+    {
+      Uint16Pair gridSize( 2 * data->stretchPixelsX.Size() + 1,  2 * data->stretchPixelsY.Size() + 1 );
+      geometry = !mBorderOnly ? CreateGridGeometry( gridSize ) : CreateBorderGeometry( gridSize );
+    }
   }
-  else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
+  else
   {
-    Uint16Pair gridSize( 2 * mStretchPixelsX.Size() + 1,  2 * mStretchPixelsY.Size() + 1 );
-    geometry = !mBorderOnly ? CreateGeometry( gridSize ) : CreateGeometryBorder( gridSize );
+    // no N patch data so use default geometry
+    geometry = GetNinePatchGeometry( VisualFactoryCache::NINE_PATCH_GEOMETRY );
   }
-
   return geometry;
 }
 
 Shader NPatchVisual::CreateShader()
 {
   Shader shader;
-  if( !mImpl->mCustomShader )
+  const NPatchLoader::Data* data;
+  // 0 is either no data (load failed?) or no stretch regions on image
+  // for both cases we use the default shader
+  NinePatchImage::StretchRanges::SizeType xStretchCount = 0;
+  NinePatchImage::StretchRanges::SizeType yStretchCount = 0;
+
+  // ask loader for the regions
+  if( mLoader.GetNPatchData( mId, data ) )
   {
-    if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
+    xStretchCount = data->stretchPixelsX.Count();
+    yStretchCount = data->stretchPixelsY.Count();
+  }
+
+  if( DALI_LIKELY( !mImpl->mCustomShader ) )
+  {
+    if( DALI_LIKELY( ( xStretchCount == 1 && yStretchCount == 1 ) ||
+                     ( xStretchCount == 0 && yStretchCount == 0 ) ) )
     {
       shader = mFactoryCache.GetShader( VisualFactoryCache::NINE_PATCH_SHADER );
-      if( !shader )
+      if( DALI_UNLIKELY( !shader ) )
       {
         shader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER );
         mFactoryCache.SaveShader( VisualFactoryCache::NINE_PATCH_SHADER, shader );
       }
     }
-    else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
+    else if( xStretchCount > 0 || yStretchCount > 0)
     {
       std::stringstream vertexShader;
-      vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n"
-                   << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n"
+      vertexShader << "#define FACTOR_SIZE_X " << xStretchCount + 2 << "\n"
+                   << "#define FACTOR_SIZE_Y " << yStretchCount + 2 << "\n"
                    << VERTEX_SHADER;
 
       shader = Shader::New( vertexShader.str(), FRAGMENT_SHADER );
@@ -360,15 +413,16 @@ Shader NPatchVisual::CreateShader()
     }
     hints = mImpl->mCustomShader->mHints;
 
-    if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
+    if( ( xStretchCount == 1 && yStretchCount == 1 ) ||
+        ( xStretchCount == 0 && yStretchCount == 0 ) )
     {
       shader = Shader::New( VERTEX_SHADER_3X3, fragmentShader, hints );
     }
-    else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
+    else if( xStretchCount > 0 || yStretchCount > 0)
     {
       std::stringstream vertexShader;
-      vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n"
-                   << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n"
+      vertexShader << "#define FACTOR_SIZE_X " << xStretchCount + 2 << "\n"
+                   << "#define FACTOR_SIZE_Y " << yStretchCount + 2 << "\n"
                    << VERTEX_SHADER;
 
       shader = Shader::New( vertexShader.str(), fragmentShader, hints );
@@ -378,209 +432,72 @@ Shader NPatchVisual::CreateShader()
   return shader;
 }
 
-void NPatchVisual::InitializeRenderer()
+void NPatchVisual::ApplyTextureAndUniforms()
 {
-  Geometry geometry = CreateGeometry();
-  Shader shader = CreateShader();
-
-  if( !geometry || !shader )
+  const NPatchLoader::Data* data;
+  if( mLoader.GetNPatchData( mId, data ) )
   {
-    DALI_LOG_ERROR("The 9 patch image '%s' doesn't have any valid stretch borders and so is not a valid 9 patch image\n", mImageUrl.c_str() );
-    InitializeFromBrokenImage();
-  }
-
-  TextureSet textureSet = TextureSet::New();
-  mImpl->mRenderer = Renderer::New( geometry, shader );
-  mImpl->mRenderer.SetTextures( textureSet );
-
-  //Register transform properties
-  mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
-}
-
-
-void NPatchVisual::DoSetOnStage( Actor& actor )
-{
-  if( !mCroppedImage )
-  {
-    if( !mImageUrl.empty() )
+    TextureSet textures( data->textureSet );
+    mImpl->mRenderer.SetTextures( textures );
+    if( data->stretchPixelsX.Size() == 1 && data->stretchPixelsY.Size() == 1 )
     {
-      NinePatchImage nPatch = NinePatchImage::New( mImageUrl );
-      InitializeFromImage( nPatch );
-    }
-    else if( mImage )
-    {
-      InitializeFromImage( mImage );
-    }
-  }
-
-  //initialize the renderer after initializing from the image since we need to know the grid size from the image before creating the geometry
-  InitializeRenderer();
-
-  if( mCroppedImage )
-  {
-    ApplyImageToSampler();
-  }
-
-  actor.AddRenderer( mImpl->mRenderer );
-}
-
-void NPatchVisual::DoSetOffStage( Actor& actor )
-{
-  mCroppedImage.Reset();
-  actor.RemoveRenderer( mImpl->mRenderer );
-  mImpl->mRenderer.Reset();
-}
-
-void NPatchVisual::DoCreatePropertyMap( Property::Map& map ) const
-{
-  map.Clear();
-  map.Insert( Toolkit::VisualProperty::TYPE, Toolkit::Visual::IMAGE );
-  if( !mImageUrl.empty() )
-  {
-    map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl );
-  }
-  else if( mImage )
-  {
-    map.Insert( Toolkit::ImageVisual::Property::URL, mImage.GetUrl() );
-  }
-  map.Insert( Toolkit::ImageVisual::Property::BORDER_ONLY, mBorderOnly );
-}
-
-void NPatchVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
-{
-  // This is where specific Properties can be set.
-}
-
-Dali::Property::Value NPatchVisual::DoGetProperty( Dali::Property::Index index )
-{
-  Dali::Property::Value value;
-
-  switch( index )
-  {
-    case Toolkit::ImageVisual::Property::URL:
-    {
-      value = mImageUrl;
-      break;
-    }
-    case Toolkit::ImageVisual::Property::BORDER_ONLY:
-    {
-      value = mBorderOnly;
-      break;
-    }
-    default:
-    {
-      break;
-    }
-  }
-
-  return value;
-}
-
-void NPatchVisual::OnSetTransform()
-{
-  if( mImpl->mRenderer )
-  {
-    mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
-  }
-}
-
-
-void NPatchVisual::ChangeRenderer( bool oldBorderOnly, size_t oldGridX, size_t oldGridY )
-{
-  //check to see if the border style has changed
+      //special case for 9 patch
+      Uint16Pair stretchX = data->stretchPixelsX[ 0 ];
+      Uint16Pair stretchY = data->stretchPixelsY[ 0 ];
 
-  bool borderOnlyChanged = oldBorderOnly != mBorderOnly;
-  bool gridChanged = oldGridX != mStretchPixelsX.Size() || oldGridY != mStretchPixelsY.Size();
+      uint16_t stretchWidth = stretchX.GetY() - stretchX.GetX();
+      uint16_t stretchHeight = stretchY.GetY() - stretchY.GetX();
 
-  if( borderOnlyChanged || gridChanged )
-  {
-    Geometry geometry = CreateGeometry();
-    if( geometry )
-    {
-      mImpl->mRenderer.SetGeometry( geometry );
+      mImpl->mRenderer.RegisterProperty( "uFixed[0]", Vector2::ZERO );
+      mImpl->mRenderer.RegisterProperty( "uFixed[1]", Vector2( stretchX.GetX(), stretchY.GetX()) );
+      mImpl->mRenderer.RegisterProperty( "uFixed[2]", Vector2( data->croppedWidth - stretchWidth, data->croppedHeight - stretchHeight ) );
+      mImpl->mRenderer.RegisterProperty( "uStretchTotal", Vector2( stretchWidth, stretchHeight ) );
     }
     else
     {
-      InitializeFromBrokenImage();
-    }
-  }
+      mImpl->mRenderer.RegisterProperty( "uNinePatchFactorsX[0]", Vector2::ZERO );
+      mImpl->mRenderer.RegisterProperty( "uNinePatchFactorsY[0]", Vector2::ZERO );
 
-  if( gridChanged )
-  {
-    Shader shader = CreateShader();
-    TextureSet textureSet;
-    if( shader )
-    {
-      textureSet = mImpl->mRenderer.GetTextures();
-      if( !textureSet )
-      {
-        InitializeFromBrokenImage();
-      }
-      mImpl->mRenderer.SetShader( shader );
+      RegisterStretchProperties( mImpl->mRenderer, "uNinePatchFactorsX", data->stretchPixelsX, data->croppedWidth );
+      RegisterStretchProperties( mImpl->mRenderer, "uNinePatchFactorsY", data->stretchPixelsY, data->croppedHeight );
     }
   }
-}
-
-void NPatchVisual::InitializeFromImage( NinePatchImage nPatch )
-{
-  mCroppedImage = nPatch.CreateCroppedBufferImage();
-  if( !mCroppedImage )
+  else
   {
-    DALI_LOG_ERROR("'%s' specify a valid 9 patch image\n", mImageUrl.c_str() );
-    InitializeFromBrokenImage();
-    return;
+    DALI_LOG_ERROR("The N patch image '%s' is not a valid N patch image\n", mImageUrl.c_str() );
+    TextureSet textureSet = TextureSet::New();
+    mImpl->mRenderer.SetTextures( textureSet );
+    Image croppedImage = VisualFactoryCache::GetBrokenVisualImage();
+    TextureSetImage( textureSet, 0u, croppedImage );
+    mImpl->mRenderer.RegisterProperty( "uFixed[0]", Vector2::ZERO );
+    mImpl->mRenderer.RegisterProperty( "uFixed[1]", Vector2::ZERO );
+    mImpl->mRenderer.RegisterProperty( "uFixed[2]", Vector2::ZERO );
+    mImpl->mRenderer.RegisterProperty( "uStretchTotal", Vector2( croppedImage.GetWidth(), croppedImage.GetHeight() ) );
   }
 
-  mImageSize = ImageDimensions( mCroppedImage.GetWidth(), mCroppedImage.GetHeight() );
-
-  mStretchPixelsX = nPatch.GetStretchPixelsX();
-  mStretchPixelsY = nPatch.GetStretchPixelsY();
-}
-
-void NPatchVisual::InitializeFromBrokenImage()
-{
-  mCroppedImage = VisualFactoryCache::GetBrokenVisualImage();
-  mImageSize = ImageDimensions( mCroppedImage.GetWidth(), mCroppedImage.GetHeight() );
-
-  mStretchPixelsX.Clear();
-  mStretchPixelsX.PushBack( Uint16Pair( 0, mImageSize.GetWidth() ) );
-  mStretchPixelsY.Clear();
-  mStretchPixelsY.PushBack( Uint16Pair( 0, mImageSize.GetHeight() ) );
+  //Register transform properties
+  mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
 }
 
-void NPatchVisual::ApplyImageToSampler()
+Geometry NPatchVisual::GetNinePatchGeometry( VisualFactoryCache::GeometryType subType )
 {
-  TextureSet textureSet = mImpl->mRenderer.GetTextures();
-  if( textureSet )
+  Geometry geometry = mFactoryCache.GetGeometry( subType );
+  if( !geometry )
   {
-    TextureSetImage( textureSet, 0u, mCroppedImage );
-
-    if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
+    if( DALI_LIKELY( VisualFactoryCache::NINE_PATCH_GEOMETRY == subType ) )
     {
-      //special case for 9 patch
-      Uint16Pair stretchX = mStretchPixelsX[ 0 ];
-      Uint16Pair stretchY = mStretchPixelsY[ 0 ];
-
-      uint16_t stretchWidth = stretchX.GetY() - stretchX.GetX();
-      uint16_t stretchHeight = stretchY.GetY() - stretchY.GetX();
-
-      mImpl->mRenderer.RegisterProperty( "uFixed[0]", Vector2::ZERO );
-      mImpl->mRenderer.RegisterProperty( "uFixed[1]", Vector2( stretchX.GetX(), stretchY.GetX()) );
-      mImpl->mRenderer.RegisterProperty( "uFixed[2]", Vector2( mImageSize.GetWidth() - stretchWidth, mImageSize.GetHeight() - stretchHeight ) );
-      mImpl->mRenderer.RegisterProperty( "uStretchTotal", Vector2( stretchWidth, stretchHeight ) );
+      geometry = CreateGridGeometry( Uint16Pair( 3, 3 ) );
     }
-    else
+    else if( VisualFactoryCache::NINE_PATCH_BORDER_GEOMETRY == subType )
     {
-      mImpl->mRenderer.RegisterProperty( "uNinePatchFactorsX[0]", Vector2::ZERO );
-      mImpl->mRenderer.RegisterProperty( "uNinePatchFactorsY[0]", Vector2::ZERO );
-
-      RegisterStretchProperties( mImpl->mRenderer, "uNinePatchFactorsX", mStretchPixelsX, mImageSize.GetWidth() );
-      RegisterStretchProperties( mImpl->mRenderer, "uNinePatchFactorsY", mStretchPixelsY, mImageSize.GetHeight() );
+      geometry = CreateBorderGeometry( Uint16Pair( 3, 3 ) );
     }
+    mFactoryCache.SaveGeometry( subType, geometry );
   }
+  return geometry;
 }
 
-Geometry NPatchVisual::CreateGeometry( Uint16Pair gridSize )
+Geometry NPatchVisual::CreateGridGeometry( Uint16Pair gridSize )
 {
   uint16_t gridWidth = gridSize.GetWidth();
   uint16_t gridHeight = gridSize.GetHeight();
@@ -598,7 +515,6 @@ Geometry NPatchVisual::CreateGeometry( Uint16Pair gridSize )
   }
 
   // Create indices
-  //TODO: compare performance with triangle strip when Geometry supports it
   Vector< unsigned short > indices;
   indices.Reserve( gridWidth * gridHeight * 6 );
 
@@ -615,7 +531,7 @@ Geometry NPatchVisual::CreateGeometry( Uint16Pair gridSize )
   return GenerateGeometry( vertices, indices );
 }
 
-Geometry NPatchVisual::CreateGeometryBorder( Uint16Pair gridSize )
+Geometry NPatchVisual::CreateBorderGeometry( Uint16Pair gridSize )
 {
   uint16_t gridWidth = gridSize.GetWidth();
   uint16_t gridHeight = gridSize.GetHeight();
@@ -655,7 +571,6 @@ Geometry NPatchVisual::CreateGeometryBorder( Uint16Pair gridSize )
   }
 
   // Create indices
-  //TODO: compare performance with triangle strip when Geometry supports it
   Vector< unsigned short > indices;
   indices.Reserve( gridWidth * gridHeight * 6 );
 
index b3d2815..1059a7e 100644 (file)
@@ -80,7 +80,7 @@ public:  // from Visual
   /**
    * @copydoc Visual::Base::GetNaturalSize
    */
-  virtual void GetNaturalSize( Vector2& naturalSize ) const;
+  virtual void GetNaturalSize( Vector2& naturalSize );
 
   /**
    * @copydoc Visual::Base::CreatePropertyMap
@@ -134,11 +134,6 @@ protected:
 private:
 
   /**
-   * @brief Initialize the renderer with the geometry and shader from the cache, if not available, create and save to the cache for sharing.
-   */
-  void InitializeRenderer();
-
-  /**
    * @brief Creates a geometry for this renderer's grid size
    *
    * @return Returns the created geometry for this renderer's grid size
@@ -153,12 +148,24 @@ private:
   Shader CreateShader();
 
   /**
+   * @brief Applies texture and related uniforms
+   */
+  void ApplyTextureAndUniforms();
+
+  /**
+   * Helper method to get the default Nine patch geometry from cache or create and store it there
+   * @param subType to use
+   * @return the geometry
+   */
+  Geometry GetNinePatchGeometry( VisualFactoryCache::GeometryType subType );
+
+  /**
    * @brief Creates a geometry for the grid size to be used by this visuals' shaders
    *
    * @param[in] gridSize The grid size of the solid geometry to create
    * @return Returns the created geometry for the grid size
    */
-  Geometry CreateGeometry( Uint16Pair gridSize );
+  Geometry CreateGridGeometry( Uint16Pair gridSize );
 
   /**
    * @brief Creates a geometry with the border only for the grid size to be used by this visuals' shaders
@@ -181,45 +188,15 @@ private:
    * @param[in] gridSize The grid size of the solid geometry to create
    * @return Returns the created geometry for the grid size
    */
-  Geometry CreateGeometryBorder( Uint16Pair gridSize );
-
-  /**
-   * @brief Creates Image from the image url and parses the image for the stretch borders. Will create a error image if the n patch image is invalid
-   *
-   * @param[in] nPatchImage The NinePatchImage to base our cropped images and stretch borders from
-   */
-  void InitializeFromImage( NinePatchImage nPatchImage );
-
-  /**
-   * @brief Creates an error Image to indicate that there was an error in either the image url or the parsing of the image
-   *
-   */
-  void InitializeFromBrokenImage();
-
-  /**
-   * @brief Applies this renderer's image to the sampler to the texture set used for this renderer
-   */
-  void ApplyImageToSampler();
-
-  /**
-   * @brief Changes the current renderer if the n-patch meta data has changed
-   *
-   * @param[in] oldBorderOnly The old flag indicating if the image should omit the centre of the n-patch and only render the border
-   * @param[in] oldGridX The old horizontal grid size of the solid geometry
-   * @param[in] oldGridY The old vertical grid size of the solid geometry
-   */
-  void ChangeRenderer( bool oldBorderOnly, size_t oldGridX, size_t oldGridY );
+  Geometry CreateBorderGeometry( Uint16Pair gridSize );
 
 private:
 
-  NinePatchImage mImage; ///< The image to render if the visual was set from an NinePatchImage, empty otherwise
-  Image mCroppedImage;
+  NPatchLoader& mLoader;      ///< reference to N patch loader for fast access
+  std::string 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
 
-  std::string mImageUrl; ///< The url to the image resource to render if the visual was set from an image resource url, empty otherwise
-  NinePatchImage::StretchRanges mStretchPixelsX;
-  NinePatchImage::StretchRanges mStretchPixelsY;
-  ImageDimensions mImageSize;
-  bool mBorderOnly;
 };
 
 } // namespace Internal
index 8285561..5fbde5a 100644 (file)
@@ -394,7 +394,7 @@ void PrimitiveVisual::SetSize( const Vector2& size )
   // ToDo: renderer responds to the size change
 }
 
-void PrimitiveVisual::GetNaturalSize( Vector2& naturalSize ) const
+void PrimitiveVisual::GetNaturalSize( Vector2& naturalSize )
 {
   naturalSize.x = mObjectDimensions.x;
   naturalSize.y = mObjectDimensions.y;
index c039fe3..5239d3f 100644 (file)
@@ -119,7 +119,7 @@ public:  // from Visual
   /**
    * @copydoc Visual::Base::GetNaturalSize
    */
-  virtual void GetNaturalSize( Vector2& naturalSize ) const;
+  virtual void GetNaturalSize( Vector2& naturalSize );
 
   /**
    * @copydoc Visual::Base::CreatePropertyMap
index 652b03d..8a390d4 100644 (file)
@@ -98,6 +98,9 @@ void SvgVisual::DoSetOnStage( Actor& actor )
   mImpl->mRenderer = Renderer::New( geometry, shader );
   mImpl->mRenderer.SetTextures( textureSet );
 
+  // Register transform properties
+  mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
+
   if( mImpl->mSize != Vector2::ZERO && mParsedImage )
   {
     AddRasterizationTask( mImpl->mSize );
@@ -116,7 +119,7 @@ void SvgVisual::DoSetOffStage( Actor& actor )
   mPlacementActor.Reset();
 }
 
-void SvgVisual::GetNaturalSize( Vector2& naturalSize ) const
+void SvgVisual::GetNaturalSize( Vector2& naturalSize )
 {
   if( mParsedImage )
   {
@@ -180,7 +183,6 @@ void SvgVisual::AddRasterizationTask( const Vector2& size )
   {
     unsigned int width = static_cast<unsigned int>(size.width);
     unsigned int height = static_cast<unsigned int>( size.height );
-    BufferImage image = BufferImage::New( width, height, Pixel::RGBA8888);
 
     RasterizingTaskPtr newTask = new RasterizingTask( this, mParsedImage, width, height );
     mFactoryCache.GetSVGRasterizationThread()->AddTask( newTask );
index 7beb6d6..e5a2f8e 100644 (file)
@@ -70,7 +70,7 @@ public:  // from Visual
   /**
    * @copydoc Visual::Base::GetNaturalSize
    */
-  virtual void GetNaturalSize( Vector2& naturalSize ) const;
+  virtual void GetNaturalSize( Vector2& naturalSize );
 
   /**
    * @copydoc Visual::Base::SetSize
index c597e27..baba744 100644 (file)
@@ -162,14 +162,6 @@ TextVisualPtr TextVisual::New( VisualFactoryCache& factoryCache )
   return new TextVisual( factoryCache );
 }
 
-void TextVisual::SetTextControlInterface( Text::ControlInterface* controlInterface )
-{
-  if( mController )
-  {
-    mController->SetTextControlInterface( controlInterface );
-  }
-}
-
 void TextVisual::SetSize( const Vector2& size )
 {
   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
@@ -191,7 +183,7 @@ float TextVisual::GetHeightForWidth( float width ) const
   return mController->GetHeightForWidth( width );
 }
 
-void TextVisual::GetNaturalSize( Vector2& naturalSize ) const
+void TextVisual::GetNaturalSize( Vector2& naturalSize )
 {
   naturalSize = mController->GetNaturalSize().GetVectorXY();
 }
@@ -226,14 +218,6 @@ void TextVisual::DoCreatePropertyMap( Property::Map& map ) const
 
   map.Insert( Toolkit::TextVisual::Property::ENABLE_MARKUP, mController->IsMarkupProcessorEnabled() );
 
-  map.Insert( Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL, mController->IsAutoScrollEnabled() );
-
-  map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED, mController->GetAutoScrollSpeed() );
-
-  map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT, mController->GetAutoScrollLoopCount() );
-
-  map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_GAP, mController->GetAutoScrollWrapGap() );
-
   map.Insert( Toolkit::TextVisual::Property::LINE_SPACING, mController->GetDefaultLineSpacing() );
 
   GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT );
@@ -501,47 +485,22 @@ void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Propert
     }
     case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL:
     {
-      const bool enableAutoScroll = propertyValue.Get<bool>();
-
-      // If request to auto scroll is the same as current state then do nothing.
-      if( enableAutoScroll != mController->IsAutoScrollEnabled() )
-      {
-        // If request is disable (false) and auto scrolling is enabled then need to stop it
-        if( !enableAutoScroll )
-        {
-          StopTextAutoScrolling(); // Causes the current animation to finish playing.
-        }
-        // If request is enable (true) then start autoscroll as not already running
-        else
-        {
-          mController->GetLayoutEngine().SetTextEllipsisEnabled( false );
-          mController->SetAutoScrollEnabled( enableAutoScroll );
-          mController->RequestRelayout();
-        }
-      }
+      // nothing to do.
       break;
     }
     case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED:
     {
-      mController->SetAutoscrollSpeed( propertyValue.Get<int>() );
+      // nothing to do.
       break;
     }
     case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT:
     {
-      const int loopCount = propertyValue.Get<int>();
-      if( loopCount > 0 )
-      {
-        mController->SetAutoScrollLoopCount( loopCount );
-      }
-      else
-      {
-        StopTextAutoScrolling(); // Causes the current animation to finish playing.
-      }
+      // nothing to do.
       break;
     }
     case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP:
     {
-      mController->SetAutoScrollWrapGap( propertyValue.Get<float>() );
+      // nothing to do.
       break;
     }
     case Toolkit::TextVisual::Property::LINE_SPACING:
@@ -751,22 +710,22 @@ Dali::Property::Value TextVisual::DoGetProperty( Dali::Property::Index index )
     }
     case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL:
     {
-      value = mController->IsAutoScrollEnabled();
+      // nothing to do.
       break;
     }
     case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED:
     {
-      value = mController->GetAutoScrollSpeed();
+      // nothing to do.
       break;
     }
     case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT:
     {
-      value = mController->GetAutoScrollLoopCount();
+      // nothing to do.
       break;
     }
     case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP:
     {
-      value = mController->GetAutoScrollWrapGap();
+      // nothing to do.
       break;
     }
     case Toolkit::TextVisual::Property::LINE_SPACING:
@@ -837,46 +796,6 @@ void TextVisual::RenderText()
       self.Add( renderableActor );
     }
     mRenderableActor = renderableActor;
-
-    if( mController->IsAutoScrollEnabled() )
-    {
-      SetUpAutoScrolling();
-    }
-  }
-}
-
-void TextVisual::StopTextAutoScrolling()
-{
-  if( mTextScroller )
-  {
-    mTextScroller->StopScrolling();
-  }
-}
-
-void TextVisual::SetUpAutoScrolling()
-{
-  Actor self = mSelf.GetHandle();
-  if( !self )
-  {
-    // Nothing to do if the handle is not initialized.
-    return;
-  }
-
-  const Text::ScrollerData* const data = mController->GetAutoScrollData();
-
-  if( NULL != data )
-  {
-    if( !mTextScroller )
-    {
-      // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults
-      mTextScroller = Text::TextScroller::New( *mController );
-    }
-
-    mTextScroller->StartScrolling( mRenderableActor,
-                                   *data );
-
-    self.Add( mTextScroller->GetScrollingText() );
-    self.Add( mTextScroller->GetSourceCamera() );
   }
 }
 
index 47289d1..dd1abf6 100644 (file)
@@ -26,7 +26,6 @@
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 #include <dali-toolkit/internal/text/text-controller.h>
-#include <dali-toolkit/internal/text/text-scroller.h>
 
 namespace Dali
 {
@@ -80,12 +79,6 @@ public:
    */
   static TextVisualPtr New( VisualFactoryCache& factoryCache );
 
-  /**
-   * @brief Sets the text control interface which is needed to communicate with a control.
-   * @param[in] controlInterface Pointer to the control-interface.
-   */
-  void SetTextControlInterface( Text::ControlInterface* controlInterface );
-
 public: // from Visual::Base
 
   /**
@@ -101,7 +94,7 @@ public: // from Visual::Base
   /**
    * @copydoc Visual::Base::GetNaturalSize()
    */
-  virtual void GetNaturalSize( Vector2& naturalSize ) const;
+  virtual void GetNaturalSize( Vector2& naturalSize );
 
   /**
    * @copydoc Visual::Base::CreatePropertyMap()
@@ -157,22 +150,11 @@ private:
    */
   void RenderText();
 
-  /**
-   * @brief Stops the text auto scroll.
-   */
-  void StopTextAutoScrolling();
-
-  /**
-   * @brief Set up Autoscrolling.
-   */
-  void SetUpAutoScrolling();
-
 private:
   Text::ControllerPtr          mController;               ///< The text's controller.
   WeakHandle<Actor>            mSelf;
 
   Text::RendererPtr            mRenderer;
-  Text::TextScrollerPtr        mTextScroller;
   Actor                        mRenderableActor;
 
   int mRenderingBackend;
index 1b9cec7..9cd41e0 100644 (file)
@@ -109,7 +109,7 @@ float Visual::Base::GetHeightForWidth( float width ) const
   return 0.f;
 }
 
-void Visual::Base::GetNaturalSize( Vector2& naturalSize ) const
+void Visual::Base::GetNaturalSize( Vector2& naturalSize )
 {
   naturalSize = Vector2::ZERO;
 }
@@ -190,8 +190,8 @@ bool Visual::Base::IsPreMultipliedAlphaEnabled() const
 
 void Visual::Base::DoSetOffStage( Actor& actor )
 {
-    actor.RemoveRenderer( mImpl->mRenderer );
-    mImpl->mRenderer.Reset();
+  actor.RemoveRenderer( mImpl->mRenderer );
+  mImpl->mRenderer.Reset();
 }
 
 bool Visual::Base::IsOnStage() const
index 306f2d9..4028ca4 100644 (file)
@@ -99,7 +99,7 @@ public:
   /**
    * @copydoc Toolkit::Visual::Base::GetNaturalSize
    */
-  virtual void GetNaturalSize( Vector2& naturalSize ) const;
+  virtual void GetNaturalSize( Vector2& naturalSize );
 
   /**
    * @copydoc Toolkit::Visual::Base::SetDepthIndex
index 248270b..51c6bc2 100644 (file)
 // CLASS HEADER
 #include "visual-factory-cache.h"
 
-// EXTERNAL HEADER
+// EXTERNAL INCLUDES
 #include <dali/devel-api/common/hash.h>
 #include <dali/public-api/images/resource-image.h>
 
-// INTERNAL HEADER
+// INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/color/color-visual.h>
 #include <dali-toolkit/internal/visuals/svg/svg-visual.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
@@ -197,6 +197,11 @@ ImageAtlasManagerPtr VisualFactoryCache::GetAtlasManager()
   return mAtlasManager;
 }
 
+NPatchLoader& VisualFactoryCache::GetNPatchLoader()
+{
+  return mNPatchLoader;
+}
+
 SvgRasterizeThread* VisualFactoryCache::GetSVGRasterizationThread()
 {
   if( !mSvgRasterizeThread )
index cb1b890..0b77e53 100644 (file)
@@ -17,9 +17,6 @@
  * limitations under the License.
  */
 
-// INTERNAL INCLUDES
-#include "svg/svg-rasterize-thread.h"
-
 // EXTERNAL INCLUDES
 #include <dali/public-api/math/uint-16-pair.h>
 #include <dali/public-api/object/ref-object.h>
@@ -29,6 +26,9 @@
 #include <dali/devel-api/common/owner-container.h>
 #include <dali/devel-api/object/weak-handle.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/npatch-loader.h>
+#include <dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h>
 
 namespace Dali
 {
@@ -42,6 +42,8 @@ namespace Internal
 class ImageAtlasManager;
 typedef IntrusivePtr<ImageAtlasManager> ImageAtlasManagerPtr;
 
+class NPatchLoader;
+
 /**
  * Caches shaders and geometries. Owned by VisualFactory.
  */
@@ -182,13 +184,19 @@ public:
 
   /**
    * Get the image atlas manager.
-   * @return A pointer pointing to the atlas manager
+   * @return A pointer to the atlas manager
    */
   ImageAtlasManagerPtr GetAtlasManager();
 
   /**
+   * Get the N-Patch texture cache.
+   * @return A reference to the N patch loader
+   */
+  NPatchLoader& GetNPatchLoader();
+
+  /**
    * Get the SVG rasterization thread.
-   * @return A pointer pointing to the SVG rasterization thread.
+   * @return A raw pointer pointing to the SVG rasterization thread.
    */
   SvgRasterizeThread* GetSVGRasterizationThread();
 
@@ -248,6 +256,8 @@ private:
   Renderer mWireframeRenderer;
 
   ImageAtlasManagerPtr mAtlasManager;
+  NPatchLoader mNPatchLoader;
+
   SvgRasterizeThread*  mSvgRasterizeThread;
 };
 
index 501a854..030512e 100644 (file)
@@ -23,6 +23,7 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
 
 namespace Dali
 {
@@ -90,6 +91,54 @@ private:
   bool                    mDebugEnabled;
 };
 
+/**
+ * @brief Template to allow discard old visual, get new one and set it on stage if possible
+ *
+ * @tparam ParameterType0 The type of first argument passed to the CreateVisual()
+ * @tparam ParameterType1 The type of second argument passed to the CreateVisual()
+ * @SINCE_1_0.39
+ * @param[in] actor Actor for which the visual will be replaced
+ * @param[in,out] visual The visual to be replaced
+ * @param[in] param0 First template based argument passed to the visual factory
+ * @param[in] param1 Second template based argument passed to the visual factory
+ */
+template< class ParameterType0, class ParameterType1 >
+void InitializeVisual( Actor& actor, Toolkit::Visual::Base& visual, ParameterType0& param0, ParameterType1& param1 )
+{
+  if( actor )
+  {
+    Toolkit::GetImplementation(visual).SetOffStage( actor );
+  }
+  visual = Toolkit::VisualFactory::Get().CreateVisual( param0, param1 );
+  if( visual && actor && actor.OnStage() )
+  {
+    Toolkit::GetImplementation(visual).SetOnStage(actor);
+  }
+}
+
+/**
+ * @brief Template to allow discard old visual, get new one and set it on stage if possible
+ *
+ * @tparam ParameterType The type of argument passed to the CreateVisual()
+ * @SINCE_1_0.39
+ * @param[in] actor Actor for which the visual will be replaced
+ * @param[in,out] visual The visual to be replaced
+ * @param[in] param Template based argument passed to the visual factory
+ */
+template< class ParameterType >
+void InitializeVisual( Actor& actor, Toolkit::Visual::Base& visual, ParameterType& param )
+{
+  if( actor && visual )
+  {
+    Toolkit::GetImplementation(visual).SetOffStage( actor );
+  }
+  visual =  Toolkit::VisualFactory::Get().CreateVisual( param );
+  if( visual && actor && actor.OnStage() )
+  {
+    Toolkit::GetImplementation(visual).SetOnStage(actor);
+  }
+}
+
 } // namespace Internal
 
 inline const Internal::VisualFactory& GetImplementation(const Toolkit::VisualFactory& factory)
index 58f7d4f..ec56a2f 100644 (file)
@@ -597,8 +597,12 @@ void Control::SetBackgroundImage( Image image )
 
 void Control::ClearBackground()
 {
-  Actor self( Self() );
-  mImpl->mBackgroundVisual.RemoveAndReset( self );
+  if( mImpl->mBackgroundVisual )
+  {
+    Actor self( Self() );
+    Toolkit::GetImplementation( mImpl->mBackgroundVisual ).SetOffStage( self );
+    mImpl->mBackgroundVisual.Reset();
+  }
   mImpl->mBackgroundColor = Color::TRANSPARENT;
 }
 
@@ -759,7 +763,7 @@ void Control::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visu
       {
         if( (*iter)->visual && self.OnStage() )
         {
-          (*iter)->visual.SetOffStage( self );
+          Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
         }
         (*iter)->visual = visual;
         visualReplaced = true;
@@ -773,17 +777,17 @@ void Control::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visu
 
   if( visual && self.OnStage() && enabled )
   {
-    visual.SetOnStage( self );
+    Toolkit::GetImplementation(visual).SetOnStage( self );
   }
 }
 
 void Control::UnregisterVisual( Property::Index index )
 {
-   RegisteredVisualContainer::Iterator iter;
-   if ( FindVisual( index, mImpl->mVisuals, iter ) )
-   {
-     mImpl->mVisuals.Erase( iter );
-   }
+  RegisteredVisualContainer::Iterator iter;
+  if ( FindVisual( index, mImpl->mVisuals, iter ) )
+  {
+    mImpl->mVisuals.Erase( iter );
+  }
 }
 
 Toolkit::Visual::Base Control::GetVisual( Property::Index index ) const
@@ -814,11 +818,11 @@ void Control::EnableVisual( Property::Index index, bool enable )
       if ( enable )
       {
 
-        (*iter)->visual.SetOnStage( parentActor );
+        Toolkit::GetImplementation((*iter)->visual).SetOnStage( parentActor );
       }
       else
       {
-        (*iter)->visual.SetOffStage( parentActor );  // No need to call if control not staged.
+        Toolkit::GetImplementation((*iter)->visual).SetOffStage( parentActor );  // No need to call if control not staged.
       }
     }
   }
@@ -1091,7 +1095,7 @@ void Control::OnStageConnection( int depth )
     if( (*iter)->visual && (*iter)->enabled )
     {
       Actor self( Self() );
-      (*iter)->visual.SetOnStage( self );
+      Toolkit::GetImplementation((*iter)->visual).SetOnStage( self );
     }
   }
 }
@@ -1104,7 +1108,7 @@ void Control::OnStageDisconnection()
     if( (*iter)->visual )
     {
       Actor self( Self() );
-      (*iter)->visual.SetOffStage( self );
+      Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
     }
   }
 }
index 14e9c05..8cac8e3 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 = 13;
+const unsigned int TOOLKIT_MICRO_VERSION = 14;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 3734525..a4e4e56 100755 (executable)
@@ -26,6 +26,8 @@ public_api_src_files = \
   $(public_api_src_dir)/controls/text-controls/text-label.cpp \
   $(public_api_src_dir)/controls/text-controls/text-field.cpp \
   $(public_api_src_dir)/controls/video-view/video-view.cpp \
+  $(public_api_src_dir)/image-loader/async-image-loader.cpp \
+  $(public_api_src_dir)/image-loader/sync-image-loader.cpp \
   $(public_api_src_dir)/styling/style-manager.cpp \
   $(public_api_src_dir)/accessibility-manager/accessibility-manager.cpp \
   $(public_api_src_dir)/focus-manager/keyboard-focus-manager.cpp \
@@ -68,6 +70,10 @@ public_api_item_view_header_files = \
   $(public_api_src_dir)/controls/scrollable/item-view/item-view-declarations.h \
   $(public_api_src_dir)/controls/scrollable/item-view/item-view.h
 
+public_api_image_loader_header_files = \
+  $(public_api_src_dir)/image-loader/async-image-loader.h \
+  $(public_api_src_dir)/image-loader/sync-image-loader.h
+
 public_api_scrollable_header_files = \
   $(public_api_src_dir)/controls/scrollable/scrollable.h
 
@@ -36,7 +36,8 @@ AsyncImageLoader::~AsyncImageLoader()
 
 AsyncImageLoader::AsyncImageLoader( Internal::AsyncImageLoader* impl )
 : BaseHandle( impl )
-{}
+{
+}
 
 AsyncImageLoader::AsyncImageLoader( const AsyncImageLoader& handle )
 : BaseHandle( handle )
@@ -45,10 +46,15 @@ AsyncImageLoader::AsyncImageLoader( const AsyncImageLoader& handle )
 
 AsyncImageLoader& AsyncImageLoader::operator=( const AsyncImageLoader& handle )
 {
-  BaseHandle::operator=(handle);
+  BaseHandle::operator=( handle );
   return *this;
 }
 
+AsyncImageLoader AsyncImageLoader::DownCast( BaseHandle handle )
+{
+  return AsyncImageLoader( dynamic_cast<Dali::Toolkit::Internal::AsyncImageLoader*>( handle.GetObjectPtr() ) );
+}
+
 AsyncImageLoader AsyncImageLoader::New()
 {
   IntrusivePtr<Internal::AsyncImageLoader> internal = Internal::AsyncImageLoader::New();
@@ -57,36 +63,36 @@ AsyncImageLoader AsyncImageLoader::New()
 
 uint32_t AsyncImageLoader::Load( const std::string& url )
 {
-  return GetImplementation(*this).Load( url, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
+  return GetImplementation( *this ).Load( url, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
 }
 
-uint32_t AsyncImageLoader::Load( const std::string& url, ImageDimensions size )
+uint32_t AsyncImageLoader::Load( const std::string& url, ImageDimensions dimensions )
 {
-  return GetImplementation(*this).Load( url, size, FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
+  return GetImplementation( *this ).Load( url, dimensions, FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
 }
 
 uint32_t AsyncImageLoader::Load( const std::string& url,
-                                 ImageDimensions size,
+                                 ImageDimensions dimensions,
                                  FittingMode::Type fittingMode,
                                  SamplingMode::Type samplingMode,
                                  bool orientationCorrection )
 {
-  return GetImplementation(*this).Load( url, size, fittingMode, samplingMode, orientationCorrection );
+  return GetImplementation(*this).Load( url, dimensions, fittingMode, samplingMode, orientationCorrection );
 }
 
-bool AsyncImageLoader::Cancel( uint32_t loadingTaskId)
+bool AsyncImageLoader::Cancel( uint32_t loadingTaskId )
 {
   return GetImplementation(*this).Cancel( loadingTaskId );
 }
 
 void AsyncImageLoader::CancelAll()
 {
-  GetImplementation(*this).CancelAll();
+  GetImplementation( *this ).CancelAll();
 }
 
 AsyncImageLoader::ImageLoadedSignalType& AsyncImageLoader::ImageLoadedSignal()
 {
-  return GetImplementation(*this).ImageLoadedSignal();
+  return GetImplementation( *this ).ImageLoadedSignal();
 }
 } // namespace Toolkit
 
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H__
-#define __DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H__
+#ifndef DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H
+#define DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
@@ -36,27 +36,38 @@ class AsyncImageLoader;
 }
 
 /**
- *@brief The AysncImageLoader is used to load pixel data from the URL asynchronously.
+ * @brief The AsyncImageLoader is used to load pixel data from a URL asynchronously.
  *
  * The images are loaded in a worker thread to avoid blocking the main event thread.
  *
- * Each load call is assigned with an ID, connect to the ImageLoadedSignal and receive the corresponding pixel data by comparing the ID.
+ * To keep track of the loading images, each load call is assigned an ID (which is returned by the Load() call).
+ * To know when the Load has completed, connect to the ImageLoadedSignal.
+ * This signal should be connected before Load is called (in case the signal is emitted immediately).
+ *
+ * Load errors can be detected by checking the PixelData object is valid from within the signal handler.
+
+ * Note: The PixelData object will automatically be destroyed when it leaves its scope.
+ *
+ * Example:
  *
- * To make sure the signal is always received, the signal should get connected before invoking the load call.
  * @code
  * class MyClass : public ConnectionTracker
  * {
- * public:
+ *   public:
  *
- *   MyCallback( uint32_t id, PixelData pixelData)
+ *   MyCallback( uint32_t loadedTaskId, PixelData pixelData )
  *   {
- *     if(id == mId1)
+ *     // First check if the image loaded correctly.
+ *     if( pixelData )
  *     {
- *       // use the loaded pixel data from the first image
- *     }
- *     else if( id == mId2 )
- *     {
- *       // use the loaded pixel data from the second image
+ *       if( loadedTaskId == mId1 )
+ *       {
+ *         // use the loaded pixel data from the first image
+ *       }
+ *       else if( loadedTaskId == mId2 )
+ *       {
+ *         // use the loaded pixel data from the second image
+ *       }
  *     }
  *   }
  *
@@ -66,11 +77,13 @@ class AsyncImageLoader;
  *
  * MyClass myObject;
  * AsyncImageLoader imageLoader = AsyncImageLoader::New();
- * // connect the signal here
+ *
+ * // Connect the signal here.
  * imageLoader.ImageLoadedSignal().Connect( &myObject, &MyClass::MyCallback );
- * // then invoke the load calls
- * testCallback.mId1 = imageLoader.Load( "first_image_url.jpg" );
- * testCallback.mId2 = imageLoader.Load( "second_image_url.jpg" );
+ *
+ * // Invoke the load calls (must do this after connecting the signal to guarantee callbacks occur).
+ * myObject.mId1 = imageLoader.Load( "first_image_url.jpg" );
+ * myObject.mId2 = imageLoader.Load( "second_image_url.jpg" );
  *
  * @endcode
  */
@@ -78,17 +91,13 @@ class DALI_IMPORT_API AsyncImageLoader : public BaseHandle
 {
 public:
 
-  /**
-   * @brief Type of signal for image loading finished.
-   *
-   * The signal is emit with the load ID and its corresponding loaded pixel data
-   */
-  typedef Signal< void( uint32_t, PixelData ) > ImageLoadedSignalType;
+  typedef Signal< void( uint32_t, PixelData ) > ImageLoadedSignalType; ///< Image loaded signal type @SINCE_1_2_14
 
 public:
 
   /**
    * @brief Constructor which creates an empty AsyncImageLoader handle.
+   * @SINCE_1_2_14
    *
    * Use AsyncImageLoader::New() to create an initialised object.
    */
@@ -96,6 +105,7 @@ public:
 
   /**
    * @brief Destructor
+   * @SINCE_1_2_14
    *
    * This is non-virtual since derived Handle types must not contain data or virtual methods.
    */
@@ -103,68 +113,99 @@ public:
 
   /**
    * @brief This copy constructor is required for (smart) pointer semantics.
+   * @SINCE_1_2_14
    *
-   * @param [in] handle A reference to the copied handle
+   * @param[in] handle A reference to the copied handle
    */
   AsyncImageLoader( const AsyncImageLoader& handle );
 
   /**
    * @brief This assignment operator is required for (smart) pointer semantics.
+   * @SINCE_1_2_14
    *
-   * @param [in] handle  A reference to the copied handle
+   * @param[in] handle  A reference to the copied handle
    * @return A reference to this
    */
   AsyncImageLoader& operator=( const AsyncImageLoader& handle );
 
- /*
-  * @brief Create a new loader to load the image asynchronously in a worker thread.
-  *
-  * @return The image loader.
-  */
+  /**
+   * @brief Create a new loader to load the image asynchronously in a worker thread.
+   * @SINCE_1_2_14
+   *
+   * @return The image loader.
+   */
   static AsyncImageLoader New();
 
   /**
-   * @brief Start a image loading task.
+   * @brief Downcast a handle to AsyncImageLoader handle.
+   *
+   * If the handle points to an AsyncImageLoader object the downcast produces
+   * a valid handle. If not, the returned handle is left uninitialized.
+   *
+   * @SINCE_1_2_14
+   * @param[in] handle A handle to an object
+   * @return A handle to a AsyncImageLoader object or an uninitialized handle
+   */
+  static AsyncImageLoader DownCast( BaseHandle handle );
+
+  /**
+   * @brief Start an image loading task.
+   * Note: When using this method, the following defaults will be used:
+   * fittingMode = FittingMode::DEFAULT
+   * samplingMode = SamplingMode::BOX_THEN_LINEAR
+   * orientationCorrection = true
+   *
+   * @SINCE_1_2_14
    *
    * @param[in] url The URL of the image file to load.
    * @return The loading task id.
    */
   uint32_t Load( const std::string& url );
-  /*
-   * @brief Start a image loading task.
+
+  /**
+   * @brief Start an image loading task.
+   * Note: When using this method, the following defaults will be used:
+   * fittingMode = FittingMode::DEFAULT
+   * samplingMode = SamplingMode::BOX_THEN_LINEAR
+   * orientationCorrection = true
+   *
+   * @SINCE_1_2_14
    *
    * @param[in] url The URL of the image file to load.
-   * @param[in] size The width and height to fit the loaded image to.
+   * @param[in] dimensions The width and height to fit the loaded image to.
    * @return The loading task id.
    */
-  uint32_t Load( const std::string& url, ImageDimensions size );
+  uint32_t Load( const std::string& url, ImageDimensions dimensions );
 
-  /*
-   * @brief Start a image loading task.
+  /**
+   * @brief Start an image loading task.
+   * @SINCE_1_2_14
    *
    * @param[in] url The URL of the image file to load.
-   * @param[in] size The width and height to fit the loaded image to.
+   * @param[in] dimensions The width and height to fit the loaded image to.
    * @param[in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
    * @param[in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
    * @param[in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
    * @return The loading task id.
    */
   uint32_t Load( const std::string& url,
-                 ImageDimensions size,
+                 ImageDimensions dimensions,
                  FittingMode::Type fittingMode,
                  SamplingMode::Type samplingMode,
                  bool orientationCorrection );
 
   /**
-   * @brief Cancel a image loading task if it is still queuing in the work thread.
+   * @brief Cancel a image loading task if it is still queueing in the work thread.
+   * @SINCE_1_2_14
    *
    * @param[in] loadingTaskId The task id returned when invoking the load call.
    * @return If true, the loading task is removed from the queue, otherwise the loading is already implemented and unable to cancel anymore
    */
-  bool Cancel( uint32_t loadingTaskId);
+  bool Cancel( uint32_t loadingTaskId );
 
   /**
    * @brief Cancel all the loading tasks in the queue
+   * @SINCE_1_2_14
    */
   void CancelAll();
 
@@ -175,14 +216,25 @@ public:
    * @code
    *   void YourCallbackName( uint32_t id, PixelData pixelData );
    * @endcode
+   * @SINCE_1_2_14
    *
-   * @return A signal object to Connect() with.
+   * @return A reference to a signal object to Connect() with.
    */
   ImageLoadedSignalType& ImageLoadedSignal();
 
 public: // Not intended for developer use
 
+  /// @cond internal
+  /**
+   * @brief Allows the creation of a AsyncImageLoader handle from an internal pointer.
+   *
+   * @note Not intended for application developers
+   * @SINCE_1_2_14
+   *
+   * @param[in] impl A pointer to the object.
+   */
   explicit DALI_INTERNAL AsyncImageLoader( Internal::AsyncImageLoader* impl );
+  /// @endcond
 
 };
 
@@ -190,4 +242,4 @@ public: // Not intended for developer use
 
 } // namespace Dali
 
-#endif /* __DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H__ */
+#endif // DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H
diff --git a/dali-toolkit/public-api/image-loader/sync-image-loader.cpp b/dali-toolkit/public-api/image-loader/sync-image-loader.cpp
new file mode 100644 (file)
index 0000000..de489dc
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+// CLASS HEADER
+#include "sync-image-loader.h"
+#include <dali/devel-api/adaptor-framework/bitmap-loader.h>
+
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace SyncImageLoader
+{
+
+
+PixelData Load( const std::string& url )
+{
+  return Load( url, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
+}
+
+PixelData Load( const std::string& url, ImageDimensions dimensions )
+{
+  return Load( url, dimensions, FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
+}
+
+PixelData Load( const std::string& url,
+                ImageDimensions dimensions,
+                FittingMode::Type fittingMode,
+                SamplingMode::Type samplingMode,
+                bool orientationCorrection )
+{
+  BitmapLoader loader = BitmapLoader::New( url, dimensions, fittingMode, samplingMode, orientationCorrection );
+
+  // Load the image synchronously (block the thread here).
+  loader.Load();
+
+  return loader.GetPixelData();
+}
+
+
+} // namespace SyncImageLoader
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/public-api/image-loader/sync-image-loader.h b/dali-toolkit/public-api/image-loader/sync-image-loader.h
new file mode 100644 (file)
index 0000000..3450ba9
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef DALI_TOOLKIT_SYNC_IMAGE_LOADER_H
+#define DALI_TOOLKIT_SYNC_IMAGE_LOADER_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.
+ */
+
+// EXTERNAL INCLUDES
+#include <string>
+#include <dali/public-api/images/image-operations.h>
+#include <dali/public-api/images/pixel-data.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace SyncImageLoader
+{
+
+/**
+ * @brief The methods in the SyncImageLoader namespace are used to load pixel data from a URL synchronously.
+ *
+ * Example:
+ *
+ * @code
+ * PixelData pixelData = Toolkit::SyncImageLoader::Load( "image_url.jpg" );
+ *
+ * // Check the image was loaded without error.
+ * if( pixelData )
+ * {
+ *   // Do work...
+ * }
+ *
+ * @endcode
+ */
+
+/**
+ * @brief Load an image synchronously.
+ * Note: When using this method, the following defaults will be used:
+ * fittingMode = FittingMode::DEFAULT
+ * samplingMode = SamplingMode::BOX_THEN_LINEAR
+ * orientationCorrection = true
+ *
+ * @SINCE_1_2_14
+ *
+ * @param[in] url The URL of the image file to load.
+ * @return A PixelData object containing the image, or an invalid object on failure.
+ */
+PixelData Load( const std::string& url );
+
+/**
+ * @brief Load an image synchronously by specifying the target dimensions.
+ * Note: When using this method, the following defaults will be used:
+ * fittingMode = FittingMode::DEFAULT
+ * samplingMode = SamplingMode::BOX_THEN_LINEAR
+ * orientationCorrection = true
+ *
+ * @SINCE_1_2_14
+ *
+ * @param[in] url The URL of the image file to load.
+ * @param[in] dimensions The width and height to fit the loaded image to.
+ * @return A PixelData object containing the image, or an invalid object on failure.
+ */
+PixelData Load( const std::string& url, ImageDimensions dimensions );
+
+/**
+ * @brief Load an image synchronously by specifying the target dimensions and options.
+ * @SINCE_1_2_14
+ *
+ * @param[in] url The URL of the image file to load.
+ * @param[in] dimensions The width and height to fit the loaded image to.
+ * @param[in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
+ * @param[in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
+ * @param[in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
+ * @return A PixelData object containing the image, or an invalid object on failure.
+ */
+PixelData Load( const std::string& url,
+                ImageDimensions dimensions,
+                FittingMode::Type fittingMode,
+                SamplingMode::Type samplingMode,
+                bool orientationCorrection );
+
+} // namespace SyncImageLoader
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_SYNC_IMAGE_LOADER_H
index 4349789..14cfeb2 100644 (file)
Binary files a/docs/content/images/creating-custom-controls/control-handle-body.png and b/docs/content/images/creating-custom-controls/control-handle-body.png differ
index 27239b3..82345bb 100644 (file)
@@ -13,13 +13,26 @@ Custom controls are created using the [handle/body idiom](@ref handle-body-idiom
 ![ ](../assets/img/creating-custom-controls/control-handle-body.png)
 ![ ](creating-custom-controls/control-handle-body.png)
  
+Namespaces are important
++ The handle & body classes should have the same name but in different namespaces
++ TypeRegistry relies on this convention
++ Here our custom control requires
+  + MyControl
+  + Internal::MyControl
 ### General Guidelines:
 + Try to avoid adding C++ APIs as they become difficult to maintain.
   + Use **properties** as much as possible as Controls should be data driven.
   + These controls will be used through JavaScript and JSON files so need to be compatible.
-+ Bear in mind that the Control is required to update when the properties change, not just the first time they are set (to deal with style change).
++ Bear in mind that the Control can be updated when the properties change (e.g. style change)
+  + Ensure control deals with these property changes gracefully
+  + Not just the first time they are set
++ Use Visuals rather than creating several child Actors
+  + DALi rendering pipeline more efficient
 + Accessibility actions should be considered when designing the Control.
 + Consider using signals if the application needs to be react to changes in the control state.
++ Use of Gestures should be preferred over analysing raw touch events
++ Check if you need to chain up to base class if overriding certain methods
  
 ___________________________________________________________________________________________________
 
@@ -125,7 +138,8 @@ This should be overridden by the custom ui control.
 // C++
 void MyUIControlImpl::OnInitialize()
 {
-  // Create visuals, register events etc.
+  // Create visuals using the VisualFactory, register events etc.
+  // Register any created visuals with Control base class
 }
 ~~~
 ___________________________________________________________________________________________________
@@ -134,13 +148,14 @@ ________________________________________________________________________________
 
 Dali::Toolkit::Internal::Control provides several behaviours which are specified through its constructor (@ref Dali::Toolkit::Internal::Control::Control()).
  
-| Behaviour                            | Description                                                             |
-|--------------------------------------|-------------------------------------------------------------------------|
-| ACTOR_BEHAVIOUR_NONE                 | No behaviour required.                                                  |
-| REQUIRES_HOVER_EVENTS                | If our control requires [hover events](@ref creating-controls-events).  |
-| REQUIRES_WHEEL_EVENTS                | If our control requires [wheel events](@ref creating-controls-events).  |
-| REQUIRES_STYLE_CHANGE_SIGNALS        | True if need to monitor style change signals such as Theme/Font change. |
-| REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | True if need to support keyboard navigation.                            |
+| Behaviour                            | Description                                                                                                    |
+|--------------------------------------|----------------------------------------------------------------------------------------------------------------|
+| CONTROL_BEHAVIOUR_DEFAULT              | Default behavior (size negotiation is on, style change is monitored, event callbacks are not called.                                      |
+| DISABLE_SIZE_NEGOTIATION             | If our control does not need size negotiation, i.e. control will be skipped by the size negotiation algorithm. |
+| REQUIRES_HOVER_EVENTS                | If our control requires [hover events](@ref creating-controls-events).                                         |
+| REQUIRES_WHEEL_EVENTS                | If our control requires [wheel events](@ref creating-controls-events).                                         |
+| DISABLE_STYLE_CHANGE_SIGNALS         | True if control should not monitor style change signals such as Theme/Font change.                                         |
+| REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | True if need to support keyboard navigation.                                                                   |
 ___________________________________________________________________________________________________
 
 ### Touch, Hover & Wheel Events {#creating-controls-events}
@@ -373,31 +388,62 @@ void MyUIControlImpl::OnStageDisconnection()
  
 ___________________________________________________________________________________________________
 
-### Size {#creating-controls-size}
+### Size Negotiation {#creating-controls-size-negotiation}
 
-Methods are provided that can be overridden if notification is required when our control's size is manipulated.
-An up call to the Control class is necessary if these methods are overridden.
+The following methods must be overridden for size negotiation to work correctly with a custom control.
  
 ~~~{.cpp}
 // C++
-void MyUIControlImpl::OnSizeSet( const Vector3& targetSize )
+Vector3 MyUIControlImpl::GetNaturalSize()
+{
+  // Return the natural size of the control
+  // This depends on our layout
+  // If we have one visual, then we can return the natural size of that
+  // If we have more visuals, then we need to calculate their positions within our control and work out the overall size we would like our control to be
+
+  // After working out the natural size of visuals that belong to this control,
+  // should also chain up to ensure other visuals belonging to the base class are
+  // also taken into account:
+  Vector2 baseSize = Control::GetNaturalSize(); // returns the size of the background.
+}
+~~~
+~~~{.cpp}
+// C++
+float MyUIControlImpl::GetHeightForWidth( float width )
 {
-  // Up call to Control
-  Control::OnSizeSet( targetSize );
+  // Called by the size negotiation algorithm if we have a fixed width
+  // We should calculate the height we would like our control to be for that width
+
+  // Should also chain up to determine the base class's preferred height:
+  float baseHeight = Control::GetHeightForWidth( width );
 
-  // Do any other operations required upon size set
 }
 ~~~
 ~~~{.cpp}
 // C++
-void MyUIControlImpl::OnSizeAnimation( Animation& animation, const Vector3& targetSize )
+float MyUIControlImpl::GetWidthForHeight( float height )
 {
-  // Up call to Control
-  Control::OnSizeAnimation( animation, targetSize );
+  // Called by the size negotiation algorithm if we have a fixed height
+  // We should calculate the width we would like our control to be for that height
 
-  // Do any other operations required upon size animation
+  // Should also chain up to determine the base class's preferred width:
+  float baseWidth = Control::GetWidth( height );
+}
+~~~
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnRelayout( const Vector2& size, RelayoutContainer& container )
+{
+  // The size is what we have been given and what our control needs to fit into
+  // Here, we need to set the position and the size of our visuals
+  // If we have other controls/actors as children
+  //  - Add the control/actor to the container paired with the size required
+  //  - To ensure this works, you need to set up the control with a relayout policy of USE_ASSIGNED_SIZE
+  //  - DO NOT CALL SetSize on this control: This will trigger another size negotiation calculation
+  // DO NOT chain up to base class.
 }
 ~~~
+More information on size negotiation can be found [here](@ref size-negotiation-controls).
  
 ___________________________________________________________________________________________________
 
index 3ae2c31..457d8e1 100644 (file)
@@ -6,7 +6,7 @@
 Visuals provide reusable rendering logic which can be used by all controls.
 This means that custom controls do not have to create actors, they can just reuse the existing visuals which increases performance.
  
-Visuals reuse geometry, shaders etc. across controls and manages the renderer and material to exist only when the control is on-stage.
+Visuals reuse geometry, shaders etc. across controls and manages the renderer and texture to exist only when the control is on-stage.
 Additionally, they respond to actor size and color change, while also providing clipping at the renderer level.
  
 DALi provides the following visuals:
@@ -22,11 +22,71 @@ Controls can provide properties that allow users to specify the visual type ( vi
 Setting visual properties are done via a property map.
 The **visualType** field in the property map specifies the visual to use/create.
 This is required to avoid ambiguity as multiple visuals may be capable of rendering the same contents.
+
+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)|
+
+## 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.
+
+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).
+
+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.
+
+
+## Alignment  {#align-type}
+| Enumeration                                          | String  | Description                                                                                          |
+|------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------|
+| Dali::Toolkit::Align::TOP_BEGIN | TOP_BEGIN | Aligns to the top of the vertical axis and the beginning of the horizontal axis (The left or right edge in Left-To-Right or Right-to-Left layouts, respectively) |
+| Dali::Toolkit::Align::TOP_CENTER | TOP_CENTER | Aligns to the top of the vertical axis and the center of the horizontal axis |
+| Dali::Toolkit::Align::TOP_END | TOP_END | Aligns to the top of the vertical axis and end of the horizontal axis (The right or left edge in Left-To-Right or Right-to-Left layouts, respectively) |
+| Dali::Toolkit::Align::CENTER_BEGIN | CENTER_BEGIN | Aligns to the center of the vertical axis and the beginning of the horizontal axis|
+| Dali::Toolkit::Align::CENTER | CENTER | Aligns to the center of the control |
+| Dali::Toolkit::Align::CENTER_END | CENTER_END | Aligns to the center of the vertical axis and end of the horizontal axis |
+| Dali::Toolkit::Align::BOTTOM_BEGIN | BOTTOM_BEGIN | Aligns to the bottom of the vertical axis and the beginning of the horizontal axis|
+| Dali::Toolkit::Align::BOTTOM_CENTER | BOTTOM_CENTER | Aligns to the bottom of the vertical axis and the center of the horizontal axis
+| Dali::Toolkit::Align::BOTTOM_END | BOTTOM_END | Aligns to the bottom of the vertical axis and end of the horizontal axis |
+Visuals also have a custom **shader** property. Whilst it's possible to change the shader, please note that some visuals rely on the vertex shader to perform certain functions. For example, the NPatch visual uses the vertex shader to perform the stretching. The **shader** property is a Property::Map with the following keys:
+
+
+| Property                                        | String   | Type    | Required | Description               |
+|-------------------------------------------------|----------|:-------:|:--------:|---------------------------|
+| Dali::Toolkit::Visual::Shader::Property::VERTEX_SHADER | vertexShader | STRING | No      | The vertex shader code. |
+| Dali::Toolkit::Visual::Shader::Property::FRAGMENT_SHADER | fragmentShader | STRING | No      | The fragment shader code. |
+| Dali::Toolkit::Visual::Shader::Property::SUBDIVIDE_GRID_X | subdivideGridX | INTEGER | No      | How to subdivide the grid along the X-Axis. Defaults to 1 |
+| Dali::Toolkit::Visual::Shader::Property::SUBDIVIDE_GRID_Y | subdivideGridY | INTEGER | No      | How to subdivide the grid along the Y-Axis. Defaults to 1 |
+| Dali::Toolkit::Visual::Shader::Property::HINTS | hints | INTEGER or ARRAY of STRING | No      | Shader hints bitmask [More info](@ref shader-hints) |
+
+## Shader hints {#shader-hints}
+
+This is a bitmask giving hints to the renderer about what the shader does, in order to help the rendering system optimise it's rendering.
+
+The bitmask can have the following values:
+
+| Value | Description |
+|-------------------------------------------|----------------------------------------|
+| Dali::Shader::Hint::NONE | No hints |
+| Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT | Might generate transparent alpha from opaque inputs |
+| Dali::Shader::Hint::MODIFIES_GEOMETRY | Might change the position of vertices - this disables culling optimizations |
+
+
+See also Dali::Shader::Hint::Value enumeration.
+
 ___________________________________________________________________________________________________
 
 ## Color Visual {#color-visual}
 
-Renders a solid color to the control's quad.
+Renders a color to the visual's quad geometry.
  
 ![ ](../assets/img/visuals/color-visual.png)
 ![ ](visuals/color-visual.png)
@@ -37,7 +97,7 @@ Renders a solid color to the control's quad.
 
 | Property                                        | String   | Type    | Required | Description               |
 |-------------------------------------------------|----------|:-------:|:--------:|---------------------------|
-| Dali::Toolkit::ColorVisual::Property::MIX_COLOR | mixColor | VECTOR4 | Yes      | The solid color required. |
+| Dali::Toolkit::ColorVisual::Property::MIX_COLOR | mixColor | VECTOR4 | Yes      | The color required. |
 
 ### Usage
 
@@ -66,7 +126,7 @@ ________________________________________________________________________________
 
 ## Gradient Visual {#gradient-visual}
 
-Renders a smooth transition of colors to the control's quad.
+Renders a smooth transition of colors to the visual's quad geometry.
  
 Both Linear and Radial gradients are supported.
 
@@ -108,9 +168,9 @@ Indicates what happens if the gradient starts or ends inside the bounds of the t
 
 | Enumeration                                          | String  | Description                                                                                          |
 |------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------|
-| Dali::Toolkit::GradientVisual::SpreadMethod::PAD     | PAD     | *Default*. Uses the terminal colors of the gradient to fill the remainder of the quad.               |
-| Dali::Toolkit::GradientVisual::SpreadMethod::REFLECT | REFLECT | Reflect the gradient pattern start-to-end, end-to-start, start-to-end etc. until the quad is filled. |
-| Dali::Toolkit::GradientVisual::SpreadMethod::REPEAT  | REPEAT  | Repeat the gradient pattern start-to-end, start-to-end, start-to-end etc. until the quad is filled.  |
+| Dali::Toolkit::GradientVisual::SpreadMethod::PAD     | PAD     | *Default*. Uses the terminal colors of the gradient to fill the remainder of the quad geometry.               |
+| Dali::Toolkit::GradientVisual::SpreadMethod::REFLECT | REFLECT | Reflect the gradient pattern start-to-end, end-to-start, start-to-end etc. until the quad geometry is filled. |
+| Dali::Toolkit::GradientVisual::SpreadMethod::REPEAT  | REPEAT  | Repeat the gradient pattern start-to-end, start-to-end, start-to-end etc. until the quad geometry is filled.  |
 
 ### Usage
 
@@ -215,7 +275,7 @@ ________________________________________________________________________________
 
 ## Image Visual {#image-visuals}
 
-Renders an image into the control's quad.
+Renders an image into the visual's geometry.
  
 Depending on the extension of the image, a different visual is provided to render the image onto the screen.
  
@@ -227,7 +287,7 @@ ___________________________
  
 ### Normal {#image-visual}
  
-Renders a raster image ( jpg, png etc.) into the control's quad.
+Renders a raster image ( jpg, png etc.) into the visual's quad geometry.
  
 ![ ](../assets/img/visuals/image-visual.png)
 ![ ](visuals/image-visual.png)
@@ -271,7 +331,7 @@ ________________________________________________________________________________
 
 ### N-Patch {#n-patch-visual}
 
-Renders an n-patch or a 9-patch image into the control's quad.
+Renders an n-patch or a 9-patch image. Uses non-quad geometry. Both geometry and texture are cached to reduce memory consumption if the same n-patch image is used elsewhere.
  
 ![ ](../assets/img/visuals/n-patch-visual.png)
 ![ ](visuals/n-patch-visual.png)
@@ -314,7 +374,7 @@ ________________________________________________________________________________
 
 ### SVG {#svg-visual}
 
-Renders a svg image into the control's quad.
+Renders a svg image into the visual's quad geometry.
  
 #### Features: SVG Tiny 1.2 specification
 
@@ -384,7 +444,7 @@ ________________________________________________________________________________
 
 ## Border Visual {#border-visual}
 
-Renders a solid color as an internal border to the control's quad.
+Renders a color as an internal border to the visual's geometry.
  
 ![ ](../assets/img/visuals/border-visual.png)
 ![ ](visuals/border-visual.png)
@@ -611,7 +671,7 @@ ________________________________________________________________________________
 
 ## Wireframe Visual {#wireframe-visual}
 
-Renders a wireframe around a control's quad.
+Renders a wireframe around a quad geometry.
 Is mainly used for debugging and is the visual that replaces all other visuals when [Visual Debug Rendering](@ref debugrendering) is turned on.
  
 ![ ](../assets/img/visuals/wireframe-visual.png)
index 8086e79..ef9b273 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-addon
 Summary:    DALi module for Node.JS
-Version:    1.2.13
+Version:    1.2.14
 Release:    1
 Group:      Development/Libraries
 License:    Apache License, Version 2.0
index 3f5d3bd..b8fb3ce 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       NDalic
 Summary:    dali wrapper
-Version:    1.2.13
+Version:    1.2.14
 Release:    1
 Group:      uifw/graphic
 License:    TO_BE_FILLED_IN
index 44e2296..1ccf8e0 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.2.13
+Version:    1.2.14
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-2-Clause and MIT