#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;
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;
-}
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)
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;
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 );
VideoPlayer();
- virtual ~VideoPlayer();
+ ~VideoPlayer();
static VideoPlayer New();
} // namespace Dali;
#endif
-
#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;
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;
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;
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;
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;
-}
-
-
#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;
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;
}
}
// 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 );
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;
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;
}
/*
- * 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.
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;
--- /dev/null
+/*
+ * 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;
+}
+
+
#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;
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;
}
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;
val = view.GetProperty( VideoView::Property::MUTED );
DALI_TEST_CHECK( val.Get( muted ) );
DALI_TEST_CHECK( muted );
+
END_TEST;
}
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 );
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;
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 );
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;
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 );
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);
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;
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;
}
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 );
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;
}
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);
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);
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);
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);
}
//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) );
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;
+}
#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;
}
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
}
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();
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 );
}
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);
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);
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;
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 );
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;
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 );
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;
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 );
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;
}
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 );
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;
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.
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;
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.
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;
}
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();
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;
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();
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;
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::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::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 );
}
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 );
}
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;
}
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 );
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 );
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 );
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 );
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 );
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();
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();
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 );
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 );
}
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 );
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 );
}
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 );
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 );
}
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;
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;
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
# public api source
publicapidir = $(topleveldir)/public-api
publicapicontrolsdir = $(publicapidir)/controls
+publicapiimageloaderdir = $(publicapidir)/image-loader
publicapiaccessibilitymanagerdir = $(publicapidir)/accessibility-manager
publicapialignmentdir = $(publicapicontrolsdir)/alignment
publicapibuttonsdir = $(publicapicontrolsdir)/buttons
# 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)
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"
#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.
#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>
$(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 \
$(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
return GetImplementation( *this ).GetHeightForWidth( width );
}
-void Visual::Base::GetNaturalSize(Vector2& naturalSize ) const
+void Visual::Base::GetNaturalSize(Vector2& naturalSize )
{
GetImplementation( *this ).GetNaturalSize( naturalSize );
}
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 );
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
{
*
* @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.
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.
};
-
-/**
- * @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
#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>
#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
{
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(
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;
// 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;
}
Control::OnStageConnection( depth );
Enable();
-
- Actor self = Self();
- if( mVisualPostFilter )
- {
- mVisualPostFilter.SetOnStage( self );
- }
- if( mVisualForChildren )
- {
- mVisualForChildren.SetOnStage( self );
- }
}
void EffectsView::OnStageDisconnection()
mFilters[i]->Disable();
}
- Actor self = Self();
- if( mVisualPostFilter )
- {
- mVisualPostFilter.SetOffStage( self );
- }
- if( mVisualForChildren )
- {
- mVisualForChildren.SetOffStage( self );
- }
-
Control::OnStageDisconnection();
}
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 );
} // namespace Dali
#endif // __DALI_TOOLKIT_INTERNAL_EFFECTS_VIEW_H__
-
// 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
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 ) );
#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>
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 );
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 );
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;
}
}
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;
}
// INTERNAL_INCLUDES
#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
namespace //Unnamed namespace
{
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++)
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 )
}
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) );
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();
}
// 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;
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()
{
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()
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;
+ }
+ }
}
}
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] );
}
}
{
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 )
// 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:
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()
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 )
{
}
#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
{
/**
* @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:
*/
virtual void RequestTextRelayout();
+private: // from TextScroller
+
+ /**
+ * @copydoc Text::ScrollerInterface::ScrollingFinished()
+ */
+ virtual void ScrollingFinished();
+
private: // Implementation
/**
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
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/video-view/video-view.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
namespace Dali
{
mPropertyMap = map;
Actor self( Self() );
- InitializeVisual( self, mVisual, mPropertyMap );
+ Internal::InitializeVisual( self, mVisual, mPropertyMap );
Property::Value* widthValue = mPropertyMap.Find( "width" );
if( widthValue )
if( mVisual )
{
CustomActor self = Self();
- mVisual.SetOnStage( self );
+ Toolkit::GetImplementation(mVisual).SetOnStage( self );
}
}
if( mVisual )
{
CustomActor self = Self();
- mVisual.SetOffStage( self );
+ Toolkit::GetImplementation(mVisual).SetOffStage( self );
}
Control::OnStageDisconnection();
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 );
mVideoPlayer.SetUrl( mUrl );
mVideoPlayer.FinishedSignal().Connect( this, &VideoView::EmitSignalFinish );
- InitializeVisual( self, mVisual, mNativeImage );
+ Internal::InitializeVisual( self, mVisual, mNativeImage );
if( mIsPlay )
{
$(toolkit_src_dir)/visuals/visual-base-impl.cpp \
$(toolkit_src_dir)/visuals/visual-base-data-impl.cpp \
$(toolkit_src_dir)/visuals/image-atlas-manager.cpp \
+ $(toolkit_src_dir)/visuals/npatch-loader.cpp \
$(toolkit_src_dir)/visuals/visual-factory-cache.cpp \
$(toolkit_src_dir)/visuals/visual-factory-impl.cpp \
$(toolkit_src_dir)/visuals/visual-string-constants.cpp \
$(toolkit_src_dir)/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 \
#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
{
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 );
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 );
taskList.RemoveTask(mRenderTaskForEmboss2);
}
+ if( mRenderTaskForOutput )
+ {
+ taskList.RemoveTask( mRenderTaskForOutput );
+ }
+
mRootActor.Reset();
}
}
AsyncImageLoader::AsyncImageLoader()
: mLoadedSignal(),
mLoadThread( new EventThreadCallback( MakeCallback( this, &AsyncImageLoader::ProcessLoadedImage ) ) ),
- mLoadTaskId( 0 ),
+ mLoadTaskId( 0u ),
mIsLoadThreadStarted( false )
{
}
}
uint32_t AsyncImageLoader::Load( const std::string& url,
- ImageDimensions size,
+ ImageDimensions dimensions,
FittingMode::Type fittingMode,
SamplingMode::Type samplingMode,
bool orientationCorrection )
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 ) );
-#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.
#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
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 );
} // 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 );
}
} // namespace Dali
-#endif /* DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H__ */
+#endif // DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H
// 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
{
void ImageLoadThread::Run()
{
- while( LoadingTask* task = NextTaskToProcess())
+ while( LoadingTask* task = NextTaskToProcess() )
{
task->loader.Load();
AddCompletedTask( task );
mLoadQueue.PushBack( task );
}
- if( wasEmpty)
+ if( wasEmpty )
{
// wake up the image loading thread
mConditionalWait.Notify();
// 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 )
{
// 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();
}
#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>
mEmbossDefaults( NULL ),
mOutlineDefaults( NULL ),
mEventData( NULL ),
- mAutoScrollData( NULL ),
mFontClient(),
mClipboard(),
mView(),
mRecalculateNaturalSize( true ),
mMarkupProcessorEnabled( false ),
mClipboardHideEnabled( true ),
- mIsAutoScrollEnabled( false )
+ mIsAutoScrollEnabled( false ),
+ mAutoScrollDirectionRTL( false )
{
mLogicalModel = LogicalModel::New();
mVisualModel = VisualModel::New();
delete mEmbossDefaults;
delete mOutlineDefaults;
delete mEventData;
- delete mAutoScrollData;
}
// Text Controller Implementation.
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.
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
editableControlInterface ) );
}
-void Controller::SetTextControlInterface( ControlInterface* controlInterface )
-{
- mImpl->mControlInterface = controlInterface;
-}
-
// public : Configure the text controller.
void Controller::EnableTextInput( DecoratorPtr decorator )
UPDATE_DIRECTION |
REORDER );
- if( NULL == mImpl->mAutoScrollData )
- {
- mImpl->mAutoScrollData = new ScrollerData();
- }
}
else
{
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 )
}
}
-// 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 )
if ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) )
{
- if( NULL != mImpl->mAutoScrollData )
- {
- mImpl->mAutoScrollData->mAutoScrollDirectionRTL = false;
- }
+ mImpl->mAutoScrollDirectionRTL = false;
}
// Reorder the lines
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;
}
}
}
#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;
#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
{
class ControlInterface;
class EditableControlInterface;
class View;
-struct ScrollerData;
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.
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.
/**
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.
*/
virtual void TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Buttons button );
-private: // Inherit from TextScroller
-
- /**
- * @copydoc Text::ScrollerInterface::ScrollingFinished()
- */
- virtual void ScrollingFinished();
-
private: // Update.
/**
+++ /dev/null
-/*
- * 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
+++ /dev/null
-#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
-
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/text-scroller-interface.h>
-#include <dali-toolkit/internal/text/text-scroller-data.h>
namespace Dali
{
namespace Toolkit
{
-namespace Text
-{
-extern const int MINIMUM_SCROLL_SPEED;
-} // namespace
-
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
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;
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" );
}
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 )
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() )
class TextScroller;
class ScrollerInterface;
-struct ScrollerData;
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.
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.
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();
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
GradientVisual::GradientVisual( VisualFactoryCache& factoryCache )
: Visual::Base( factoryCache ),
- mGradientType( LINEAR )
+ mGradientType( LINEAR ),
+ mIsOpaque( true )
{
mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
}
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
{
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;
+ }
}
}
}
Matrix3 mGradientTransform;
IntrusivePtr<Gradient> mGradient;
Type mGradientType;
+ bool mIsOpaque; ///< Set to false if any of the stop colors are not opaque
};
} // namespace Internal
Visual::Base::SetSize( size );
}
-void BatchImageVisual::GetNaturalSize( Vector2& naturalSize ) const
+void BatchImageVisual::GetNaturalSize( Vector2& naturalSize )
{
if( mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0 )
{
/**
* @copydoc Visual::Base::GetNaturalSize
*/
- virtual void GetNaturalSize( Vector2& naturalSize ) const;
+ virtual void GetNaturalSize( Vector2& naturalSize );
/**
* @copydoc Visual::Base::CreatePropertyMap
}
}
-void ImageVisual::GetNaturalSize( Vector2& naturalSize ) const
+void ImageVisual::GetNaturalSize( Vector2& naturalSize )
{
if(mImage)
{
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()
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 );
}
}
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 );
}
}
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;
}
/**
* @copydoc Visual::Base::GetNaturalSize
*/
- virtual void GetNaturalSize( Vector2& naturalSize ) const;
+ virtual void GetNaturalSize( Vector2& naturalSize );
/**
* @copydoc Visual::Base::CreatePropertyMap
--- /dev/null
+ /*
+ * 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
--- /dev/null
+#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
// 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>
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 )
{
}
}
-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 );
}
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 );
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();
}
// Create indices
- //TODO: compare performance with triangle strip when Geometry supports it
Vector< unsigned short > indices;
indices.Reserve( gridWidth * gridHeight * 6 );
return GenerateGeometry( vertices, indices );
}
-Geometry NPatchVisual::CreateGeometryBorder( Uint16Pair gridSize )
+Geometry NPatchVisual::CreateBorderGeometry( Uint16Pair gridSize )
{
uint16_t gridWidth = gridSize.GetWidth();
uint16_t gridHeight = gridSize.GetHeight();
}
// Create indices
- //TODO: compare performance with triangle strip when Geometry supports it
Vector< unsigned short > indices;
indices.Reserve( gridWidth * gridHeight * 6 );
/**
* @copydoc Visual::Base::GetNaturalSize
*/
- virtual void GetNaturalSize( Vector2& naturalSize ) const;
+ virtual void GetNaturalSize( Vector2& naturalSize );
/**
* @copydoc Visual::Base::CreatePropertyMap
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
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
* @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
// 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;
/**
* @copydoc Visual::Base::GetNaturalSize
*/
- virtual void GetNaturalSize( Vector2& naturalSize ) const;
+ virtual void GetNaturalSize( Vector2& naturalSize );
/**
* @copydoc Visual::Base::CreatePropertyMap
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 );
mPlacementActor.Reset();
}
-void SvgVisual::GetNaturalSize( Vector2& naturalSize ) const
+void SvgVisual::GetNaturalSize( Vector2& naturalSize )
{
if( mParsedImage )
{
{
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 );
/**
* @copydoc Visual::Base::GetNaturalSize
*/
- virtual void GetNaturalSize( Vector2& naturalSize ) const;
+ virtual void GetNaturalSize( Vector2& naturalSize );
/**
* @copydoc Visual::Base::SetSize
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 );
return mController->GetHeightForWidth( width );
}
-void TextVisual::GetNaturalSize( Vector2& naturalSize ) const
+void TextVisual::GetNaturalSize( Vector2& naturalSize )
{
naturalSize = mController->GetNaturalSize().GetVectorXY();
}
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 );
}
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:
}
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:
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() );
}
}
#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
{
*/
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
/**
/**
* @copydoc Visual::Base::GetNaturalSize()
*/
- virtual void GetNaturalSize( Vector2& naturalSize ) const;
+ virtual void GetNaturalSize( Vector2& naturalSize );
/**
* @copydoc Visual::Base::CreatePropertyMap()
*/
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;
return 0.f;
}
-void Visual::Base::GetNaturalSize( Vector2& naturalSize ) const
+void Visual::Base::GetNaturalSize( Vector2& naturalSize )
{
naturalSize = Vector2::ZERO;
}
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
/**
* @copydoc Toolkit::Visual::Base::GetNaturalSize
*/
- virtual void GetNaturalSize( Vector2& naturalSize ) const;
+ virtual void GetNaturalSize( Vector2& naturalSize );
/**
* @copydoc Toolkit::Visual::Base::SetDepthIndex
// 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>
return mAtlasManager;
}
+NPatchLoader& VisualFactoryCache::GetNPatchLoader()
+{
+ return mNPatchLoader;
+}
+
SvgRasterizeThread* VisualFactoryCache::GetSVGRasterizationThread()
{
if( !mSvgRasterizeThread )
* 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>
#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
{
class ImageAtlasManager;
typedef IntrusivePtr<ImageAtlasManager> ImageAtlasManagerPtr;
+class NPatchLoader;
+
/**
* Caches shaders and geometries. Owned by VisualFactory.
*/
/**
* 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();
Renderer mWireframeRenderer;
ImageAtlasManagerPtr mAtlasManager;
+ NPatchLoader mNPatchLoader;
+
SvgRasterizeThread* mSvgRasterizeThread;
};
// 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
{
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)
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;
}
{
if( (*iter)->visual && self.OnStage() )
{
- (*iter)->visual.SetOffStage( self );
+ Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
}
(*iter)->visual = visual;
visualReplaced = true;
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
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.
}
}
}
if( (*iter)->visual && (*iter)->enabled )
{
Actor self( Self() );
- (*iter)->visual.SetOnStage( self );
+ Toolkit::GetImplementation((*iter)->visual).SetOnStage( self );
}
}
}
if( (*iter)->visual )
{
Actor self( Self() );
- (*iter)->visual.SetOffStage( self );
+ Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
}
}
}
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
$(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 \
$(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
AsyncImageLoader::AsyncImageLoader( Internal::AsyncImageLoader* impl )
: BaseHandle( impl )
-{}
+{
+}
AsyncImageLoader::AsyncImageLoader( const AsyncImageLoader& handle )
: BaseHandle( 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();
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
-#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.
}
/**
- *@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
+ * }
* }
* }
*
*
* 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
*/
{
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.
*/
/**
* @brief Destructor
+ * @SINCE_1_2_14
*
* This is non-virtual since derived Handle types must not contain data or virtual methods.
*/
/**
* @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();
* @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
};
} // namespace Dali
-#endif /* __DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H__ */
+#endif // DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
![ ](../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
___________________________________________________________________________________________________
// 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
}
~~~
___________________________________________________________________________________________________
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}
___________________________________________________________________________________________________
-### 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).
___________________________________________________________________________________________________
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:
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)
| 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
## 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.
| 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
## 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.
### 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)
### 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)
### 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
## 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)
## 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)
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
Name: NDalic
Summary: dali wrapper
-Version: 1.2.13
+Version: 1.2.14
Release: 1
Group: uifw/graphic
License: TO_BE_FILLED_IN
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