From: Xiangyin Ma Date: Mon, 28 Sep 2015 17:34:35 +0000 (+0100) Subject: Render control background without creating extra actor X-Git-Tag: dali_1.1.5~2^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=a41be0bf03293b22c95b2fa206aa87357e0d406a Render control background without creating extra actor Change-Id: Ifda38ccf7da36fce360faca7dcbea58c0044d8ad --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp index f77f903..4bfc808 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp @@ -382,7 +382,20 @@ int UtcDaliControlBackgroundColor(void) DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); control.SetBackgroundColor( Color::RED ); - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::RED, TEST_LOCATION ); + + Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND ); + Property::Map* resultMap = propValue.GetMap(); + DALI_TEST_CHECK( resultMap->Find( "renderer-type" ) ); + DALI_TEST_CHECK( resultMap->Find( "renderer-type" )->Get() == "color-renderer" ); + DALI_TEST_CHECK( resultMap->Find( "blend-color" ) ); + DALI_TEST_CHECK( resultMap->Find( "blend-color" )->Get() == Color::RED ); + + control.SetBackgroundColor( Color::YELLOW ); + + propValue = control.GetProperty( Control::Property::BACKGROUND ); + resultMap = propValue.GetMap(); + DALI_TEST_CHECK( resultMap->Find( "blend-color" ) ); + DALI_TEST_CHECK( resultMap->Find( "blend-color" )->Get() == Color::YELLOW ); END_TEST; } @@ -396,21 +409,21 @@ int UtcDaliControlBackgroundImage(void) Image image = ResourceImage::New("TestImage"); control.SetBackgroundImage( image ); - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); - - control.SetBackgroundColor( Color::GREEN ); - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::GREEN, TEST_LOCATION ); - - control.SetBackgroundColor( Color::RED ); - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::RED, TEST_LOCATION ); - control.ClearBackground(); - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); + Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND ); + Property::Map* resultMap = propValue.GetMap(); + DALI_TEST_CHECK( resultMap->Find( "renderer-type" ) ); + DALI_TEST_CHECK( resultMap->Find( "renderer-type" )->Get() == "image-renderer" ); + DALI_TEST_CHECK( resultMap->Find( "image-url" ) ); + DALI_TEST_CHECK( resultMap->Find( "image-url" )->Get() == "TestImage" ); - control.SetBackgroundColor( Color::YELLOW ); + image = ResourceImage::New("TestImage2"); control.SetBackgroundImage( image ); - // The background can be either an image or a color, not both - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); + + propValue = control.GetProperty( Control::Property::BACKGROUND ); + resultMap = propValue.GetMap(); + DALI_TEST_CHECK( resultMap->Find( "image-url" ) ); + DALI_TEST_CHECK( resultMap->Find( "image-url" )->Get() == "TestImage2" ); END_TEST; } @@ -420,34 +433,42 @@ int UtcDaliControlBackgroundProperties(void) ToolkitTestApplication application; Control control = Control::New(); - DALI_TEST_CHECK( control.GetChildCount() == 0 ); DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND ).Get< Property::Map >().Empty() ); Property::Map colorMap; colorMap["color"] = Color::RED; control.SetProperty( Control::Property::BACKGROUND, colorMap ); - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::RED, TEST_LOCATION ); - DALI_TEST_CHECK( control.GetChildCount() > 0 ); Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND ); Property::Map* resultMap = propValue.GetMap(); - DALI_TEST_CHECK( resultMap->Find( "color" ) ); - DALI_TEST_CHECK( resultMap->Find( "color" )->Get() == Color::RED ); + DALI_TEST_CHECK( resultMap->Find( "renderer-type" ) ); + DALI_TEST_CHECK( resultMap->Find( "renderer-type" )->Get() == "color-renderer" ); + DALI_TEST_CHECK( resultMap->Find( "blend-color" ) ); + DALI_TEST_CHECK( resultMap->Find( "blend-color" )->Get() == Color::RED ); Property::Map imageMap; imageMap[ "filename" ] = "TestImage"; control.SetProperty( Control::Property::BACKGROUND, imageMap ); - DALI_TEST_CHECK( control.GetChildCount() > 0 ); - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); propValue = control.GetProperty( Control::Property::BACKGROUND ); resultMap = propValue.GetMap(); - DALI_TEST_CHECK( resultMap->Find( "filename" ) ); - DALI_TEST_CHECK( resultMap->Find( "filename" )->Get< std::string>() == "TestImage" ); + DALI_TEST_CHECK( resultMap->Find( "renderer-type" ) ); + DALI_TEST_CHECK( resultMap->Find( "renderer-type" )->Get() == "image-renderer" ); + DALI_TEST_CHECK( resultMap->Find( "image-url" ) ); + DALI_TEST_CHECK( resultMap->Find( "image-url" )->Get() == "TestImage" ); + + Property::Map rendererMap; + rendererMap["renderer-type"] = "color-renderer"; + rendererMap["blend-color"] = Color::CYAN; + control.SetProperty( Control::Property::BACKGROUND, rendererMap ); + propValue = control.GetProperty( Control::Property::BACKGROUND ); + resultMap = propValue.GetMap(); + DALI_TEST_CHECK( resultMap->Find( "renderer-type" ) ); + DALI_TEST_CHECK( resultMap->Find( "renderer-type" )->Get() == "color-renderer" ); + DALI_TEST_CHECK( resultMap->Find( "blend-color" ) ); + DALI_TEST_CHECK( resultMap->Find( "blend-color" )->Get() == Color::CYAN ); Property::Map emptyMap; control.SetProperty( Control::Property::BACKGROUND, emptyMap ); - DALI_TEST_CHECK( control.GetChildCount() == 0 ); - DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION ); DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND ).Get< Property::Map >().Empty() ); END_TEST; diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp index abe2fb6..e0b50d1 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp @@ -74,7 +74,7 @@ int UtcDaliControlRendererCopyAndAssignment(void) END_TEST; } -int UtcDaliControlRendererSetDepthIndex(void) +int UtcDaliControlRendererSetGetDepthIndex(void) { ToolkitTestApplication application; tet_infoline( "UtcDaliControlRendererSetDepthIndex" ); @@ -93,9 +93,75 @@ int UtcDaliControlRendererSetDepthIndex(void) controlRenderer.SetOnStage( actor ); DALI_TEST_EQUALS( actor.GetRendererAt(0u).GetDepthIndex(), 1.f, TEST_LOCATION ); + DALI_TEST_EQUALS( controlRenderer.GetDepthIndex(), 1.f, TEST_LOCATION ); controlRenderer.SetDepthIndex( -1.f ); DALI_TEST_EQUALS( actor.GetRendererAt(0u).GetDepthIndex(), -1.f, TEST_LOCATION ); + DALI_TEST_EQUALS( controlRenderer.GetDepthIndex(), -1.f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliControlRendererSize(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliControlRendererGetNaturalSize" ); + + RendererFactory factory = RendererFactory::Get(); + Vector2 rendererSize( 20.f, 30.f ); + Vector2 naturalSize; + + // color renderer + ControlRenderer colorRenderer = factory.GetControlRenderer( Color::MAGENTA ); + colorRenderer.SetSize( rendererSize ); + DALI_TEST_EQUALS( colorRenderer.GetSize(), rendererSize, TEST_LOCATION ); + colorRenderer.GetNaturalSize(naturalSize); + DALI_TEST_EQUALS( naturalSize, Vector2::ZERO, TEST_LOCATION ); + + // image renderer + Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME, ImageDimensions(100, 200)); + ControlRenderer imageRenderer = factory.GetControlRenderer( image ); + imageRenderer.SetSize( rendererSize ); + DALI_TEST_EQUALS( imageRenderer.GetSize(), rendererSize, TEST_LOCATION ); + imageRenderer.GetNaturalSize(naturalSize); + DALI_TEST_EQUALS( naturalSize, Vector2(100.f, 200.f), TEST_LOCATION ); + + // n patch renderer + TestPlatformAbstraction& platform = application.GetPlatform(); + Vector2 testSize(80.f, 160.f); + platform.SetClosestImageSize(testSize); + image = ResourceImage::New(TEST_NPATCH_FILE_NAME); + ControlRenderer nPatchRenderer = factory.GetControlRenderer( image ); + nPatchRenderer.SetSize( rendererSize ); + DALI_TEST_EQUALS( nPatchRenderer.GetSize(), rendererSize, TEST_LOCATION ); + nPatchRenderer.GetNaturalSize(naturalSize); + DALI_TEST_EQUALS( naturalSize, testSize, TEST_LOCATION ); + + // border renderer + float borderSize = 5.f; + ControlRenderer borderRenderer = factory.GetControlRenderer( borderSize, Color::RED ); + borderRenderer.SetSize( rendererSize ); + DALI_TEST_EQUALS( borderRenderer.GetSize(), rendererSize, TEST_LOCATION ); + borderRenderer.GetNaturalSize(naturalSize); + DALI_TEST_EQUALS( naturalSize, Vector2::ZERO, TEST_LOCATION ); + + // gradient renderer + Property::Map propertyMap; + propertyMap.Insert("renderer-type", "gradient-renderer"); + Vector2 start(-1.f, -1.f); + Vector2 end(1.f, 1.f); + propertyMap.Insert("gradient-start-position", start); + propertyMap.Insert("gradient-end-position", end); + propertyMap.Insert("gradient-stop-offset", Vector2(0.f, 1.f)); + Property::Array stopColors; + stopColors.PushBack( Color::RED ); + stopColors.PushBack( Color::GREEN ); + propertyMap.Insert("gradient-stop-color", stopColors); + ControlRenderer gradientRenderer = factory.GetControlRenderer(propertyMap); + gradientRenderer.SetSize( rendererSize ); + DALI_TEST_EQUALS( gradientRenderer.GetSize(), rendererSize, TEST_LOCATION ); + gradientRenderer.GetNaturalSize(naturalSize); + DALI_TEST_EQUALS( naturalSize, Vector2::ZERO,TEST_LOCATION ); END_TEST; } @@ -132,6 +198,47 @@ int UtcDaliControlRendererSetOnOffStage(void) END_TEST; } +int UtcDaliControlRendererRemoveAndReset(void) +{ + ToolkitTestApplication application; + tet_infoline( "intUtcDaliControlRendererRemoveAndReset" ); + + RendererFactory factory = RendererFactory::Get(); + + Actor actor = Actor::New(); + actor.SetSize(200.f, 200.f); + Stage::GetCurrent().Add( actor ); + + ControlRenderer imageRenderer; + // test calling RemoveAndReset with an empty handle + try + { + imageRenderer.RemoveAndReset( actor ); + tet_result(TET_PASS); + } + catch (DaliException& exception) + { + tet_result(TET_FAIL); + } + + Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME, ImageDimensions(100, 200)); + imageRenderer = factory.GetControlRenderer(image); + DALI_TEST_CHECK( imageRenderer ); + + imageRenderer.SetOnStage( actor ); + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + + imageRenderer.RemoveAndReset( actor ); + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); // renderer is removed from actor + DALI_TEST_CHECK( !imageRenderer ); // control renderer is reset + + END_TEST; +} + int UtcDaliControlRendererGetPropertyMap1(void) { ToolkitTestApplication application; diff --git a/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp b/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp index 30e8b58..c036334 100644 --- a/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp +++ b/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp @@ -56,11 +56,26 @@ void ControlRenderer::SetSize( const Vector2& size ) GetImplementation( *this ).SetSize(size); } +const Vector2& ControlRenderer::GetSize() const +{ + return GetImplementation( *this ).GetSize(); +} + +void ControlRenderer::GetNaturalSize(Vector2& naturalSize ) const +{ + GetImplementation( *this ).GetNaturalSize( naturalSize ); +} + void ControlRenderer::SetDepthIndex( float index ) { GetImplementation( *this ).SetDepthIndex(index); } +float ControlRenderer::GetDepthIndex() const +{ + return GetImplementation( *this ).GetDepthIndex(); +} + void ControlRenderer::SetOnStage( Actor& actor ) { GetImplementation( *this ).SetOnStage(actor); @@ -71,6 +86,15 @@ void ControlRenderer::SetOffStage( Actor& actor ) GetImplementation( *this ).SetOffStage(actor); } +void ControlRenderer::RemoveAndReset( Actor& actor ) +{ + if( actor && *this ) + { + SetOffStage( actor ); + } + Reset(); +} + void ControlRenderer::CreatePropertyMap( Property::Map& map ) const { GetImplementation( *this ).CreatePropertyMap( map ); diff --git a/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h b/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h index 3a44603..fe26fab 100644 --- a/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h +++ b/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h @@ -78,6 +78,22 @@ public: void SetSize( const Vector2& size ); /** + * @brief Get the size of the painting area. + * + * @return The size of the renderer's painting area. + */ + const Vector2& GetSize() const; + + /** + * @brief Return the natural size of the renderer. + * + * Deriving classes stipulate the natural size and by default a renderer has a ZERO natural size. + * + * @param[out] naturalSize The renderer's natural size + */ + void GetNaturalSize( Vector2& naturalSize ) const; + + /** * @brief Set the depth index of this renderer. * * Depth-index controls draw-order for overlapping renderers. @@ -88,6 +104,13 @@ public: void SetDepthIndex( float index ); /** + * @brief Get the depth index of this renderer + * + * @return The depth index of this renderer. + */ + float GetDepthIndex() const; + + /** * @brief Renderer only exists when control is on stage. * * This function should be called when the control put on stage. @@ -106,6 +129,15 @@ public: void SetOffStage( Actor& actor ); /** + * @brief Remove the renderer from actor and reset the control renderer self. + * + * This function can be called with an empty handle. If the control renderer is empty, do nothing. + * + * @param[in] actor The actor to be set off stage. + */ + void RemoveAndReset( Actor& actor ); + + /** * @brief Create the property map representing this renderer. * * @param[out] map The renderer property map. diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp b/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp index acc3ead..1fa7bf3 100644 --- a/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp +++ b/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp @@ -49,6 +49,16 @@ void ControlRenderer::SetSize( const Vector2& size ) mImpl->mSize = size; } +const Vector2& ControlRenderer::GetSize() const +{ + return mImpl->mSize; +} + +void ControlRenderer::GetNaturalSize( Vector2& naturalSize ) const +{ + naturalSize = Vector2::ZERO; +} + void ControlRenderer::SetClipRect( const Rect& clipRect ) { mImpl->mClipRect = clipRect; @@ -68,6 +78,11 @@ void ControlRenderer::SetDepthIndex( float index ) } } +float ControlRenderer::GetDepthIndex() const +{ + return mImpl->mDepthIndex; +} + void ControlRenderer::SetOnStage( Actor& actor ) { Material material = Material::New( mImpl->mShader ); @@ -81,12 +96,15 @@ void ControlRenderer::SetOnStage( Actor& actor ) void ControlRenderer::SetOffStage( Actor& actor ) { - DoSetOffStage( actor ); + if( mImpl->mIsOnStage ) + { + DoSetOffStage( actor ); - actor.RemoveRenderer( mImpl->mRenderer ); - mImpl->mRenderer.Reset(); + actor.RemoveRenderer( mImpl->mRenderer ); + mImpl->mRenderer.Reset(); - mImpl->mIsOnStage = false; + mImpl->mIsOnStage = false; + } } void ControlRenderer::DoSetOnStage( Actor& actor ) diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-impl.h b/dali-toolkit/internal/controls/renderers/control-renderer-impl.h index 86620f8..773e7c0 100644 --- a/dali-toolkit/internal/controls/renderers/control-renderer-impl.h +++ b/dali-toolkit/internal/controls/renderers/control-renderer-impl.h @@ -61,6 +61,16 @@ public: virtual void SetSize( const Vector2& size ); /** + * @copydoc Toolkit::ControlRenderer::GetSize + */ + const Vector2& GetSize() const; + + /** + * @copydoc Toolkit::ControlRenderer::GetNaturalSize + */ + virtual void GetNaturalSize( Vector2& naturalSize ) const; + + /** * ToDo: Add this function to Toolkit::ControlRenderer when it is fully implemented. * * Set the clip rectangular of this renderer. @@ -85,6 +95,11 @@ public: void SetDepthIndex( float index ); /** + * @copydoc Toolkit::ControlRenderer::GetDepthIndex + */ + float GetDepthIndex() const; + + /** * @copydoc Toolkit::ControlRenderer::SetOnStage * @pre Impl->mGeometry must be created before this method is called */ diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp index 93c5c9a..b84b5f5 100644 --- a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp @@ -215,18 +215,40 @@ void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Proper void ImageRenderer::SetSize( const Vector2& size ) { ControlRenderer::SetSize( size ); - // ToDo: renderer responds to the size change +} + +void ImageRenderer::GetNaturalSize( Vector2& naturalSize ) const +{ + if(mImage) + { + naturalSize.x = mImage.GetWidth(); + naturalSize.y = mImage.GetHeight(); + return; + } + else if( mDesiredSize.GetWidth()>0 && mDesiredSize.GetHeight()>0) + { + naturalSize.x = mDesiredSize.GetWidth(); + naturalSize.y = mDesiredSize.GetHeight(); + return; + } + else if( !mImageUrl.empty() ) + { + ImageDimensions dimentions = ResourceImage::GetImageSize( mImageUrl ); + naturalSize.x = dimentions.GetWidth(); + naturalSize.y = dimentions.GetHeight(); + return; + } + + naturalSize = Vector2::ZERO; } void ImageRenderer::SetClipRect( const Rect& clipRect ) { ControlRenderer::SetClipRect( clipRect ); - //ToDo: renderer responds to the clipRect change } void ImageRenderer::SetOffset( const Vector2& offset ) { - //ToDo: renderer applies the offset } void ImageRenderer::DoSetOnStage( Actor& actor ) diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.h b/dali-toolkit/internal/controls/renderers/image/image-renderer.h index bbaa139..fd88df0 100644 --- a/dali-toolkit/internal/controls/renderers/image/image-renderer.h +++ b/dali-toolkit/internal/controls/renderers/image/image-renderer.h @@ -95,6 +95,11 @@ public: // from ControlRenderer virtual void SetSize( const Vector2& size ); /** + * @copydoc ControlRenderer::GetNaturalSize + */ + virtual void GetNaturalSize( Vector2& naturalSize ) const; + + /** * @copydoc ControlRenderer::SetClipRect */ virtual void SetClipRect( const Rect& clipRect ); diff --git a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp index d49f3d3..aa52f3e 100644 --- a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp @@ -187,6 +187,25 @@ void NPatchRenderer::Initialize( RendererFactoryCache& factoryCache, const Prope } } +void NPatchRenderer::GetNaturalSize( Vector2& naturalSize ) const +{ + if( mImage ) + { + naturalSize.x = mImage.GetWidth(); + naturalSize.y = mImage.GetHeight(); + return; + } + else if( !mImageUrl.empty() ) + { + ImageDimensions dimentions = ResourceImage::GetImageSize( mImageUrl ); + naturalSize.x = dimentions.GetWidth(); + naturalSize.y = dimentions.GetHeight(); + return; + } + + naturalSize = Vector2::ZERO; +} + void NPatchRenderer::SetClipRect( const Rect& clipRect ) { ControlRenderer::SetClipRect( clipRect ); diff --git a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h index 6bdb696..0bcd28a 100644 --- a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h +++ b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h @@ -71,6 +71,11 @@ public: // from ControlRenderer virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); /** + * @copydoc ControlRenderer::GetNaturalSize + */ + virtual void GetNaturalSize( Vector2& naturalSize ) const; + + /** * @copydoc ControlRenderer::SetClipRect */ virtual void SetClipRect( const Rect& clipRect ); diff --git a/dali-toolkit/public-api/controls/control-impl.cpp b/dali-toolkit/public-api/controls/control-impl.cpp index af2f4ca..c3ca785 100644 --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@ -164,98 +164,8 @@ TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &Do DALI_TYPE_REGISTRATION_END() - const char * const BACKGROUND_COLOR_NAME("color"); -/** - * Structure which holds information about the background of a control - */ -struct Background -{ - //ToDo: remove this actor and apply the Renderer on the Control - // when the implementation of Actor::RemoveRenderer(Renderer&) is in place. - Actor actor; ///< Background actor - ControlRenderer controlRenderer; ///< The control renderer to render the background - // The background can either be an image or a solid color. - Image image; ///< The background image - Vector4 color; ///< The background color - - /** - * Constructor - */ - Background() - : actor(), - controlRenderer(), - image(), - color( Color::TRANSPARENT ) - { - } -}; - -//ToDo: skip this actor creation and apply the Renderer on the Control -// when the implementation of Actor::RemoveRenderer(Renderer&) is in place. -Actor CreateBackgroundActor() -{ - // Create the actor - Actor actor = Actor::New(); - actor.SetSize( Vector3::ONE ); - actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION ); - actor.SetColorMode( USE_PARENT_COLOR ); - - //Constraint scale of the background actor to the size of the control - Constraint constraint = Constraint::New( actor, - Actor::Property::SCALE, - EqualToConstraint() ); - constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); - constraint.Apply(); - - return actor; -} - -/** - * @brief Create the background actor for the control. - * - * @param[in] actor The parent actor of the background - * @param[in] color The background color - */ -void CreateBackground( Background& background, const Vector4& color ) -{ - background.actor = CreateBackgroundActor(); - - background.image.Reset(); - background.color = color; - - // Create the control renderer - RendererFactory rendererFactory = Toolkit::RendererFactory::Get(); - background.controlRenderer = rendererFactory.GetControlRenderer(color); - - // ToDo: Call SetOnStage at Control::OnStageConnection and call SetOffStage at Control::OnStageDisconnection; - // Currently Actor::RemoveRenderer doesnot work yet. - background.controlRenderer.SetOnStage( background.actor ); -} - -/** - * @brief Create the background actor for the control. - * - * @param[in] actor The parent actor of the background - * @param[in] image The background image - */ -void CreateBackground( Background& background, const Image& image ) -{ - background.actor = CreateBackgroundActor(); - - background.color = Color::TRANSPARENT; - background.image = image; - - // Create the control renderer - RendererFactory rendererFactory = Toolkit::RendererFactory::Get(); - background.controlRenderer = rendererFactory.GetControlRenderer(image); - - // ToDo: Call SetOnStage at Control::OnStageConnection and call SetOffStage at Control::OnStageDisconnection; - // Currently Actor::RemoveRenderer doesnot work yet. - background.controlRenderer.SetOnStage( background.actor ); -} - } // unnamed namespace namespace Internal @@ -269,7 +179,7 @@ public: Impl(Control& controlImpl) : mControlImpl( controlImpl ), mStyleName(""), - mBackground( NULL ), + mBackgroundRenderer(), mStartingPinchScale( NULL ), mKeyEventSignal(), mPinchGestureDetector(), @@ -286,7 +196,6 @@ public: ~Impl() { // All gesture detectors will be destroyed so no need to disconnect. - delete mBackground; delete mStartingPinchScale; } @@ -312,21 +221,6 @@ public: mControlImpl.OnLongPress(longPress); } - // Background Methods - - /** - * Only creates an instance of the background if we actually use it. - * @return A reference to the Background structure. - */ - Background& GetBackground() - { - if ( !mBackground ) - { - mBackground = new Background; - } - return *mBackground; - } - // Properties /** @@ -361,16 +255,11 @@ public: const Property::Map* map = value.GetMap(); if( map ) { - const Property::Value* colorValue = map->Find( BACKGROUND_COLOR_NAME ); - Vector4 color; - if( colorValue && colorValue->Get(color)) - { - controlImpl.SetBackgroundColor( color ); - break; - } + controlImpl.SetBackground( *map ); + break; } - // The background is neither an valid image nor a valid color, so it is no longer required + // The background is neither a valid image nor a property map, so it is no longer required controlImpl.ClearBackground(); break; } @@ -418,18 +307,9 @@ public: case Toolkit::Control::Property::BACKGROUND: { Property::Map map; - - Background* back = controlImpl.mImpl->mBackground; - if ( back && back->actor) + if( controlImpl.mImpl->mBackgroundRenderer ) { - if( back->image ) - { - Scripting::CreatePropertyMap( back->image, map ); - } - else - { - map[BACKGROUND_COLOR_NAME] = back->color; - } + (controlImpl.mImpl->mBackgroundRenderer).CreatePropertyMap( map ); } value = map; @@ -451,7 +331,7 @@ public: Control& mControlImpl; std::string mStyleName; - Background* mBackground; ///< Only create the background if we use it + Toolkit::ControlRenderer mBackgroundRenderer; ///< The control renderer to render the background Vector3* mStartingPinchScale; ///< The scale when a pinch gesture starts, TODO: consider removing this Toolkit::Control::KeyEventSignalType mKeyEventSignal; Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusGainedSignal; @@ -521,81 +401,93 @@ const std::string& Control::GetStyleName() const void Control::SetBackgroundColor( const Vector4& color ) { - Background& background( mImpl->GetBackground() ); + Actor self( Self() ); + Toolkit::RendererFactory factory = Toolkit::RendererFactory::Get(); - // The background renderer exits and it is a color renderer, we continue to use the current renderer - if ( background.actor && (!background.image) - && (!Toolkit::RendererFactory::Get().ResetRenderer( background.controlRenderer, color ) )) + if( mImpl->mBackgroundRenderer ) { - background.color = color; + Toolkit::ControlRenderer currentRenderer( mImpl->mBackgroundRenderer ); + // if ResetRenderer returns false, we continue to use the current renderer with a new color set to it. + if( ! factory.ResetRenderer( mImpl->mBackgroundRenderer, color ) ) + { + return; + } + // ResetRenderer returns true, a new renderer is created. Remove the current renderer and reset. + currentRenderer.RemoveAndReset( self ); } else { - // TODO: Apply the new renderer directly, as Actor::RemoveRenderer is not working yet, we create a new actor - if( background.actor ) - { - mImpl->mAddRemoveBackgroundChild = true; - Self().Remove( background.actor ); - mImpl->mAddRemoveBackgroundChild = false; - } - // Create background actor - CreateBackground(background, color ); - mImpl->mAddRemoveBackgroundChild = true; - // The actor does not need to be inserted to guarantee order. - Self().Add( background.actor ); - mImpl->mAddRemoveBackgroundChild = false; + mImpl->mBackgroundRenderer = factory.GetControlRenderer( color ); + } + + if( self.OnStage() ) + { + mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX ); + mImpl->mBackgroundRenderer.SetOnStage( self ); } } Vector4 Control::GetBackgroundColor() const { - if ( mImpl->mBackground ) + return Color::TRANSPARENT; +} + +void Control::SetBackground(const Property::Map& map) +{ + const Property::Value* colorValue = map.Find( BACKGROUND_COLOR_NAME ); + Vector4 color; + if( colorValue && colorValue->Get(color)) { - return mImpl->mBackground->color; + SetBackgroundColor( color ); + return; + } + + Actor self( Self() ); + mImpl->mBackgroundRenderer.RemoveAndReset( self ); + + Toolkit::RendererFactory factory = Toolkit::RendererFactory::Get(); + mImpl->mBackgroundRenderer = factory.GetControlRenderer( map ); + + // mBackgroundRenderer might be empty, if an invalid map is provided, no background. + if( self.OnStage() && mImpl->mBackgroundRenderer) + { + mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX ); + mImpl->mBackgroundRenderer.SetOnStage( self ); } - return Color::TRANSPARENT; } void Control::SetBackgroundImage( Image image ) { - Background& background( mImpl->GetBackground() ); + Actor self( Self() ); + Toolkit::RendererFactory factory = Toolkit::RendererFactory::Get(); - // The background renderer exits and it is an image renderer, we continue to use the current renderer - if( background.actor && background.image - && (! Toolkit::RendererFactory::Get().ResetRenderer( background.controlRenderer, image ) ) ) + if( mImpl->mBackgroundRenderer ) { - background.image = image; + Toolkit::ControlRenderer currentRenderer( mImpl->mBackgroundRenderer ); + // if ResetRenderer returns false, we continue to use the current renderer with a new image set to it. + if( ! factory.ResetRenderer( mImpl->mBackgroundRenderer, image ) ) + { + return; + } + // ResetRenderer returns true, a new renderer is created. Remove the current renderer and reset. + currentRenderer.RemoveAndReset( self ); } else { - // TODO: Apply the new renderer directly, as Actor::RemoveRenderer is not working yet, we create a new actor - if( background.actor ) - { - mImpl->mAddRemoveBackgroundChild = true; - Self().Remove( background.actor ); - mImpl->mAddRemoveBackgroundChild = false; - } - // Create background actor - CreateBackground(background, image); - mImpl->mAddRemoveBackgroundChild = true; - // The actor does not need to be inserted to guarantee order. - Self().Add( background.actor ); - mImpl->mAddRemoveBackgroundChild = false; + mImpl->mBackgroundRenderer = factory.GetControlRenderer( image ); + } + + if( self.OnStage() ) + { + mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX ); + mImpl->mBackgroundRenderer.SetOnStage( self ); } } void Control::ClearBackground() { - if ( mImpl->mBackground ) - { - Background& background( mImpl->GetBackground() ); - mImpl->mAddRemoveBackgroundChild = true; - Self().Remove( background.actor ); - mImpl->mAddRemoveBackgroundChild = false; - - delete mImpl->mBackground; - mImpl->mBackground = NULL; - } + Actor self(Self()); + mImpl->mBackgroundRenderer.RemoveAndReset( self ); } void Control::EnableGestureDetection(Gesture::Type type) @@ -928,14 +820,21 @@ void Control::OnStageConnection( int depth ) } } - if( mImpl->mBackground && mImpl->mBackground->controlRenderer) + if( mImpl->mBackgroundRenderer) { - mImpl->mBackground->controlRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX+depth ); + mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX ); + Actor self(Self()); + mImpl->mBackgroundRenderer.SetOnStage( self ); } } void Control::OnStageDisconnection() { + if( mImpl->mBackgroundRenderer) + { + Actor self(Self()); + mImpl->mBackgroundRenderer.SetOffStage( self ); + } } void Control::OnKeyInputFocusGained() @@ -1016,30 +915,13 @@ void Control::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dime Vector3 Control::GetNaturalSize() { - //Control's natural size is the size of its background image if it has been set, or ZERO otherwise - Vector3 naturalSize = Vector3::ZERO; - if( mImpl->mBackground ) + if( mImpl->mBackgroundRenderer ) { - if( mImpl->mBackground->actor.GetRendererCount() > 0 ) - { - Material backgroundMaterial = mImpl->mBackground->actor.GetRendererAt(0).GetMaterial(); - if( backgroundMaterial.GetNumberOfSamplers() > 0 ) - { - Image backgroundImage = backgroundMaterial.GetSamplerAt(0).GetImage(); - if( backgroundImage ) - { - naturalSize.x = backgroundImage.GetWidth(); - naturalSize.y = backgroundImage.GetHeight(); - } - } - } - else - { - return mImpl->mBackground->actor.GetNaturalSize(); - } + Vector2 naturalSize; + mImpl->mBackgroundRenderer.GetNaturalSize(naturalSize); + return Vector3(naturalSize); } - - return naturalSize; + return Vector3::ZERO; } float Control::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension ) @@ -1049,27 +931,11 @@ float Control::CalculateChildSize( const Dali::Actor& child, Dimension::Type dim float Control::GetHeightForWidth( float width ) { - if( mImpl->mBackground ) - { - Actor actor = mImpl->mBackground->actor; - if( actor ) - { - return actor.GetHeightForWidth( width ); - } - } return GetHeightForWidthBase( width ); } float Control::GetWidthForHeight( float height ) { - if( mImpl->mBackground ) - { - Actor actor = mImpl->mBackground->actor; - if( actor ) - { - return actor.GetWidthForHeight( height ); - } - } return GetWidthForHeightBase( height ); } diff --git a/dali-toolkit/public-api/controls/control-impl.h b/dali-toolkit/public-api/controls/control-impl.h index 4a8466d..aa86d6a 100644 --- a/dali-toolkit/public-api/controls/control-impl.h +++ b/dali-toolkit/public-api/controls/control-impl.h @@ -102,6 +102,13 @@ public: void SetBackgroundImage( Image image ); /** + * @brief Set the background with a property map. + * + * @param[in] map The background property map. + */ + void SetBackground(const Property::Map& map); + + /** * @copydoc Dali::Toolkit::Control::ClearBackground */ void ClearBackground(); diff --git a/dali-toolkit/public-api/controls/control.h b/dali-toolkit/public-api/controls/control.h index d6425e2..51f6bd1 100644 --- a/dali-toolkit/public-api/controls/control.h +++ b/dali-toolkit/public-api/controls/control.h @@ -89,7 +89,7 @@ public: enum { STYLE_NAME = PROPERTY_START_INDEX, ///< name "style-name", @see SetStyleName, type std::string - BACKGROUND, ///< name "background", @see SetBackgroundImage, type Map, @since DALi 1.1.4 + BACKGROUND, ///< name "background", @since DALi 1.1.4, type Map KEY_INPUT_FOCUS, ///< name "key-input-focus", @see SetKeyInputFocus, type bool }; };