Keep Splitter items on the stack.

This commit is contained in:
Teo Mrnjavac 2016-02-22 18:51:44 +01:00
parent 7bf0fa2575
commit bafaa6a225
2 changed files with 52 additions and 49 deletions

View File

@ -33,7 +33,6 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QStyleOption> #include <QStyleOption>
static const int VIEW_HEIGHT = qMax( CalamaresUtils::defaultFontHeight() + 8, // wins out with big fonts static const int VIEW_HEIGHT = qMax( CalamaresUtils::defaultFontHeight() + 8, // wins out with big fonts
(int)( CalamaresUtils::defaultFontHeight() * 0.6 ) + 22 ); // wins out with small fonts (int)( CalamaresUtils::defaultFontHeight() * 0.6 ) + 22 ); // wins out with small fonts
static const int CORNER_RADIUS = 3; static const int CORNER_RADIUS = 3;
@ -42,8 +41,8 @@ static const int EXTENDED_PARTITION_MARGIN = qMax( 4, VIEW_HEIGHT / 6 );
PartitionSplitterWidget::PartitionSplitterWidget( QWidget* parent ) PartitionSplitterWidget::PartitionSplitterWidget( QWidget* parent )
: QWidget( parent ) : QWidget( parent )
, m_resizing( false ) , m_resizing( false )
, m_itemToResize( nullptr ) , m_itemToResize( PartitionSplitterItem::null() )
, m_itemToResizeNext( nullptr ) , m_itemToResizeNext( PartitionSplitterItem::null() )
, m_itemMinSize( 0 ) , m_itemMinSize( 0 )
, m_itemMaxSize( 0 ) , m_itemMaxSize( 0 )
, m_itemPrefSize( 0 ) , m_itemPrefSize( 0 )
@ -97,8 +96,8 @@ PartitionSplitterWidget::init( Device* dev, bool drawNestedPartitions )
void void
PartitionSplitterWidget::setupItems( const QVector<PartitionSplitterItem>& items ) PartitionSplitterWidget::setupItems( const QVector<PartitionSplitterItem>& items )
{ {
m_itemToResize = nullptr; m_itemToResize = PartitionSplitterItem::null();
m_itemToResizeNext = nullptr; m_itemToResizeNext = PartitionSplitterItem::null();
m_itemToResizePath.clear(); m_itemToResizePath.clear();
m_items.clear(); m_items.clear();
@ -128,46 +127,46 @@ PartitionSplitterWidget::setSplitPartition( const QString& path,
// We need to remove the itemToResizeNext from wherever it is // We need to remove the itemToResizeNext from wherever it is
for ( int i = 0; i < m_items.count(); ++i ) for ( int i = 0; i < m_items.count(); ++i )
{ {
if ( m_items[ i ].itemPath == m_itemToResize->itemPath && if ( m_items[ i ].itemPath == m_itemToResize.itemPath &&
i + 1 < m_items.count() ) i + 1 < m_items.count() )
{ {
m_items[ i ].size = m_items[ i ].size + m_itemToResizeNext->size; m_items[ i ].size = m_items[ i ].size + m_itemToResizeNext.size;
m_items.removeAt( i + 1 ); m_items.removeAt( i + 1 );
m_itemToResizeNext = nullptr; m_itemToResizeNext = PartitionSplitterItem::null();
break; break;
} }
else if ( !m_items[ i ].children.isEmpty() ) else if ( !m_items[ i ].children.isEmpty() )
{ {
for ( int j = 0; j < m_items[ i ].children.count(); ++j ) for ( int j = 0; j < m_items[ i ].children.count(); ++j )
{ {
if ( m_items[ i ].children[ j ].itemPath == m_itemToResize->itemPath && if ( m_items[ i ].children[ j ].itemPath == m_itemToResize.itemPath &&
j + 1 < m_items[ i ].children.count() ) j + 1 < m_items[ i ].children.count() )
{ {
m_items[ i ].children[ j ].size = m_items[ i ].children[ j ].size =
m_items[ i ].children[ j ].size + m_itemToResizeNext->size; m_items[ i ].children[ j ].size + m_itemToResizeNext.size;
m_items[ i ].children.removeAt( j + 1 ); m_items[ i ].children.removeAt( j + 1 );
m_itemToResizeNext = nullptr; m_itemToResizeNext = PartitionSplitterItem::null();
break; break;
} }
} }
if ( !m_itemToResizeNext ) if ( m_itemToResizeNext.isNull() )
break; break;
} }
} }
m_itemToResize = nullptr; m_itemToResize = PartitionSplitterItem::null();
m_itemToResizePath.clear(); m_itemToResizePath.clear();
} }
PartitionSplitterItem* itemToResize = _findItem( m_items, PartitionSplitterItem itemToResize = _findItem( m_items,
[ path ]( PartitionSplitterItem& item ) -> bool [ path ]( PartitionSplitterItem& item ) -> bool
{ {
return path == item.itemPath; return path == item.itemPath;
} ); } );
if ( !itemToResize ) if ( itemToResize.isNull() )
return; return;
cDebug() << "itemToResize:" << itemToResize->itemPath; cDebug() << "itemToResize:" << itemToResize.itemPath;
m_itemToResize = itemToResize; m_itemToResize = itemToResize;
m_itemToResizePath = path; m_itemToResizePath = path;
@ -175,48 +174,48 @@ PartitionSplitterWidget::setSplitPartition( const QString& path,
if ( preferredSize > maxSize ) if ( preferredSize > maxSize )
preferredSize = maxSize; preferredSize = maxSize;
qint64 newSize = m_itemToResize->size - preferredSize; qint64 newSize = m_itemToResize.size - preferredSize;
m_itemToResize->size = preferredSize; m_itemToResize.size = preferredSize;
m_itemMinSize = minSize; m_itemMinSize = minSize;
m_itemMaxSize = maxSize; m_itemMaxSize = maxSize;
m_itemPrefSize = preferredSize; m_itemPrefSize = preferredSize;
for ( int i = 0; i < m_items.count(); ++i ) for ( int i = 0; i < m_items.count(); ++i )
{ {
if ( m_items[ i ].itemPath == itemToResize->itemPath ) if ( m_items[ i ].itemPath == itemToResize.itemPath )
{ {
m_items.insert( i+1, m_items.insert( i+1,
{ "", QColor( "#c0392b" ), false, newSize, {} } ); { "", QColor( "#c0392b" ), false, newSize, {} } );
m_itemToResizeNext = &( m_items[ i+1 ] ); m_itemToResizeNext = m_items[ i+1 ];
break; break;
} }
else if ( !m_items[ i ].children.isEmpty() ) else if ( !m_items[ i ].children.isEmpty() )
{ {
for ( int j = 0; j < m_items[ i ].children.count(); ++j ) for ( int j = 0; j < m_items[ i ].children.count(); ++j )
{ {
if ( m_items[ i ].children[ j ].itemPath == itemToResize->itemPath ) if ( m_items[ i ].children[ j ].itemPath == itemToResize.itemPath )
{ {
m_items[ i ].children.insert( j+1, m_items[ i ].children.insert( j+1,
{ "", QColor( "#c0392b" ), false, newSize, {} } ); { "", QColor( "#c0392b" ), false, newSize, {} } );
m_itemToResizeNext = &( m_items[ i ].children[ j+1 ] ); m_itemToResizeNext = m_items[ i ].children[ j+1 ];
break; break;
} }
} }
if ( m_itemToResizeNext ) if ( !m_itemToResizeNext.isNull() )
break; break;
} }
} }
emit partitionResized( m_itemToResize->itemPath, emit partitionResized( m_itemToResize.itemPath,
m_itemToResize->size, m_itemToResize.size,
m_itemToResizeNext->size ); m_itemToResizeNext.size );
cDebug() << "Items updated. Status:"; cDebug() << "Items updated. Status:";
foreach ( const PartitionSplitterItem& item, m_items ) foreach ( const PartitionSplitterItem& item, m_items )
cDebug() << "item" << item.itemPath << "size" << item.size; cDebug() << "item" << item.itemPath << "size" << item.size;
cDebug() << "m_itemToResize: " << m_itemToResize << m_itemToResize->itemPath; cDebug() << "m_itemToResize: " << !m_itemToResize.isNull() << m_itemToResize.itemPath;
cDebug() << "m_itemToResizeNext:" << m_itemToResizeNext << m_itemToResizeNext->itemPath; cDebug() << "m_itemToResizeNext:" << !m_itemToResizeNext.isNull() << m_itemToResizeNext.itemPath;
repaint(); repaint();
} }
@ -227,7 +226,7 @@ PartitionSplitterWidget::splitPartitionSize() const
{ {
if ( !m_itemToResize ) if ( !m_itemToResize )
return -1; return -1;
return m_itemToResize->size; return m_itemToResize.size;
} }
@ -236,7 +235,7 @@ PartitionSplitterWidget::newPartitionSize() const
{ {
if ( !m_itemToResizeNext ) if ( !m_itemToResizeNext )
return -1; return -1;
return m_itemToResizeNext->size; return m_itemToResizeNext.size;
} }
@ -284,7 +283,7 @@ PartitionSplitterWidget::mouseMoveEvent( QMouseEvent* event )
if ( m_resizing ) if ( m_resizing )
{ {
qint64 start = 0; qint64 start = 0;
QString itemPath = m_itemToResize->itemPath; QString itemPath = m_itemToResize.itemPath;
for ( auto it = m_items.constBegin(); for ( auto it = m_items.constBegin();
it != m_items.constEnd(); ++it ) it != m_items.constEnd(); ++it )
{ {
@ -328,16 +327,16 @@ PartitionSplitterWidget::mouseMoveEvent( QMouseEvent* event )
qint64 span = m_itemPrefSize; qint64 span = m_itemPrefSize;
qreal percent = mx / span; qreal percent = mx / span;
qint64 oldsize = m_itemToResize->size; qint64 oldsize = m_itemToResize.size;
m_itemToResize->size = qRound64( span * percent ); m_itemToResize.size = qRound64( span * percent );
m_itemToResizeNext->size -= m_itemToResize->size - oldsize; m_itemToResizeNext.size -= m_itemToResize.size - oldsize;
repaint(); repaint();
emit partitionResized( itemPath, emit partitionResized( itemPath,
m_itemToResize->size, m_itemToResize.size,
m_itemToResizeNext->size ); m_itemToResizeNext.size );
} }
else else
{ {
@ -428,7 +427,7 @@ PartitionSplitterWidget::drawResizeHandle( QPainter* painter,
} }
auto p1 = arrow_offsets[ 0 ]; auto p1 = arrow_offsets[ 0 ];
if ( m_itemToResize->size > m_itemMinSize ) if ( m_itemToResize.size > m_itemMinSize )
{ {
auto arrow = QPainterPath( QPointF( x + -1 * p1.first, p1.second ) ); auto arrow = QPainterPath( QPointF( x + -1 * p1.first, p1.second ) );
for ( auto p : arrow_offsets ) for ( auto p : arrow_offsets )
@ -436,7 +435,7 @@ PartitionSplitterWidget::drawResizeHandle( QPainter* painter,
painter->drawPath( arrow ); painter->drawPath( arrow );
} }
if ( m_itemToResize->size < m_itemMaxSize ) if ( m_itemToResize.size < m_itemMaxSize )
{ {
auto arrow = QPainterPath( QPointF( x + p1.first, p1.second ) ); auto arrow = QPainterPath( QPointF( x + p1.first, p1.second ) );
for ( auto p : arrow_offsets ) for ( auto p : arrow_offsets )
@ -493,7 +492,7 @@ PartitionSplitterWidget::drawPartitions( QPainter* painter,
row > 0 && row > 0 &&
!items[ row - 1 ].isFreeSpace && !items[ row - 1 ].isFreeSpace &&
!items[ row - 1 ].itemPath.isEmpty() && !items[ row - 1 ].itemPath.isEmpty() &&
items[ row - 1 ].itemPath == m_itemToResize->itemPath ) items[ row - 1 ].itemPath == m_itemToResize.itemPath )
{ {
m_resizeHandleX = x; m_resizeHandleX = x;
drawResizeHandle( painter, rect, m_resizeHandleX ); drawResizeHandle( painter, rect, m_resizeHandleX );
@ -505,20 +504,20 @@ PartitionSplitterWidget::drawPartitions( QPainter* painter,
template < typename F > template < typename F >
PartitionSplitterItem* PartitionSplitterItem
PartitionSplitterWidget::_findItem( QVector< PartitionSplitterItem >& items, PartitionSplitterWidget::_findItem( QVector< PartitionSplitterItem >& items,
F condition ) F condition )
{ {
for ( auto it = items.begin(); it != items.end(); ++it) for ( auto it = items.begin(); it != items.end(); ++it)
{ {
if ( condition( *it ) ) if ( condition( *it ) )
return &*it; return *it;
PartitionSplitterItem* candidate = _findItem( it->children, condition ); PartitionSplitterItem candidate = _findItem( it->children, condition );
if ( candidate ) if ( !candidate.isNull() )
return candidate; return candidate;
} }
return nullptr; return PartitionSplitterItem::null();
} }

View File

@ -31,6 +31,11 @@ struct PartitionSplitterItem
qint64 size; qint64 size;
QVector< PartitionSplitterItem > children; QVector< PartitionSplitterItem > children;
static PartitionSplitterItem null() { return { QString(), QColor(), false, 0 }; }
bool isNull() const { return itemPath.isEmpty() && size == 0; }
operator bool() const { return !isNull(); }
}; };
class PartitionSplitterWidget : public QWidget class PartitionSplitterWidget : public QWidget
@ -75,16 +80,15 @@ private:
int x ); int x );
template < typename F > template < typename F >
PartitionSplitterItem* _findItem( QVector< PartitionSplitterItem >& items, PartitionSplitterItem _findItem( QVector< PartitionSplitterItem >& items, F condition );
F condition );
QPair< QVector< PartitionSplitterItem >, qreal > QPair< QVector< PartitionSplitterItem >, qreal >
computeItemsVector( const QVector< PartitionSplitterItem >& originalItems ) const; computeItemsVector( const QVector< PartitionSplitterItem >& originalItems ) const;
QVector< PartitionSplitterItem > m_items; QVector< PartitionSplitterItem > m_items;
QString m_itemToResizePath; QString m_itemToResizePath;
PartitionSplitterItem* m_itemToResize; PartitionSplitterItem m_itemToResize;
PartitionSplitterItem* m_itemToResizeNext; PartitionSplitterItem m_itemToResizeNext;
qint64 m_itemMinSize; qint64 m_itemMinSize;
qint64 m_itemMaxSize; qint64 m_itemMaxSize;