From 6e64f3edb893125dfc77c89944f75221a9addfaa Mon Sep 17 00:00:00 2001 From: Kingsley Stephens Date: Wed, 7 May 2014 17:34:31 +0100 Subject: [PATCH] (Popup) Fix size conflict between popup title and content [Issue#] N/A [Problem] The popup was not being laid out correctly when having content and no fixed size specified [Cause] The natural size of a TextView does not take wrapping into account [Solution] Limit max size of title to stage width and allow images in content to shrink but not grow Change-Id: Idd16e52b14bd946ee41ae58f62acb621123bffee --- .../internal/controls/popup/popup-impl.cpp | 64 +++++------- .../internal/controls/relayout-helper.cpp | 116 ++++++++++++++------- 2 files changed, 109 insertions(+), 71 deletions(-) diff --git a/base/dali-toolkit/internal/controls/popup/popup-impl.cpp b/base/dali-toolkit/internal/controls/popup/popup-impl.cpp index 8f1c9ef..88a88ed 100755 --- a/base/dali-toolkit/internal/controls/popup/popup-impl.cpp +++ b/base/dali-toolkit/internal/controls/popup/popup-impl.cpp @@ -732,16 +732,11 @@ void Popup::OnRelaidOut( Vector2 size, ActorSizeContainer& container ) // Relayout content if( mContent ) { - Vector2 contentSize; - contentSize.width = popupSize.width; - - Toolkit::Control control = Toolkit::Control::DownCast( mContent ); - if( control ) - { - contentSize.height = control.GetHeightForWidth( contentSize.width ); - } - else + // If the content width is greater than popup width then scale it down/wrap text as needed + Vector2 contentSize( RelayoutHelper::GetNaturalSize( mContent ) ); + if( contentSize.width > popupSize.width ) { + contentSize.width = popupSize.width; contentSize.height = RelayoutHelper::GetHeightForWidth( mContent, contentSize.width ); } @@ -826,28 +821,38 @@ bool Popup::OnKeyEvent(const KeyEvent& event) Vector3 Popup::GetNaturalSize() { - Vector3 naturalSize; + float margin = 2.0f * ( POPUP_OUT_MARGIN_WIDTH + mPopupStyle->margin ); + const float maxWidth = Stage::GetCurrent().GetSize().width - margin; - if ( mTitle ) - { - naturalSize += mTitle.GetImplementation().GetNaturalSize(); - naturalSize.height += mPopupStyle->margin; - } + Vector3 naturalSize( 0.0f, 0.0f, 0.0f ); - if( mContent ) + if ( mTitle ) { - Vector3 contentSize; - - Toolkit::Control control = Toolkit::Control::DownCast( mContent ); - if( control ) + Vector3 titleNaturalSize = mTitle.GetImplementation().GetNaturalSize(); + // Buffer to avoid errors. The width of the popup could potentially be the width of the title text. + // It was observed in this case that text wrapping was then inconsistent when seen on device + const float titleBuffer = 0.5f; + titleNaturalSize.width += titleBuffer; + + // As TextView GetNaturalSize does not take wrapping into account, limit the width + // to that of the stage + if( titleNaturalSize.width >= maxWidth) { - contentSize = control.GetImplementation().GetNaturalSize(); + naturalSize.width = maxWidth; + naturalSize.height = mTitle.GetImplementation().GetHeightForWidth( naturalSize.width ); } else { - contentSize = RelayoutHelper::GetNaturalSize( mContent ); + naturalSize += titleNaturalSize; } + naturalSize.height += mPopupStyle->margin; + } + + if( mContent ) + { + Vector3 contentSize = RelayoutHelper::GetNaturalSize( mContent ); + // Choose the biggest width naturalSize.width = std::max( naturalSize.width, contentSize.width ); naturalSize.height += contentSize.height + mPopupStyle->margin; } @@ -858,7 +863,6 @@ Vector3 Popup::GetNaturalSize() } // Add the margins - float margin( 2.0f * ( POPUP_OUT_MARGIN_WIDTH + mPopupStyle->margin ) ); naturalSize.width += margin; naturalSize.height += margin; @@ -878,19 +882,7 @@ float Popup::GetHeightForWidth( float width ) if( mContent ) { - float contentHeight; - - Toolkit::Control control = Toolkit::Control::DownCast( mContent ); - if( control ) - { - contentHeight = control.GetImplementation().GetHeightForWidth( popupWidth ); - } - else - { - contentHeight = RelayoutHelper::GetHeightForWidth( mContent, popupWidth ); - } - - height += contentHeight + mPopupStyle->margin; + height += RelayoutHelper::GetHeightForWidth( mContent, popupWidth ) + mPopupStyle->margin; } if( !mButtons.empty() ) diff --git a/base/dali-toolkit/internal/controls/relayout-helper.cpp b/base/dali-toolkit/internal/controls/relayout-helper.cpp index b5f1fc9..e951e80 100644 --- a/base/dali-toolkit/internal/controls/relayout-helper.cpp +++ b/base/dali-toolkit/internal/controls/relayout-helper.cpp @@ -16,6 +16,9 @@ #include "relayout-helper.h" +#include + + namespace Dali { @@ -30,29 +33,41 @@ namespace RelayoutHelper Vector3 GetNaturalSize( Actor actor ) { - Vector3 size = actor.GetCurrentSize(); - const float depth = size.depth; + Vector3 size( 0.0f, 0.0f, 0.0f ); - // Get natural size for TextActor. - TextActor textActor = TextActor::DownCast( actor ); - if( textActor ) + Toolkit::Control control = Toolkit::Control::DownCast( actor ); + if( control ) { - Font font = textActor.GetFont(); - if( !font ) - { - font = Font::New(); - } - size = font.MeasureText( textActor.GetText() ); - size.depth = depth; + size = control.GetNaturalSize(); } - - // Get natural size for ImageActor. - // TODO: currently it doesn't work as expected. - ImageActor imageActor = ImageActor::DownCast( actor ); - if( ( imageActor ) && ( imageActor.GetImage() ) ) + else { - Image image = imageActor.GetImage(); - size = Vector3( static_cast( image.GetWidth() ), static_cast( image.GetHeight() ), depth ); + size = actor.GetCurrentSize(); + const float depth = size.depth; + + // Get natural size for ImageActor. + // TODO: currently it doesn't work as expected. + ImageActor imageActor = ImageActor::DownCast( actor ); + if( ( imageActor ) && ( imageActor.GetImage() ) ) + { + Image image = imageActor.GetImage(); + size = Vector3( static_cast( image.GetWidth() ), static_cast( image.GetHeight() ), depth ); + } + else + { + // Get natural size for TextActor. + TextActor textActor = TextActor::DownCast( actor ); + if( textActor ) + { + Font font = textActor.GetFont(); + if( !font ) + { + font = Font::New(); + } + size = font.MeasureText( textActor.GetText() ); + size.depth = depth; + } + } } return size; @@ -60,28 +75,59 @@ Vector3 GetNaturalSize( Actor actor ) float GetHeightForWidth( Actor actor, float width ) { - Vector3 size = actor.GetCurrentSize(); - float height = 0.f; + float height = 0.0f; - TextActor textActor = TextActor::DownCast( actor ); - if( textActor ) + Toolkit::Control control = Toolkit::Control::DownCast( actor ); + if( control ) + { + height = control.GetHeightForWidth( width ); + } + else { - Font font = textActor.GetFont(); - if( !font ) + bool constrainSize = false; + Vector3 size( 0.0f, 0.0f, 0.0f ); + + ImageActor imageActor = ImageActor::DownCast( actor ); + if( ( imageActor ) && ( imageActor.GetImage() ) ) + { + Image image = imageActor.GetImage(); + size = Vector3( static_cast( image.GetWidth() ), static_cast( image.GetHeight() ), 0.0f ); + + constrainSize = true; + } + else { - font = Font::New(); + TextActor textActor = TextActor::DownCast( actor ); + if( textActor ) + { + Font font = textActor.GetFont(); + if( !font ) + { + font = Font::New(); + } + size = font.MeasureText( textActor.GetText() ); + + constrainSize = true; + } + else + { + size = actor.GetCurrentSize(); + } } - size = font.MeasureText( textActor.GetText() ); - } - ImageActor imageActor = ImageActor::DownCast( actor ); - if( ( imageActor ) && ( imageActor.GetImage() ) ) - { - Image image = imageActor.GetImage(); - size = Vector3( static_cast( image.GetWidth() ), static_cast( image.GetHeight() ), 0.f ); - } + // Scale the actor + float scaleRatio = width / size.width; + if( constrainSize ) + { + // Allow the scale to decrease if greater than input width but not increase if less than input width + if( scaleRatio > 1.0f ) + { + scaleRatio = 1.0f; + } + } - height = size.height / ( size.width / width ); + height = size.height * scaleRatio; + } return height; } -- 2.7.4