Fix UIRichText children sizing, take into account padding.

This commit is contained in:
Martín Lucas Golini
2026-04-06 02:39:14 -03:00
parent 535353dd02
commit dbde511d99
4 changed files with 125 additions and 10 deletions

View File

@@ -377,7 +377,7 @@
"working_dir": "${project_root}/bin"
},
{
"args": "",
"args": "-c system --hn-dark",
"command": "${project_root}/bin/eepp-ui-html-debug",
"name": "eepp-ui-html-debug",
"working_dir": "${project_root}/bin"

View File

@@ -478,11 +478,12 @@ void UIRichText::rebuildRichText( RichText& richText, IntrinsicMode mode ) {
Float maxWidth = mSize.getWidth() - mPaddingPx.Left - mPaddingPx.Right;
if ( maxWidth < 0 )
maxWidth = 0;
Float mw = 0.f;
if ( !mMaxWidthEq.empty() ) {
mw = getMaxSizePx().getWidth() - mPaddingPx.Left - mPaddingPx.Right;
if ( mw < 0 ) mw = 0.f;
if ( mw < 0 )
mw = 0.f;
}
if ( mWidthPolicy == SizePolicy::WrapContent || mode != IntrinsicMode::None ) {
@@ -521,7 +522,9 @@ void UIRichText::rebuildRichText( RichText& richText, IntrinsicMode mode ) {
if ( mode == IntrinsicMode::None ) {
if ( widget->getLayoutWidthPolicy() == SizePolicy::MatchParent ) {
if ( mSize.getWidth() != 0 ) {
widget->setPixelsSize( mSize.getWidth() - margin.Left - margin.Right,
widget->setPixelsSize( eemax( 0.f, mSize.getWidth() - mPaddingPx.Left -
mPaddingPx.Right - margin.Left -
margin.Right ),
widget->getPixelsSize().getHeight() );
} else {
onAutoSizeChild( widget );
@@ -661,7 +664,8 @@ void UIRichText::positionChildren() {
pos.y += widget->getPrevNode()->getPixelsSize().getHeight();
}
widget->setPixelsPosition( pos );
widget->setPixelsSize( { mSize.getWidth(), 0 } );
widget->setPixelsSize(
{ eemax( 0.f, mSize.getWidth() - mPaddingPx.Left - mPaddingPx.Right ), 0 } );
} else {
curCharIdx += 1;
const auto* span = getNextCustomSpan();

View File

@@ -1,6 +1,33 @@
#include <eepp/ee.hpp>
EE_MAIN_FUNC int main( int, char** ) {
#include <args/args.hxx>
#include <iostream>
EE_MAIN_FUNC int main( int argc, char** argv ) {
args::ArgumentParser parser( "eepp HTML Example" );
args::HelpFlag help( parser, "help", "Display this help menu", { 'h', "help" } );
args::Flag hnDark( parser, "hn-dark",
"Force a custom CSS style for Hacker News site to be dark.", { "hn-dark" } );
args::ValueFlag<std::string> prefersColorScheme(
parser, "prefers-color-scheme",
"Set the preferred color scheme (\"light\", \"dark\" or \"system\")",
{ 'c', "prefers-color-scheme" } );
try {
parser.ParseCLI( Sys::parseArguments( argc, argv ) );
} catch ( const args::Help& ) {
std::cout << parser;
return EXIT_SUCCESS;
} catch ( const args::ParseError& e ) {
std::cerr << e.what() << std::endl;
std::cerr << parser;
return EXIT_FAILURE;
} catch ( args::ValidationError& e ) {
std::cerr << e.what() << std::endl;
std::cerr << parser;
return EXIT_FAILURE;
}
UIApplication app( { 1280, 720, "eepp - UI HTML Example" } );
Log::instance()->setLogLevelThreshold( LogLevel::Debug );
@@ -19,7 +46,12 @@ EE_MAIN_FUNC int main( int, char** ) {
ui->getUIIconThemeManager()->setCurrentTheme(
IconManager::init( "icons", remixIconFont, noniconsFont, codIconFont ) );
ui->setColorSchemePreference( ColorSchemeExtPreference::Light );
ui->setColorSchemePreference(
!prefersColorScheme.Get().empty()
? ColorSchemePreferences::fromStringExt( prefersColorScheme.Get() )
: ColorSchemeExtPreference::Light );
bool useHNDark = hnDark.Get();
ui->loadLayoutFromString( R"xml(
<vbox layout_width="match_parent" layout_height="match_parent">
@@ -48,11 +80,11 @@ EE_MAIN_FUNC int main( int, char** ) {
fwdBtn->setEnabled( historyIndex < static_cast<int>( history.size() ) - 1 );
};
const auto loadDocumentData = [ui, mainContainer, urlBar, &app,
scrollView]( URI url, std::string& data ) {
const auto loadDocumentData = [ui, mainContainer, urlBar, &app, scrollView,
useHNDark]( URI url, std::string& data ) {
if ( data.empty() )
return;
ui->ensureMainThread( [url, data, mainContainer, urlBar, ui, &app, scrollView] {
ui->ensureMainThread( [url, data, mainContainer, urlBar, ui, &app, scrollView, useHNDark] {
mainContainer->closeAllChildren();
ui->getStyleSheet().removeAllWithoutMarker( app.getStyleSheetDefaultMarker() );
ui->setURIFromURL( url );
@@ -61,6 +93,44 @@ EE_MAIN_FUNC int main( int, char** ) {
scrollView->getVerticalScrollBar()->setValue( 0 );
ui->loadLayoutFromString( HTMLFormatter::HTMLtoXML( data ), mainContainer, hash );
urlBar->setText( urlStr );
if ( useHNDark && url.getAuthority() == "news.ycombinator.com" ) {
static const std::string_view HN_DARK = R"css(
body * {
color: #dcdccc !important;
}
body,
#hnmain,
.pagetop {
background-color: #404040 !important;
}
body > center > table > tbody > tr:first-child * {
background-color: #505050 !important;
}
body > center > table > tbody > tr:first-child * a:hover {
background: #404040 !important;
}
body code, body pre, body input, body textarea {
background: #505050 !important;
}
body a {
color: #7F9F7F !important;
}
body .subtext a {
color: #dcdccc !important;
}
body a:visited, body a:visited span {
color: #CC9393 !important;
}
body a:hover, body a:hover span {
background: #505050 !important;
}
)css";
StyleSheetParser parser;
if ( parser.loadFromString( HN_DARK ) )
ui->getStyleSheet().combineStyleSheet( parser.getStyleSheet() );
}
} );
};

View File

@@ -1111,6 +1111,47 @@ UTEST( UIRichText, MinMaxWidthChildren ) {
Engine::destroySingleton();
}
UTEST( UIRichText, MatchParentChildPadding ) {
Engine::instance()->createWindow( WindowSettings( 800, 600, "RichText MatchParent Child Padding Test",
WindowStyle::Default, WindowBackend::Default,
32, {}, 1, false, true ) );
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
ASSERT_TRUE( font->loaded() );
FontFamily::loadFromRegular( font );
UI::UISceneNode* sceneNode = UI::UISceneNode::New();
UI::UIThemeManager* themeManager = sceneNode->getUIThemeManager();
themeManager->setDefaultFont( font );
String xml = R"xml(
<LinearLayout id="container" layout_width="match_parent" layout_height="match_parent">
<RichText id="rt_parent" layout_width="200dp" layout_height="wrap_content" padding="10dp">
<Widget id="child_widget" layout_width="match_parent" layout_height="50dp" />
</RichText>
</LinearLayout>
)xml";
sceneNode->loadLayoutFromString( xml );
UI::UIRichText* rtParent = sceneNode->find<UI::UIRichText>( "rt_parent" );
UI::UIWidget* childWidget = sceneNode->find<UI::UIWidget>( "child_widget" );
ASSERT_TRUE( rtParent != nullptr );
ASSERT_TRUE( childWidget != nullptr );
sceneNode->update( Time::Zero );
Float parentWidth = rtParent->getSize().getWidth();
Float childWidth = childWidget->getSize().getWidth();
Float expectedChildWidth = parentWidth - PixelDensity::dpToPx( 20 );
EXPECT_EQ( childWidth, expectedChildWidth );
eeDelete( sceneNode );
Engine::destroySingleton();
}
UTEST( UILayout, MinMaxWidthChildren ) {
Engine::instance()->createWindow( WindowSettings( 800, 600, "Layout Min/Max Width Children Test",
WindowStyle::Default, WindowBackend::Default,