Several HTML widgets fixes.

This commit is contained in:
Martín Lucas Golini
2026-04-29 14:07:56 -03:00
parent 4ab9942e37
commit 04d69e2871
9 changed files with 140 additions and 55 deletions

View File

@@ -230,10 +230,10 @@ enum class PropertyId : Uint32 {
DisplayOptions = String::hash( "display-options" ),
MenuWidthMode = String::hash( "menu-width-mode" ),
ExpandText = String::hash( "expand-text" ),
Colspan = String::hash( "colspan" ),
ColSpan = String::hash( "colspan" ),
TableLayout = String::hash( "table-layout" ),
Cellpadding = String::hash( "cellpadding" ),
Cellspacing = String::hash( "cellspacing" ),
CellPadding = String::hash( "cellpadding" ),
CellSpacing = String::hash( "cellspacing" ),
Size = String::hash( "size" ),
Type = String::hash( "type" ),
Rows = String::hash( "rows" ),

View File

@@ -1,8 +1,8 @@
#ifndef EE_UI_TABLELAYOUTER_HPP
#define EE_UI_TABLELAYOUTER_HPP
#include <eepp/ui/uilayouter.hpp>
#include <eepp/core/small_vector.hpp>
#include <eepp/ui/uilayouter.hpp>
namespace EE { namespace UI {
@@ -17,17 +17,25 @@ enum class TableLayout { Auto, Fixed };
class EE_API TableLayouter : public UILayouter {
public:
TableLayouter( UIWidget* container ) : UILayouter( container ) {}
void updateLayout() override;
void computeIntrinsicWidths() override;
void setTableLayout( TableLayout layout );
TableLayout getTableLayout() const;
void setCellpadding( Float padding );
Float getCellpadding() const;
void setCellspacing( Float spacing );
Float getCellspacing() const;
void setCellPadding( Float padding );
Float getCellPadding() const;
void setCellSpacing( Float spacing );
Float getCellSpacing() const;
Float getMinIntrinsicWidth() override;
Float getMaxIntrinsicWidth() override;
protected:

View File

@@ -22,6 +22,11 @@ class EE_API UIHTMLTable : public UIHTMLWidget {
virtual Float getMaxIntrinsicWidth() const;
virtual std::vector<PropertyId> getPropertiesImplemented() const;
virtual std::string getPropertyString( const PropertyDefinition* propertyDef,
const Uint32& state = 0 ) const;
virtual bool applyProperty( const StyleSheetProperty& attribute );
protected:
@@ -43,14 +48,19 @@ class EE_API UIHTMLTableCell : public UIRichText {
virtual bool isType( const Uint32& type ) const;
virtual std::vector<PropertyId> getPropertiesImplemented() const;
virtual std::string getPropertyString( const PropertyDefinition* propertyDef,
const Uint32& state = 0 ) const;
virtual bool applyProperty( const StyleSheetProperty& attribute );
Uint32 getColspan() const;
Uint32 getColSpan() const;
virtual void onSizeChange();
protected:
Uint32 mColspan{ 1 };
Uint32 mColSpan{ 1 };
};
class EE_API UIHTMLTableRow : public UIHTMLWidget {

View File

@@ -42,8 +42,11 @@ class EE_API UIHTMLWidget : public UILayout {
int getZIndex() const { return mZIndex; }
void setZIndex( int zIndex );
virtual std::vector<PropertyId> getPropertiesImplemented() const;
virtual std::string getPropertyString( const PropertyDefinition* propertyDef,
const Uint32& state = 0 ) const;
virtual bool applyProperty( const StyleSheetProperty& attribute );
virtual void updateLayout();

View File

@@ -18,19 +18,19 @@ TableLayout TableLayouter::getTableLayout() const {
return mTableLayout;
}
void TableLayouter::setCellpadding( Float padding ) {
void TableLayouter::setCellPadding( Float padding ) {
mCellpadding = padding;
}
Float TableLayouter::getCellpadding() const {
Float TableLayouter::getCellPadding() const {
return mCellpadding;
}
void TableLayouter::setCellspacing( Float spacing ) {
void TableLayouter::setCellSpacing( Float spacing ) {
mCellspacing = spacing;
}
Float TableLayouter::getCellspacing() const {
Float TableLayouter::getCellSpacing() const {
return mCellspacing;
}
@@ -102,7 +102,7 @@ void TableLayouter::computeIntrinsicWidths() {
if ( child->getType() == UI_TYPE_HTML_TABLE_CELL ) {
auto* cell = child->asType<UIHTMLTableCell>();
mCells.push_back( cell );
colCount += cell->getColspan();
colCount += cell->getColSpan();
if ( mCellpadding > 0 && cell->getPadding() == Rectf::Zero ) {
cell->setPadding( { mCellpadding, mCellpadding, mCellpadding, mCellpadding } );
}
@@ -135,7 +135,7 @@ void TableLayouter::computeIntrinsicWidths() {
Float cellSpecified = sanitizeFloat(
std::max( cell->getPropertyWidth(),
getRecursiveSpecifiedWidth( getRecursiveSpecifiedWidth, cell ) ) );
Uint32 colspan = cell->getColspan();
Uint32 colspan = cell->getColSpan();
if ( colspan == 1 && colIndex < maxCols ) {
if ( cellSpecified > 0.f ) {
@@ -153,7 +153,7 @@ void TableLayouter::computeIntrinsicWidths() {
Float cellSpecified = sanitizeFloat(
std::max( cell->getPropertyWidth(),
getRecursiveSpecifiedWidth( getRecursiveSpecifiedWidth, cell ) ) );
Uint32 colspan = cell->getColspan();
Uint32 colspan = cell->getColSpan();
if ( colspan > 1 && cellSpecified > 0.f ) {
Float curSpec = 0.f;
@@ -188,7 +188,7 @@ void TableLayouter::computeIntrinsicWidths() {
getRecursiveSpecifiedWidth( getRecursiveSpecifiedWidth, cell ) ) );
cell->mWidthPolicy = widthPolicy;
Uint32 colspan = cell->getColspan();
Uint32 colspan = cell->getColSpan();
if ( colspan == 1 && colIndex < maxCols ) {
mColMinWidths[colIndex] = std::max( mColMinWidths[colIndex], cellMin );
@@ -219,7 +219,7 @@ void TableLayouter::computeIntrinsicWidths() {
getRecursiveSpecifiedWidth( getRecursiveSpecifiedWidth, cell ) ) );
cell->mWidthPolicy = widthPolicy;
Uint32 colspan = cell->getColspan();
Uint32 colspan = cell->getColSpan();
if ( colspan > 1 ) {
// Min excess
@@ -448,7 +448,7 @@ void TableLayouter::updateLayout() {
cell->beginAttributesTransaction();
cell->setLayoutWidthPolicy( SizePolicy::Fixed );
cell->setLayoutHeightPolicy( SizePolicy::WrapContent );
Uint32 cellColspan = cell->getColspan();
Uint32 cellColspan = cell->getColSpan();
Float cellWidth = 0;
for ( Uint32 j = 0; j < cellColspan && ( colIndex + j ) < maxCols; ++j ) {
cellWidth += mColWidths[colIndex + j];
@@ -469,7 +469,7 @@ void TableLayouter::updateLayout() {
UIHTMLTableCell* cell = mCells[start + c];
cell->beginAttributesTransaction();
cell->setPixelsPosition( currentX, 0 );
Uint32 cellColspan = cell->getColspan();
Uint32 cellColspan = cell->getColSpan();
Float cellWidth = 0;
for ( Uint32 j = 0; j < cellColspan && ( colIndex + j ) < maxCols; ++j ) {
cellWidth += mColWidths[colIndex + j];

View File

@@ -24,23 +24,59 @@ bool UIHTMLTable::isType( const Uint32& type ) const {
return UIHTMLTable::getType() == type || UIHTMLWidget::isType( type );
}
std::vector<PropertyId> UIHTMLTable::getPropertiesImplemented() const {
auto props = UIHTMLWidget::getPropertiesImplemented();
auto local = { PropertyId::CellSpacing, PropertyId::CellPadding, PropertyId::TableLayout };
props.insert( props.end(), local.begin(), local.end() );
return props;
}
std::string UIHTMLTable::getPropertyString( const PropertyDefinition* propertyDef,
const Uint32& state ) const {
if ( NULL == propertyDef )
return "";
switch ( propertyDef->getPropertyId() ) {
case PropertyId::CellSpacing:
if ( const_cast<UIHTMLTable*>( this )->getLayouter() &&
mDisplay == CSSDisplay::Table ) {
return String::fromFloat(
static_cast<TableLayouter*>( const_cast<UIHTMLTable*>( this )->getLayouter() )
->getCellSpacing() );
}
return "";
case PropertyId::CellPadding:
if ( const_cast<UIHTMLTable*>( this )->getLayouter() &&
mDisplay == CSSDisplay::Table ) {
return String::fromFloat(
static_cast<TableLayouter*>( const_cast<UIHTMLTable*>( this )->getLayouter() )
->getCellPadding() );
}
return "";
case PropertyId::TableLayout:
return mTopEq;
default:
return UIHTMLWidget::getPropertyString( propertyDef );
}
}
bool UIHTMLTable::applyProperty( const StyleSheetProperty& attribute ) {
if ( attribute.getPropertyDefinition() == nullptr )
return false;
switch ( attribute.getPropertyDefinition()->getPropertyId() ) {
case PropertyId::Cellspacing:
if ( const_cast<UIHTMLTable*>( this )->getLayouter() ) {
static_cast<TableLayouter*>( const_cast<UIHTMLTable*>( this )->getLayouter() )
->setCellspacing( lengthFromValue( attribute ) );
case PropertyId::CellSpacing:
if ( getLayouter() && mDisplay == CSSDisplay::Table ) {
static_cast<TableLayouter*>( getLayouter() )
->setCellSpacing( lengthFromValue( attribute ) );
invalidateIntrinsicSize();
tryUpdateLayout();
}
return true;
case PropertyId::Cellpadding:
if ( const_cast<UIHTMLTable*>( this )->getLayouter() ) {
static_cast<TableLayouter*>( const_cast<UIHTMLTable*>( this )->getLayouter() )
->setCellpadding( lengthFromValue( attribute ) );
case PropertyId::CellPadding:
if ( getLayouter() && mDisplay == CSSDisplay::Table ) {
static_cast<TableLayouter*>( getLayouter() )
->setCellPadding( lengthFromValue( attribute ) );
invalidateIntrinsicSize();
tryUpdateLayout();
}
@@ -48,8 +84,8 @@ bool UIHTMLTable::applyProperty( const StyleSheetProperty& attribute ) {
case PropertyId::TableLayout: {
std::string val = attribute.asString();
String::toLowerInPlace( val );
if ( const_cast<UIHTMLTable*>( this )->getLayouter() ) {
static_cast<TableLayouter*>( const_cast<UIHTMLTable*>( this )->getLayouter() )
if ( getLayouter() && mDisplay == CSSDisplay::Table ) {
static_cast<TableLayouter*>( getLayouter() )
->setTableLayout( val == "fixed" ? TableLayout::Fixed : TableLayout::Auto );
invalidateIntrinsicSize();
tryUpdateLayout();
@@ -137,15 +173,35 @@ bool UIHTMLTableCell::isType( const Uint32& type ) const {
return UIHTMLTableCell::getType() == type || UIRichText::isType( type );
}
std::vector<PropertyId> UIHTMLTableCell::getPropertiesImplemented() const {
auto props = UIHTMLWidget::getPropertiesImplemented();
auto local = { PropertyId::ColSpan };
props.insert( props.end(), local.begin(), local.end() );
return props;
}
std::string UIHTMLTableCell::getPropertyString( const PropertyDefinition* propertyDef,
const Uint32& state ) const {
if ( NULL == propertyDef )
return "";
switch ( propertyDef->getPropertyId() ) {
case PropertyId::ColSpan:
return String::format( "%lld", mColSpan );
default:
return UIHTMLWidget::getPropertyString( propertyDef );
}
}
bool UIHTMLTableCell::applyProperty( const StyleSheetProperty& attribute ) {
if ( attribute.getPropertyDefinition() == nullptr )
return false;
switch ( attribute.getPropertyDefinition()->getPropertyId() ) {
case PropertyId::Colspan: {
mColspan = attribute.asUint( 1 );
if ( mColspan == 0 )
mColspan = 1;
case PropertyId::ColSpan: {
mColSpan = attribute.asUint( 1 );
if ( mColSpan == 0 )
mColSpan = 1;
notifyLayoutAttrChangeParent();
return true;
}
@@ -155,8 +211,8 @@ bool UIHTMLTableCell::applyProperty( const StyleSheetProperty& attribute ) {
return UIRichText::applyProperty( attribute );
}
Uint32 UIHTMLTableCell::getColspan() const {
return mColspan;
Uint32 UIHTMLTableCell::getColSpan() const {
return mColSpan;
}
void UIHTMLTableCell::onSizeChange() {

View File

@@ -72,6 +72,14 @@ void UIHTMLWidget::setZIndex( int zIndex ) {
mZIndex = zIndex;
}
std::vector<PropertyId> UIHTMLWidget::getPropertiesImplemented() const {
auto props = UILayout::getPropertiesImplemented();
auto local = { PropertyId::Display, PropertyId::Position, PropertyId::Top, PropertyId::Right,
PropertyId::Bottom, PropertyId::Left, PropertyId::ZIndex };
props.insert( props.end(), local.begin(), local.end() );
return props;
}
std::string UIHTMLWidget::getPropertyString( const PropertyDefinition* propertyDef,
const Uint32& state ) const {
if ( NULL == propertyDef )

View File

@@ -313,7 +313,7 @@ std::string UIRichText::getPropertyString( const PropertyDefinition* propertyDef
}
std::vector<PropertyId> UIRichText::getPropertiesImplemented() const {
auto props = UILayout::getPropertiesImplemented();
auto props = UIHTMLWidget::getPropertiesImplemented();
auto local = { PropertyId::FontFamily, PropertyId::FontSize,
PropertyId::FontStyle, PropertyId::Color,
PropertyId::BackgroundColor, PropertyId::TextShadowColor,
@@ -554,19 +554,19 @@ void UIRichText::loadFromXmlNode( const pugi::xml_node& node ) {
}
void UIRichText::onSizeChange() {
UILayout::onSizeChange();
UIHTMLWidget::onSizeChange();
notifyLayoutAttrChange();
notifyLayoutAttrChangeParent();
}
void UIRichText::onPaddingChange() {
UILayout::onPaddingChange();
UIHTMLWidget::onPaddingChange();
notifyLayoutAttrChange();
notifyLayoutAttrChangeParent();
}
void UIRichText::onChildCountChange( Node* child, const bool& removed ) {
UILayout::onChildCountChange( child, removed );
UIHTMLWidget::onChildCountChange( child, removed );
if ( !removed && child->isWidget() && child->isType( UI_TYPE_TEXTSPAN ) ) {
static_cast<UITextSpan*>( child )->setInheritedStyle( mRichText.getFontStyleConfig() );
}
@@ -586,7 +586,7 @@ void UIRichText::onFontStyleChanged() {
}
void UIRichText::onAlphaChange() {
UILayout::onAlphaChange();
UIHTMLWidget::onAlphaChange();
}
void UIRichText::rebuildRichText( UILayout* container, RichText& richText, IntrinsicMode mode ) {
@@ -868,7 +868,7 @@ Uint32 UIRichText::onMouseDown( const Vector2i& position, const Uint32& flags )
mSelecting = true;
}
return UILayout::onMouseDown( position, flags );
return UIHTMLWidget::onMouseDown( position, flags );
}
Uint32 UIRichText::onMouseUp( const Vector2i& position, const Uint32& flags ) {
@@ -876,15 +876,15 @@ Uint32 UIRichText::onMouseUp( const Vector2i& position, const Uint32& flags ) {
mSelecting = false;
}
return UILayout::onMouseClick( position, flags );
return UIHTMLWidget::onMouseClick( position, flags );
}
Uint32 UIRichText::onMouseDoubleClick( const Vector2i& position, const Uint32& flags ) {
return UILayout::onMouseDoubleClick( position, flags );
return UIHTMLWidget::onMouseDoubleClick( position, flags );
}
Uint32 UIRichText::onFocusLoss() {
UILayout::onFocusLoss();
UIHTMLWidget::onFocusLoss();
selCurEnd( selCurInit() );
onSelectionChange();

View File

@@ -48,7 +48,7 @@ Uint32 UITextSpan::getType() const {
}
bool UITextSpan::isType( const Uint32& type ) const {
return UITextSpan::getType() == type ? true : UIWidget::isType( type );
return UITextSpan::getType() == type ? true : UIHTMLWidget::isType( type );
}
void UITextSpan::drawBorder() {
@@ -109,7 +109,7 @@ bool UITextSpan::applyProperty( const StyleSheetProperty& attribute ) {
setTextDecoration( attribute.asTextDecoration() );
break;
default:
return UIWidget::applyProperty( attribute );
return UIHTMLWidget::applyProperty( attribute );
}
return true;
@@ -145,12 +145,12 @@ std::string UITextSpan::getPropertyString( const PropertyDefinition* propertyDef
case PropertyId::TextDecoration:
return Text::styleFlagToString( getTextDecoration() );
default:
return UIWidget::getPropertyString( propertyDef, propertyIndex );
return UIHTMLWidget::getPropertyString( propertyDef, propertyIndex );
}
}
std::vector<PropertyId> UITextSpan::getPropertiesImplemented() const {
auto props = UIWidget::getPropertiesImplemented();
auto props = UIHTMLWidget::getPropertiesImplemented();
auto local = { PropertyId::Text,
PropertyId::FontFamily,
PropertyId::FontSize,
@@ -336,7 +336,7 @@ UITextSpan* UITextSpan::setFontShadowOffset( const Vector2f& offset ) {
}
void UITextSpan::onAlphaChange() {
UIWidget::onAlphaChange();
UIHTMLWidget::onAlphaChange();
notifyLayoutAttrChange();
}
@@ -357,7 +357,7 @@ void UITextSpan::onTextChanged() {
}
void UITextSpan::onChildCountChange( Node* child, const bool& removed ) {
UIWidget::onChildCountChange( child, removed );
UIHTMLWidget::onChildCountChange( child, removed );
if ( !removed && child->isWidget() && child->isType( UI_TYPE_TEXTSPAN ) ) {
static_cast<UITextSpan*>( child )->setInheritedStyle( mFontStyleConfig );
}
@@ -372,13 +372,13 @@ Uint32 UITextSpan::onMessage( const NodeMessage* Msg ) {
return 1;
}
}
return UIWidget::onMessage( Msg );
return UIHTMLWidget::onMessage( Msg );
}
void UITextSpan::loadFromXmlNode( const pugi::xml_node& node ) {
beginAttributesTransaction();
UIWidget::loadFromXmlNode( node );
UIHTMLWidget::loadFromXmlNode( node );
bool hasElements = false;
for ( pugi::xml_node child = node.first_child(); child; child = child.next_sibling() ) {
@@ -632,7 +632,7 @@ Uint32 UIAnchorSpan::onKeyDown( const KeyEvent& event ) {
}
}
return UIWidget::onKeyDown( event );
return UITextSpan::onKeyDown( event );
}
std::string UIAnchorSpan::getPropertyString( const PropertyDefinition* propertyDef,