Improve percentage resolution in HTML elements.

This commit is contained in:
Martín Lucas Golini
2026-05-03 19:49:38 -03:00
parent da30372aae
commit 9e3c13903d
5 changed files with 94 additions and 34 deletions

View File

@@ -42,6 +42,8 @@ class EE_API StyleSheetLength {
static bool isLength( const std::string& unitStr );
static bool isPercentage( const std::string& val );
static StyleSheetLength fromString( const std::string& str, const Float& defaultValue = 0,
bool pxAsDp = false );

View File

@@ -68,6 +68,12 @@ void BlockLayouter::updateLayout() {
{ mContainer->lengthFromValue( *prop ), mContainer->getPixelsSize().getHeight() } );
}
if ( mContainer->getLayoutHeightPolicy() == SizePolicy::Fixed && mContainer->getUIStyle() &&
( prop = mContainer->getUIStyle()->getProperty( PropertyId::Height ) ) ) {
mContainer->setInternalPixelsSize(
{ mContainer->getPixelsSize().getWidth(), mContainer->lengthFromValue( *prop ) } );
}
UIRichText::rebuildRichText( widget, *rt );
rt->updateLayout();
@@ -80,6 +86,20 @@ void BlockLayouter::updateLayout() {
mContainer->getPixelsContentOffset().Right;
if ( !mContainer->getMaxWidthEq().empty() && totW > mContainer->getMaxSizePx().getWidth() )
mContainer->setClipType( ClipType::ContentBox );
} else if ( mContainer->getLayoutWidthPolicy() == SizePolicy::Fixed &&
mContainer->getUIStyle() ) {
const StyleSheetProperty* wprop =
mContainer->getUIStyle()->getProperty( PropertyId::Width );
if ( wprop && StyleSheetLength::isPercentage( wprop->value() ) && mContainer->getParent() &&
mContainer->getParent()->isWidget() &&
mContainer->getParent()->asType<UIWidget>()->getLayoutWidthPolicy() ==
SizePolicy::WrapContent ) {
totW = rt->getSize().getWidth() + mContainer->getPixelsContentOffset().Left +
mContainer->getPixelsContentOffset().Right;
if ( !mContainer->getMaxWidthEq().empty() &&
totW > mContainer->getMaxSizePx().getWidth() )
mContainer->setClipType( ClipType::ContentBox );
}
}
if ( totW != mContainer->getPixelsSize().getWidth() ||
@@ -93,6 +113,20 @@ void BlockLayouter::updateLayout() {
if ( !mContainer->getMaxHeightEq().empty() &&
totH > mContainer->getMaxSizePx().getHeight() )
mContainer->setClipType( ClipType::ContentBox );
} else if ( mContainer->getLayoutHeightPolicy() == SizePolicy::Fixed &&
mContainer->getUIStyle() ) {
const StyleSheetProperty* hprop =
mContainer->getUIStyle()->getProperty( PropertyId::Height );
if ( hprop && StyleSheetLength::isPercentage( hprop->value() ) && mContainer->getParent() &&
mContainer->getParent()->isWidget() &&
mContainer->getParent()->asType<UIWidget>()->getLayoutHeightPolicy() ==
SizePolicy::WrapContent ) {
totH = rt->getSize().getHeight() + mContainer->getPixelsContentOffset().Top +
mContainer->getPixelsContentOffset().Bottom;
if ( !mContainer->getMaxHeightEq().empty() &&
totH > mContainer->getMaxSizePx().getHeight() )
mContainer->setClipType( ClipType::ContentBox );
}
}
if ( totH != mContainer->getPixelsSize().getHeight() ||

View File

@@ -188,6 +188,10 @@ bool StyleSheetLength::isLength( const std::string& unitStr ) {
return false;
}
bool StyleSheetLength::isPercentage( const std::string& val ) {
return !val.empty() && val.back() == '%';
}
StyleSheetLength::StyleSheetLength() : mUnit( Px ), mValue( 0 ) {}
StyleSheetLength::StyleSheetLength( const Float& val, const StyleSheetLength::Unit& unit ) :

View File

@@ -272,9 +272,11 @@ void TableLayouter::computeIntrinsicWidths() {
}
mMinIntrinsicWidth = totalMin + mContainer->getPixelsContentOffset().Left +
mContainer->getPixelsContentOffset().Right + ( maxCols + 1 ) * mCellspacing;
mContainer->getPixelsContentOffset().Right +
( maxCols + 1 ) * mCellspacing;
mMaxIntrinsicWidth = totalMax + mContainer->getPixelsContentOffset().Left +
mContainer->getPixelsContentOffset().Right + ( maxCols + 1 ) * mCellspacing;
mContainer->getPixelsContentOffset().Right +
( maxCols + 1 ) * mCellspacing;
mIntrinsicWidthsDirty = false;
}
@@ -297,8 +299,36 @@ void TableLayouter::updateLayout() {
{ widget->lengthFromValue( *prop ), widget->getPixelsSize().getHeight() } );
}
if ( widget->getLayoutHeightPolicy() == SizePolicy::Fixed && widget->getUIStyle() &&
( prop = widget->getUIStyle()->getProperty( PropertyId::Height ) ) ) {
widget->asType<UINode>()->setInternalPixelsSize(
{ widget->getPixelsSize().getWidth(), widget->lengthFromValue( *prop ) } );
}
computeIntrinsicWidths();
bool useContentWidth = false;
if ( widget->getLayoutWidthPolicy() == SizePolicy::Fixed && widget->getUIStyle() ) {
const StyleSheetProperty* wprop = widget->getUIStyle()->getProperty( PropertyId::Width );
if ( wprop && StyleSheetLength::isPercentage( wprop->value() ) && widget->getParent() &&
widget->getParent()->isWidget() &&
widget->getParent()->asType<UIWidget>()->getLayoutWidthPolicy() ==
SizePolicy::WrapContent ) {
useContentWidth = true;
}
}
bool useContentHeight = false;
if ( widget->getLayoutHeightPolicy() == SizePolicy::Fixed && widget->getUIStyle() ) {
const StyleSheetProperty* hprop = widget->getUIStyle()->getProperty( PropertyId::Height );
if ( hprop && StyleSheetLength::isPercentage( hprop->value() ) && widget->getParent() &&
widget->getParent()->isWidget() &&
widget->getParent()->asType<UIWidget>()->getLayoutHeightPolicy() ==
SizePolicy::WrapContent ) {
useContentHeight = true;
}
}
if ( mRows.empty() ) {
mPacking = false;
return;
@@ -306,8 +336,11 @@ void TableLayouter::updateLayout() {
size_t maxCols = mColMinWidths.size();
mColWidths.assign( maxCols, 0.f );
Float paddingH = mContainer->getPixelsContentOffset().Left + mContainer->getPixelsContentOffset().Right;
Float paddingH =
mContainer->getPixelsContentOffset().Left + mContainer->getPixelsContentOffset().Right;
Float containerWidth = mContainer->getPixelsSize().getWidth();
if ( useContentWidth )
containerWidth = mMaxIntrinsicWidth;
Float availableWidth = sanitizeFloat(
std::max( 0.f, containerWidth - paddingH - ( maxCols + 1 ) * mCellspacing ) );
@@ -523,12 +556,15 @@ void TableLayouter::updateLayout() {
if ( mFooter && !mRows.empty() )
mRows[rowCount - 1]->setPixelsPosition( mContainer->getPixelsContentOffset().Left, 0 );
if ( mContainer->getLayoutHeightPolicy() == SizePolicy::WrapContent ) {
if ( mContainer->getLayoutHeightPolicy() == SizePolicy::WrapContent || useContentHeight ) {
mContainer->asType<UINode>()->setInternalPixelsHeight(
mContainer->getPixelsContentOffset().Top + headHeight + bodyHeight + footerHeight +
( rowCount + 1 ) * mCellspacing + mContainer->getPixelsContentOffset().Bottom );
}
if ( useContentWidth )
widget->asType<UINode>()->setInternalPixelsWidth( mMaxIntrinsicWidth );
mPacking = false;
}

View File

@@ -1947,22 +1947,14 @@ bool UIWidget::applyProperty( const StyleSheetProperty& attribute ) {
if ( attribute.value() == "auto" ) {
setLayoutHeightPolicy( SizePolicy::WrapContent );
} else {
StyleSheetLength length( attribute.value() );
if ( length.getUnit() == StyleSheetLength::Unit::Percentage && getParent() &&
getParent()->isWidget() &&
getParent()->asType<UIWidget>()->getLayoutHeightPolicy() ==
SizePolicy::WrapContent ) {
setLayoutHeightPolicy( SizePolicy::WrapContent );
} else {
if ( mStyle ) {
mStyle->setStyleSheetProperty(
StyleSheetProperty( "layout-height", attribute.value(), true,
StyleSheetSelectorRule::SpecificityImportant ) );
}
setLayoutHeightPolicy( SizePolicy::Fixed );
setSize( mDpSize.getWidth(), eefloor( lengthFromValueAsDp( attribute ) ) );
notifyLayoutAttrChange();
if ( mStyle ) {
mStyle->setStyleSheetProperty(
StyleSheetProperty( "layout-height", attribute.value(), true,
StyleSheetSelectorRule::SpecificityImportant ) );
}
setLayoutHeightPolicy( SizePolicy::Fixed );
setSize( mDpSize.getWidth(), eefloor( lengthFromValueAsDp( attribute ) ) );
notifyLayoutAttrChange();
}
break;
case PropertyId::BackgroundColor:
@@ -2210,21 +2202,13 @@ bool UIWidget::applyProperty( const StyleSheetProperty& attribute ) {
setLayoutHeightPolicy( SizePolicy::Fixed );
unsetFlags( UI_AUTO_SIZE );
} else {
StyleSheetLength length( val, 0 );
if ( length.getUnit() == StyleSheetLength::Unit::Percentage && getParent() &&
getParent()->isWidget() &&
getParent()->asType<UIWidget>()->getLayoutHeightPolicy() ==
SizePolicy::WrapContent ) {
setLayoutHeightPolicy( SizePolicy::WrapContent );
} else {
unsetFlags( UI_AUTO_SIZE );
setLayoutHeightPolicy( SizePolicy::Fixed );
Float newVal = eefloor( lengthFromValueAsDp( attribute ) );
if ( !( newVal == 0 && getLayoutWeight() != 0 &&
getParent()->isType( UI_TYPE_LINEAR_LAYOUT ) ) ) {
setInternalHeight( newVal );
onSizeChange();
}
unsetFlags( UI_AUTO_SIZE );
setLayoutHeightPolicy( SizePolicy::Fixed );
Float newVal = eefloor( lengthFromValueAsDp( attribute ) );
if ( !( newVal == 0 && getLayoutWeight() != 0 &&
getParent()->isType( UI_TYPE_LINEAR_LAYOUT ) ) ) {
setInternalHeight( newVal );
onSizeChange();
}
}
break;