2017-07-21 18:21:34 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
|
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "QskIndexedLayoutBox.h"
|
|
|
|
#include "QskLayoutEngine.h"
|
|
|
|
#include "QskLayoutItem.h"
|
2018-08-03 08:15:28 +02:00
|
|
|
#include "QskQuick.h"
|
2018-05-01 12:41:20 +02:00
|
|
|
|
2017-07-21 18:21:34 +02:00
|
|
|
class QskIndexedLayoutBox::PrivateData
|
|
|
|
{
|
2018-08-03 08:15:28 +02:00
|
|
|
public:
|
|
|
|
PrivateData()
|
|
|
|
: autoAddChildren( true )
|
|
|
|
, blockChildAdded( false )
|
|
|
|
, defaultAlignment( Qt::AlignLeft | Qt::AlignVCenter )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool autoAddChildren : 1;
|
|
|
|
bool blockChildAdded : 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
QGridLayoutEngine is supposed to find the alignment
|
|
|
|
( see: QGridLayoutEngine::effectiveAlignment ) by looking up in:
|
|
|
|
item -> row/column -> layout default.
|
|
|
|
|
|
|
|
Unfortunatly the layout default can't be modified without accessing
|
|
|
|
private methods and - for some reason worse - QGridLayoutEngine::effectiveAlignment
|
|
|
|
does not fall back to the layout default for the horizontal alignment.
|
|
|
|
|
|
|
|
But as we don't offer setting the row/column alignment at the public API
|
|
|
|
of QskIndexedLayoutBox we work around by using them instead.
|
|
|
|
*/
|
|
|
|
Qt::Alignment defaultAlignment;
|
|
|
|
};
|
|
|
|
|
2018-08-03 08:15:28 +02:00
|
|
|
QskIndexedLayoutBox::QskIndexedLayoutBox( QQuickItem* parent )
|
|
|
|
: QskLayout( parent )
|
|
|
|
, m_data( new PrivateData() )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
// classBegin/componentComplete -> setActive( false/true ) ?
|
|
|
|
}
|
|
|
|
|
|
|
|
QskIndexedLayoutBox::~QskIndexedLayoutBox()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskIndexedLayoutBox::setAutoAddChildren( bool on )
|
|
|
|
{
|
|
|
|
if ( on != m_data->autoAddChildren )
|
|
|
|
{
|
|
|
|
m_data->autoAddChildren = on;
|
|
|
|
Q_EMIT autoAddChildrenChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool QskIndexedLayoutBox::autoAddChildren() const
|
|
|
|
{
|
|
|
|
return m_data->autoAddChildren;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskIndexedLayoutBox::setDefaultAlignment( Qt::Alignment alignment )
|
|
|
|
{
|
|
|
|
bool hasChanged = false;
|
|
|
|
|
|
|
|
const Qt::Alignment alignV = alignment & Qt::AlignVertical_Mask;
|
|
|
|
if ( alignV != ( m_data->defaultAlignment & Qt::AlignVertical_Mask ) )
|
|
|
|
{
|
|
|
|
hasChanged = true;
|
|
|
|
|
|
|
|
for ( int row = 0; row < engine().rowCount(); row++ )
|
|
|
|
engine().setRowAlignment( row, alignV, Qt::Vertical );
|
|
|
|
}
|
|
|
|
|
|
|
|
const Qt::Alignment alignH = alignment & Qt::AlignHorizontal_Mask;
|
|
|
|
if ( alignH != ( m_data->defaultAlignment & Qt::AlignHorizontal_Mask ) )
|
|
|
|
{
|
|
|
|
hasChanged = true;
|
|
|
|
|
|
|
|
for ( int col = 0; col < engine().columnCount(); col++ )
|
|
|
|
engine().setRowAlignment( col, alignH, Qt::Horizontal );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( hasChanged )
|
|
|
|
{
|
|
|
|
m_data->defaultAlignment = alignment;
|
|
|
|
Q_EMIT defaultAlignmentChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Qt::Alignment QskIndexedLayoutBox::defaultAlignment() const
|
|
|
|
{
|
|
|
|
return m_data->defaultAlignment;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskIndexedLayoutBox::addItem(
|
|
|
|
QQuickItem* item, Qt::Alignment alignment )
|
|
|
|
{
|
|
|
|
insertItem( -1, item, alignment );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskIndexedLayoutBox::insertItem(
|
|
|
|
int index, QQuickItem* item, Qt::Alignment alignment )
|
|
|
|
{
|
|
|
|
if ( item == nullptr )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( item->parentItem() == this )
|
|
|
|
{
|
|
|
|
const int oldIndex = indexOf( item );
|
2018-08-03 08:15:28 +02:00
|
|
|
if ( oldIndex >= 0 )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
// the item has been inserted before
|
|
|
|
|
|
|
|
const bool doAppend = index < 0 || index >= itemCount();
|
|
|
|
|
|
|
|
if ( ( index == oldIndex ) ||
|
|
|
|
( doAppend && oldIndex == itemCount() - 1 ) )
|
|
|
|
{
|
|
|
|
// already at its position, nothing to do
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
removeAt( oldIndex );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QskLayoutItem* layoutItem = new QskLayoutItem( item, 0, 0 );
|
|
|
|
layoutItem->setAlignment( alignment );
|
|
|
|
|
|
|
|
insertLayoutItem( layoutItem, index );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskIndexedLayoutBox::setAlignment( int index, Qt::Alignment alignment )
|
|
|
|
{
|
|
|
|
QskLayoutItem* layoutItem = engine().layoutItemAt( index );
|
|
|
|
if ( layoutItem && alignment != layoutItem->alignment() )
|
|
|
|
{
|
|
|
|
layoutItem->setAlignment( alignment );
|
|
|
|
activate(); // invalidate() ???
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Qt::Alignment QskIndexedLayoutBox::alignment( int index ) const
|
|
|
|
{
|
|
|
|
QskLayoutItem* layoutItem = engine().layoutItemAt( index );
|
|
|
|
if ( layoutItem )
|
|
|
|
return layoutItem->alignment();
|
|
|
|
|
|
|
|
return Qt::Alignment();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskIndexedLayoutBox::setAlignment( QQuickItem* item, Qt::Alignment alignment )
|
|
|
|
{
|
|
|
|
setAlignment( engine().indexOf( item ), alignment );
|
|
|
|
}
|
|
|
|
|
|
|
|
Qt::Alignment QskIndexedLayoutBox::alignment( QQuickItem* item ) const
|
|
|
|
{
|
|
|
|
return alignment( engine().indexOf( item ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskIndexedLayoutBox::insertLayoutItem(
|
|
|
|
QskLayoutItem* layoutItem, int index )
|
|
|
|
{
|
|
|
|
const int numItems = itemCount();
|
|
|
|
if ( index < 0 || index > numItems )
|
|
|
|
index = numItems;
|
|
|
|
|
|
|
|
setupLayoutItem( layoutItem, index );
|
|
|
|
|
|
|
|
const int rowCount = engine().rowCount();
|
|
|
|
const int columnCount = engine().columnCount();
|
|
|
|
|
|
|
|
// not exception safe !!
|
|
|
|
m_data->blockChildAdded = true;
|
|
|
|
insertItemInternal( layoutItem, index );
|
|
|
|
m_data->blockChildAdded = false;
|
|
|
|
|
|
|
|
if ( rowCount != engine().rowCount() )
|
|
|
|
{
|
|
|
|
const Qt::Alignment alignV = m_data->defaultAlignment & Qt::AlignVertical_Mask;
|
|
|
|
for ( int row = 0; row < engine().rowCount(); row++ )
|
|
|
|
engine().setRowAlignment( row, alignV, Qt::Vertical );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( columnCount != engine().columnCount() )
|
|
|
|
{
|
|
|
|
const Qt::Alignment alignH = m_data->defaultAlignment & Qt::AlignHorizontal_Mask;
|
|
|
|
for ( int col = 0; col < engine().columnCount(); col++ )
|
|
|
|
engine().setRowAlignment( col, alignH, Qt::Horizontal );
|
|
|
|
}
|
|
|
|
|
|
|
|
layoutItemInserted( layoutItem, index );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskIndexedLayoutBox::itemChange(
|
|
|
|
QQuickItem::ItemChange change, const QQuickItem::ItemChangeData& value )
|
|
|
|
{
|
2018-08-03 08:15:28 +02:00
|
|
|
switch ( change )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
case QQuickItem::ItemChildAddedChange:
|
|
|
|
{
|
|
|
|
if ( m_data->autoAddChildren && !m_data->blockChildAdded )
|
|
|
|
{
|
2018-01-19 10:07:05 +01:00
|
|
|
if ( !qskIsTransparentForPositioner( value.item ) )
|
2017-07-21 18:21:34 +02:00
|
|
|
addItem( value.item );
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QQuickItem::ItemChildRemovedChange:
|
|
|
|
{
|
|
|
|
removeItem( value.item );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Inherited::itemChange( change, value );
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "moc_QskIndexedLayoutBox.cpp"
|