QskSubcontrolLayoutEngine improved

This commit is contained in:
Uwe Rathmann 2022-08-29 15:02:43 +02:00
parent 45e157c2c6
commit df5eb382f9
2 changed files with 52 additions and 42 deletions

View File

@ -276,10 +276,11 @@ class QskSubcontrolLayoutEngine::PrivateData
PrivateData( Qt::Orientation orientation ) PrivateData( Qt::Orientation orientation )
: orientation( orientation ) : orientation( orientation )
{ {
elements.reserve( 2 ); // often Graphic + Text
} }
Qt::Orientation orientation; Qt::Orientation orientation;
LayoutElement* elements[2] = {}; QVector< LayoutElement* > elements;
}; };
QskSubcontrolLayoutEngine::QskSubcontrolLayoutEngine( Qt::Orientation orientation ) QskSubcontrolLayoutEngine::QskSubcontrolLayoutEngine( Qt::Orientation orientation )
@ -290,8 +291,7 @@ QskSubcontrolLayoutEngine::QskSubcontrolLayoutEngine( Qt::Orientation orientatio
QskSubcontrolLayoutEngine::~QskSubcontrolLayoutEngine() QskSubcontrolLayoutEngine::~QskSubcontrolLayoutEngine()
{ {
for ( auto element : m_data->elements ) qDeleteAll( m_data->elements );
delete element;
} }
bool QskSubcontrolLayoutEngine::setOrientation( Qt::Orientation orientation ) bool QskSubcontrolLayoutEngine::setOrientation( Qt::Orientation orientation )
@ -326,24 +326,52 @@ void QskSubcontrolLayoutEngine::setGraphicTextElements( const QskSkinnable* skin
QskAspect::Subcontrol textSubcontrol, const QString& text, QskAspect::Subcontrol textSubcontrol, const QString& text,
QskAspect::Subcontrol graphicSubControl, const QSizeF& graphicSize ) QskAspect::Subcontrol graphicSubControl, const QSizeF& graphicSize )
{ {
const bool hasText = !text.isEmpty(); /*
const bool hasGraphic = !graphicSize.isEmpty(); QskSubcontrolLayoutEngine was initially created to support the
situation of an icon and a text, that can be found at several places
in conrols. This method supports to set up such a layout without
having to deal with the details of the layout classes.
*/
auto graphicElement = new GraphicElement( skinnable, graphicSubControl ); GraphicElement* graphicElement = nullptr;
graphicElement->setSourceSize( graphicSize ); if ( !graphicSize.isEmpty() && ( graphicSubControl != QskAspect::Control ) )
graphicElement->setIgnored( !hasGraphic ); {
graphicElement = dynamic_cast< GraphicElement * >( element( graphicSubControl ) );
if ( graphicElement == nullptr )
{
graphicElement = new GraphicElement( skinnable, graphicSubControl );
m_data->elements.prepend( graphicElement );
}
auto textElement = new TextElement( skinnable, textSubcontrol ); graphicElement->setSourceSize( graphicSize );
textElement->setText( text ); }
textElement->setIgnored( !hasText );
TextElement* textElement = nullptr;
if ( !text.isEmpty() && ( graphicSubControl != QskAspect::Control ) )
{
textElement = dynamic_cast< TextElement* >( element( textSubcontrol ) );
if ( textElement == nullptr )
{
textElement = new TextElement( skinnable, textSubcontrol );
m_data->elements.append( textElement );
}
textElement->setText( text );
}
/*
Now the difficult part: setting up size policies and the preferred size.
The code below is probably not the final word - let's see what type of
default settings we need most often. TODO ...
*/
using SP = QskSizePolicy; using SP = QskSizePolicy;
if ( hasText && !hasGraphic ) if ( textElement && graphicElement == nullptr )
{ {
textElement->setSizePolicy( SP::Preferred, SP::Constrained ); textElement->setSizePolicy( SP::Preferred, SP::Constrained );
} }
else if ( hasGraphic && !hasText ) else if ( graphicElement && textElement == nullptr )
{ {
const auto size = graphicElement->effectiveStrutSize(); const auto size = graphicElement->effectiveStrutSize();
@ -352,7 +380,7 @@ void QskSubcontrolLayoutEngine::setGraphicTextElements( const QskSkinnable* skin
else else
graphicElement->setSizePolicy( SP::Ignored, SP::ConstrainedExpanding ); graphicElement->setSizePolicy( SP::Ignored, SP::ConstrainedExpanding );
} }
else if ( hasText && hasGraphic ) else if ( textElement && graphicElement )
{ {
if ( orientation() == Qt::Horizontal ) if ( orientation() == Qt::Horizontal )
{ {
@ -377,18 +405,11 @@ void QskSubcontrolLayoutEngine::setGraphicTextElements( const QskSkinnable* skin
graphicElement->setPreferredSize( size ); graphicElement->setPreferredSize( size );
} }
setElementAt( 0, graphicElement );
setElementAt( 1, textElement );
} }
void QskSubcontrolLayoutEngine::setElementAt( int index, LayoutElement* element ) void QskSubcontrolLayoutEngine::addElement( LayoutElement* element )
{ {
if ( index >= 0 && index < count() ) m_data->elements += element;
{
delete m_data->elements[ index ];
m_data->elements[ index ] = element;
}
} }
QskSubcontrolLayoutEngine::LayoutElement* QskSubcontrolLayoutEngine::elementAt( int index ) const QskSubcontrolLayoutEngine::LayoutElement* QskSubcontrolLayoutEngine::elementAt( int index ) const
@ -432,24 +453,20 @@ void QskSubcontrolLayoutEngine::layoutItems()
int row = 0; int row = 0;
int col = 0; int col = 0;
int& index = m_data->orientation == Qt::Horizontal ? col : row;
for ( auto element : m_data->elements ) for ( auto element : m_data->elements )
{ {
if ( element && !element->isIgnored() ) const auto rect = geometryAt( element, QRect( col, row, 1, 1 ) );
{ element->setGeometry( rect );
const auto rect = geometryAt( element, QRect( col, row, 1, 1 ) );
element->setGeometry( rect );
if ( m_data->orientation == Qt::Horizontal ) index++;
col++;
else
row++;
}
} }
} }
int QskSubcontrolLayoutEngine::effectiveCount( Qt::Orientation orientation ) const int QskSubcontrolLayoutEngine::effectiveCount( Qt::Orientation orientation ) const
{ {
return ( orientation == m_data->orientation ) ? 2 : 1; return ( orientation == m_data->orientation ) ? m_data->elements.count() : 1;
} }
QRectF QskSubcontrolLayoutEngine::subControlRect( QskAspect::Subcontrol subControl ) const QRectF QskSubcontrolLayoutEngine::subControlRect( QskAspect::Subcontrol subControl ) const
@ -474,12 +491,9 @@ void QskSubcontrolLayoutEngine::setupChain( Qt::Orientation orientation,
for ( auto element : m_data->elements ) for ( auto element : m_data->elements )
{ {
if ( element == nullptr || element->isIgnored() )
continue;
qreal constraint = -1.0; qreal constraint = -1.0;
if ( !constraints.isEmpty() ) if ( !constraints.isEmpty() )
constraint = constraints[index1].length; constraint = constraints[ index1 ].length;
const auto cell = qskCell( element, orientation, isLayoutOrientation, constraint ); const auto cell = qskCell( element, orientation, isLayoutOrientation, constraint );
chain.expandCell( index2, cell ); chain.expandCell( index2, cell );

View File

@ -45,9 +45,6 @@ class QskSubcontrolLayoutEngine : public QskLayoutEngine2D
virtual Qt::Alignment alignment() const override; virtual Qt::Alignment alignment() const override;
inline void setIgnored( bool on ) { m_ignored = on; }
inline bool isIgnored() const { return m_ignored; }
inline void setStretch( int stretch ) { m_stretch = stretch; } inline void setStretch( int stretch ) { m_stretch = stretch; }
inline int stretch() const { return m_stretch; } inline int stretch() const { return m_stretch; }
@ -121,9 +118,8 @@ class QskSubcontrolLayoutEngine : public QskLayoutEngine2D
void setSpacing( qreal ); void setSpacing( qreal );
qreal spacing() const; qreal spacing() const;
void setElementAt( int index, LayoutElement* ); void addElement( LayoutElement* );
LayoutElement* elementAt( int ) const; LayoutElement* elementAt( int ) const;
LayoutElement* element( QskAspect::Subcontrol ) const; LayoutElement* element( QskAspect::Subcontrol ) const;
int count() const override final; int count() const override final;