2019-07-01 14:45:25 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
2023-04-06 09:23:37 +02:00
|
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
2019-07-01 14:45:25 +02:00
|
|
|
*****************************************************************************/
|
|
|
|
|
2019-06-19 14:08:45 +02:00
|
|
|
#include "QskLinearLayoutEngine.h"
|
2021-12-15 08:45:29 +01:00
|
|
|
#include "QskLayoutMetrics.h"
|
2019-07-01 14:45:25 +02:00
|
|
|
#include "QskLayoutChain.h"
|
2022-08-06 15:41:32 +02:00
|
|
|
#include "QskLayoutElement.h"
|
2019-06-19 14:08:45 +02:00
|
|
|
#include "QskSizePolicy.h"
|
|
|
|
#include "QskQuick.h"
|
|
|
|
|
|
|
|
#include <qvector.h>
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
2022-08-06 15:41:32 +02:00
|
|
|
inline QskLayoutMetrics qskItemMetrics(
|
|
|
|
QQuickItem* item, Qt::Orientation orientation, qreal constraint )
|
|
|
|
{
|
|
|
|
const QskItemLayoutElement layoutItem( item );
|
|
|
|
return layoutItem.metrics( orientation, constraint );
|
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
class Element
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
|
|
|
public:
|
2019-07-27 12:36:52 +02:00
|
|
|
Element( QQuickItem* item );
|
|
|
|
Element( qreal spacing );
|
2021-07-14 14:43:12 +02:00
|
|
|
Element( const Element& );
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
Element& operator=( const Element& );
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-09-16 07:32:28 +02:00
|
|
|
qreal spacing() const;
|
2019-07-27 12:36:52 +02:00
|
|
|
QQuickItem* item() const;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
int stretch() const;
|
|
|
|
void setStretch( int );
|
2019-06-19 14:08:45 +02:00
|
|
|
|
|
|
|
bool isIgnored() const;
|
|
|
|
|
2019-09-10 17:01:47 +02:00
|
|
|
QskLayoutChain::CellData cell(
|
|
|
|
Qt::Orientation, bool isLayoutOrientation ) const;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
union
|
|
|
|
{
|
|
|
|
QQuickItem* m_item;
|
2019-09-16 07:32:28 +02:00
|
|
|
qreal m_spacing;
|
2019-06-19 14:08:45 +02:00
|
|
|
};
|
|
|
|
|
2019-09-05 10:46:42 +02:00
|
|
|
int m_stretch = -1;
|
|
|
|
bool m_isSpacer;
|
2019-06-19 14:08:45 +02:00
|
|
|
};
|
2022-04-22 08:13:19 +02:00
|
|
|
|
|
|
|
class ElementsVector : public std::vector< Element >
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// to avoid warnings when assigning size_t to int
|
|
|
|
inline int count() const { return static_cast< int >( size() ); }
|
|
|
|
};
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
Element::Element( QQuickItem* item )
|
2019-06-19 14:08:45 +02:00
|
|
|
: m_item( item )
|
|
|
|
, m_isSpacer( false )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
Element::Element( qreal spacing )
|
2019-09-16 07:32:28 +02:00
|
|
|
: m_spacing( spacing )
|
2019-06-19 14:08:45 +02:00
|
|
|
, m_isSpacer( true )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-07-14 14:43:12 +02:00
|
|
|
Element::Element( const Element& other )
|
|
|
|
: m_stretch( other.m_stretch )
|
|
|
|
, m_isSpacer( other.m_isSpacer )
|
|
|
|
{
|
|
|
|
if ( other.m_isSpacer )
|
|
|
|
m_spacing = other.m_spacing;
|
|
|
|
else
|
|
|
|
m_item = other.m_item;
|
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
Element& Element::operator=( const Element& other )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
|
|
|
m_isSpacer = other.m_isSpacer;
|
|
|
|
|
|
|
|
if ( other.m_isSpacer )
|
2019-09-16 07:32:28 +02:00
|
|
|
m_spacing = other.m_spacing;
|
2019-06-19 14:08:45 +02:00
|
|
|
else
|
|
|
|
m_item = other.m_item;
|
|
|
|
|
|
|
|
m_stretch = other.m_stretch;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2019-09-16 07:32:28 +02:00
|
|
|
inline qreal Element::spacing() const
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-09-16 07:32:28 +02:00
|
|
|
return m_isSpacer ? m_spacing : -1.0;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
inline QQuickItem* Element::item() const
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
return m_isSpacer ? nullptr : m_item;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
inline int Element::stretch() const
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
return m_stretch;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
inline void Element::setStretch( int stretch )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
m_stretch = stretch;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
bool Element::isIgnored() const
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-09-10 17:01:47 +02:00
|
|
|
return !( m_isSpacer || qskIsVisibleToLayout( m_item ) );
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-09-10 17:01:47 +02:00
|
|
|
QskLayoutChain::CellData Element::cell(
|
|
|
|
Qt::Orientation orientation, bool isLayoutOrientation ) const
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
QskLayoutChain::CellData cell;
|
2019-07-12 15:24:06 +02:00
|
|
|
cell.canGrow = true;
|
2019-07-13 10:03:04 +02:00
|
|
|
cell.isValid = true;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( !m_isSpacer )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-09-10 17:01:47 +02:00
|
|
|
const auto policy = qskSizePolicy( m_item ).policy( orientation );
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( isLayoutOrientation )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( m_stretch < 0 )
|
2019-07-12 15:24:06 +02:00
|
|
|
cell.stretch = ( policy & QskSizePolicy::ExpandFlag ) ? 1 : 0;
|
2019-06-19 14:08:45 +02:00
|
|
|
else
|
2019-07-27 12:36:52 +02:00
|
|
|
cell.stretch = m_stretch;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-12 15:24:06 +02:00
|
|
|
cell.canGrow = policy & QskSizePolicy::GrowFlag;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( isLayoutOrientation )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2021-12-15 08:45:29 +01:00
|
|
|
cell.metrics.setMinimum( m_spacing );
|
|
|
|
cell.metrics.setPreferred( m_spacing );
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( m_stretch <= 0 )
|
2021-12-15 08:45:29 +01:00
|
|
|
cell.metrics.setMaximum( m_spacing );
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
cell.stretch = qMax( m_stretch, 0 );
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-01 14:45:25 +02:00
|
|
|
return cell;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class QskLinearLayoutEngine::PrivateData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
PrivateData( Qt::Orientation orientation, uint dimension )
|
2019-07-27 12:36:52 +02:00
|
|
|
: dimension( dimension )
|
|
|
|
, sumIgnored( -1 )
|
|
|
|
, orientation( orientation )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
inline Element* elementAt( int index ) const
|
|
|
|
{
|
2022-04-22 08:13:19 +02:00
|
|
|
if ( ( index < 0 ) || ( index >= this->elements.count() ) )
|
2019-07-27 12:36:52 +02:00
|
|
|
return nullptr;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
return const_cast< Element* >( &this->elements[index] );
|
|
|
|
}
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2022-04-22 08:13:19 +02:00
|
|
|
ElementsVector elements;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
uint dimension;
|
2019-07-13 11:01:48 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
mutable int sumIgnored : 30;
|
|
|
|
unsigned int orientation : 2;
|
2019-06-19 14:08:45 +02:00
|
|
|
};
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
QskLinearLayoutEngine::QskLinearLayoutEngine(
|
|
|
|
Qt::Orientation orientation, uint dimension )
|
2019-06-19 14:08:45 +02:00
|
|
|
: m_data( new PrivateData( orientation, dimension ) )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QskLinearLayoutEngine::~QskLinearLayoutEngine()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-07-12 15:37:42 +02:00
|
|
|
bool QskLinearLayoutEngine::setOrientation( Qt::Orientation orientation )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( m_data->orientation != orientation )
|
|
|
|
{
|
|
|
|
m_data->orientation = orientation;
|
|
|
|
invalidate( LayoutCache );
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2019-07-12 15:37:42 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
return false;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Qt::Orientation QskLinearLayoutEngine::orientation() const
|
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
return static_cast< Qt::Orientation >( m_data->orientation );
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-12 15:37:42 +02:00
|
|
|
bool QskLinearLayoutEngine::setDimension( uint dimension )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
|
|
|
if ( dimension < 1 )
|
|
|
|
dimension = 1;
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( m_data->dimension != dimension )
|
|
|
|
{
|
|
|
|
m_data->dimension = dimension;
|
|
|
|
invalidate( LayoutCache );
|
2019-07-12 15:37:42 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
return true;
|
|
|
|
}
|
2019-07-12 15:37:42 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
return false;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
uint QskLinearLayoutEngine::dimension() const
|
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
return m_data->dimension;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int QskLinearLayoutEngine::count() const
|
|
|
|
{
|
2022-04-22 08:13:19 +02:00
|
|
|
return m_data->elements.count();
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-12 15:37:42 +02:00
|
|
|
bool QskLinearLayoutEngine::setStretchFactorAt( int index, int stretchFactor )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( auto element = m_data->elementAt( index ) )
|
|
|
|
{
|
|
|
|
if ( stretchFactor < 0 )
|
|
|
|
stretchFactor = -1;
|
|
|
|
|
|
|
|
if ( element->stretch() != stretchFactor )
|
|
|
|
{
|
|
|
|
element->setStretch( stretchFactor );
|
|
|
|
invalidate( LayoutCache );
|
2019-07-12 15:37:42 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2019-07-12 15:37:42 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
return false;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int QskLinearLayoutEngine::stretchFactorAt( int index ) const
|
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( const auto element = m_data->elementAt( index ) )
|
|
|
|
return element->stretch();
|
|
|
|
|
|
|
|
return -1;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
int QskLinearLayoutEngine::insertItem( QQuickItem* item, int index )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
auto& elements = m_data->elements;
|
|
|
|
|
|
|
|
if ( index < 0 || index > count() )
|
|
|
|
{
|
2022-04-22 08:13:19 +02:00
|
|
|
index = elements.count();
|
2019-07-27 12:36:52 +02:00
|
|
|
elements.emplace_back( item );
|
|
|
|
}
|
2019-06-19 14:08:45 +02:00
|
|
|
else
|
2019-07-27 12:36:52 +02:00
|
|
|
{
|
|
|
|
elements.emplace( elements.begin() + index, item );
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidate();
|
|
|
|
return index;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
int QskLinearLayoutEngine::insertSpacerAt( int index, qreal spacing )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
spacing = qMax( spacing, static_cast< qreal >( 0.0 ) );
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
auto& elements = m_data->elements;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( index < 0 || index > count() )
|
|
|
|
{
|
2022-04-22 08:13:19 +02:00
|
|
|
index = elements.count();
|
2019-07-27 12:36:52 +02:00
|
|
|
elements.emplace_back( spacing );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
elements.emplace( elements.begin() + index, spacing );
|
|
|
|
}
|
2019-06-19 14:08:45 +02:00
|
|
|
|
|
|
|
invalidate( LayoutCache );
|
2019-07-27 12:36:52 +02:00
|
|
|
return index;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
bool QskLinearLayoutEngine::removeAt( int index )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
auto element = m_data->elementAt( index );
|
|
|
|
if ( element == nullptr )
|
|
|
|
return false;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( element->isIgnored() )
|
|
|
|
m_data->sumIgnored--;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-09-10 17:01:47 +02:00
|
|
|
const auto itemType = qskSizePolicy( element->item() ).constraintType();
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
int invalidationMode = LayoutCache;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-09-10 17:01:47 +02:00
|
|
|
if ( itemType > QskSizePolicy::Unconstrained )
|
2019-07-27 12:36:52 +02:00
|
|
|
invalidationMode |= ElementCache;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
m_data->elements.erase( m_data->elements.begin() + index );
|
|
|
|
invalidate( invalidationMode );
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
return true;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
bool QskLinearLayoutEngine::clear()
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( count() <= 0 )
|
|
|
|
return false;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
m_data->elements.clear();
|
|
|
|
invalidate();
|
|
|
|
|
|
|
|
return true;
|
2019-07-13 10:36:12 +02:00
|
|
|
}
|
|
|
|
|
2022-08-06 15:41:32 +02:00
|
|
|
QskSizePolicy QskLinearLayoutEngine::sizePolicyAt( int index ) const
|
|
|
|
{
|
|
|
|
return qskSizePolicy( itemAt( index ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
int QskLinearLayoutEngine::indexOf( const QQuickItem* item ) const
|
|
|
|
{
|
|
|
|
if ( item )
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
indexOf is often called after inserting an item to
|
|
|
|
set additinal properties. So we search in reverse order
|
|
|
|
*/
|
|
|
|
|
|
|
|
for ( int i = count() - 1; i >= 0; --i )
|
|
|
|
{
|
|
|
|
if ( itemAt( i ) == item )
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-06-19 14:08:45 +02:00
|
|
|
QQuickItem* QskLinearLayoutEngine::itemAt( int index ) const
|
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( const auto element = m_data->elementAt( index ) )
|
|
|
|
return element->item();
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
return nullptr;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
qreal QskLinearLayoutEngine::spacerAt( int index ) const
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( const auto element = m_data->elementAt( index ) )
|
2019-09-16 07:32:28 +02:00
|
|
|
return element->spacing();
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
return -1.0;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
void QskLinearLayoutEngine::layoutItems()
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
|
|
|
uint row = 0;
|
|
|
|
uint col = 0;
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
for ( const auto& element : m_data->elements )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( element.isIgnored() )
|
2019-06-19 14:08:45 +02:00
|
|
|
continue;
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( auto item = element.item() )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2022-04-08 16:46:20 +02:00
|
|
|
if ( qskIsAdjustableByLayout( item ) )
|
2019-09-16 12:38:10 +02:00
|
|
|
{
|
|
|
|
const QRect grid( col, row, 1, 1 );
|
2022-08-06 15:41:32 +02:00
|
|
|
|
|
|
|
const QskItemLayoutElement layoutElement( item );
|
|
|
|
|
|
|
|
const auto rect = geometryAt( &layoutElement, grid );
|
|
|
|
if ( rect.size().isValid() )
|
|
|
|
qskSetItemGeometry( item, rect );
|
2019-09-16 12:38:10 +02:00
|
|
|
}
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( m_data->orientation == Qt::Horizontal )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( ++col == m_data->dimension )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
|
|
|
col = 0;
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( ++row == m_data->dimension )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
|
|
|
row = 0;
|
|
|
|
col++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
int QskLinearLayoutEngine::effectiveCount( Qt::Orientation orientation ) const
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
const uint cellCount = effectiveCount();
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( orientation == m_data->orientation )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
return qMin( cellCount, m_data->dimension );
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
int count = cellCount / m_data->dimension;
|
|
|
|
if ( cellCount % m_data->dimension )
|
|
|
|
count++;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
return count;
|
|
|
|
}
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
int QskLinearLayoutEngine::effectiveCount() const
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( m_data->sumIgnored < 0 )
|
2019-07-12 15:37:42 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
m_data->sumIgnored = 0;
|
|
|
|
|
|
|
|
for ( const auto& element : m_data->elements )
|
|
|
|
{
|
|
|
|
if ( element.isIgnored() )
|
|
|
|
m_data->sumIgnored++;
|
|
|
|
}
|
2019-07-12 15:37:42 +02:00
|
|
|
}
|
|
|
|
|
2022-04-22 08:13:19 +02:00
|
|
|
return m_data->elements.count() - m_data->sumIgnored;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
void QskLinearLayoutEngine::invalidateElementCache()
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
m_data->sumIgnored = -1;
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
void QskLinearLayoutEngine::setupChain( Qt::Orientation orientation,
|
|
|
|
const QskLayoutChain::Segments& constraints, QskLayoutChain& chain ) const
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
uint index1 = 0;
|
|
|
|
uint index2 = 0;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
const bool isLayoutOrientation = ( orientation == m_data->orientation );
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
qreal constraint = -1.0;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
for ( const auto& element : m_data->elements )
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( element.isIgnored() )
|
|
|
|
continue;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( !constraints.isEmpty() )
|
|
|
|
constraint = constraints[index1].length;
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-09-10 17:01:47 +02:00
|
|
|
auto cell = element.cell( orientation, isLayoutOrientation );
|
|
|
|
|
|
|
|
if ( element.item() )
|
2022-08-06 15:41:32 +02:00
|
|
|
cell.metrics = qskItemMetrics( element.item(), orientation, constraint );
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
chain.expandCell( index2, cell );
|
2019-06-19 14:08:45 +02:00
|
|
|
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( isLayoutOrientation )
|
|
|
|
{
|
|
|
|
if ( ++index2 == m_data->dimension )
|
|
|
|
{
|
|
|
|
index2 = 0;
|
|
|
|
index1++;
|
|
|
|
}
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
2019-07-27 12:36:52 +02:00
|
|
|
else
|
2019-06-19 14:08:45 +02:00
|
|
|
{
|
2019-07-27 12:36:52 +02:00
|
|
|
if ( ++index1 == m_data->dimension )
|
|
|
|
{
|
|
|
|
index1 = 0;
|
|
|
|
index2++;
|
|
|
|
}
|
2019-06-19 14:08:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|