Lots of model/view/delegate changes.

Created delegate for ProgressTreeView.
No more columns, only roles throughout the model.
Added row types and some user roles to the model.
Look and feel changes to ProgressTreeView.
This commit is contained in:
Teo Mrnjavac 2014-07-01 17:45:28 +02:00
parent 0eddb34c15
commit 698cff45c8
16 changed files with 335 additions and 18 deletions

View File

@ -19,6 +19,7 @@ set( calamaresSources
modulesystem/ViewModule.cpp
progresstree/CategoryItem.cpp
progresstree/ProgressTreeDelegate.cpp
progresstree/ProgressTreeItem.cpp
progresstree/ProgressTreeModel.cpp
progresstree/ProgressTreeView.cpp

View File

@ -89,6 +89,29 @@ ViewManager::addViewStep( ViewStep* step )
connect( step, &ViewStep::nextStatusChanged,
m_next, &QPushButton::setEnabled );
emit currentStepChanged();
}
QList< ViewStep* >
ViewManager::steps() const
{
return m_steps;
}
ViewStep*
ViewManager::currentStep() const
{
return m_steps.value( m_currentStep );
}
int
ViewManager::currentStepIndex() const
{
return m_currentStep;
}
@ -100,6 +123,7 @@ ViewManager::next()
{
m_currentStep++;
m_stack->setCurrentIndex( m_currentStep );
emit currentStepChanged();
}
else if ( !step->isAtEnd() )
{
@ -120,6 +144,7 @@ ViewManager::back()
{
m_currentStep--;
m_stack->setCurrentIndex( m_currentStep );
emit currentStepChanged();
}
else if ( !step->isAtBeginning() )
{

View File

@ -44,12 +44,17 @@ public:
void addViewStep( ViewStep* step );
QList< ViewStep* > steps() const { return m_steps; }
QList< ViewStep* > steps() const;
ViewStep* currentStep() const;
int currentStepIndex() const;
public slots:
void next();
void back();
signals:
void currentStepChanged();
private:
static ViewManager* s_instance;

View File

@ -18,6 +18,7 @@
#include "CategoryItem.h"
#include "ProgressTreeModel.h"
CategoryItem::CategoryItem( const QString& text, ProgressTreeItem* parent )
: ProgressTreeItem( parent )
@ -26,8 +27,13 @@ CategoryItem::CategoryItem( const QString& text, ProgressTreeItem* parent )
QVariant
CategoryItem::data( int column ) const
CategoryItem::data( int role ) const
{
Q_UNUSED( column );
return m_text;
if ( role == ProgressTreeModel::ProgressTreeItemTypeRole )
return ProgressTreeModel::Category;
if ( role == ProgressTreeModel::ProgressTreeItemRole )
return this;
if ( role == Qt::DisplayRole )
return m_text;
return QVariant();
}

View File

@ -27,7 +27,7 @@ class CategoryItem : public ProgressTreeItem
public:
explicit CategoryItem( const QString& text, ProgressTreeItem* parent = nullptr );
virtual QVariant data( int column ) const override;
virtual QVariant data( int role ) const override;
private:
QString m_text;

View File

@ -0,0 +1,134 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ProgressTreeDelegate.h"
#include "../CalamaresApplication.h"
#include "../CalamaresWindow.h"
#include "ViewStepItem.h"
#include "ProgressTreeModel.h"
#include "../ViewManager.h"
#include <QAbstractItemView>
#include <QPainter>
ProgressTreeDelegate::ProgressTreeDelegate( QAbstractItemView* parent )
: QStyledItemDelegate( parent )
, m_parent( parent )
{
}
QSize
ProgressTreeDelegate::sizeHint( const QStyleOptionViewItem& option,
const QModelIndex& index ) const
{
ProgressTreeModel::RowType type =
static_cast< ProgressTreeModel::RowType >(
index.data( ProgressTreeModel::ProgressTreeItemTypeRole ).toInt() );
if ( type == ProgressTreeModel::Invalid )
return option.rect.size();
QFont font = qApp->font();
if ( type == ProgressTreeModel::Category )
{
font.setPointSize( font.pointSize() + 5 );
}
else if ( type == ProgressTreeModel::ViewStep )
{
font.setPointSize( font.pointSize() + 2 );
}
QFontMetrics fm( font );
int height = fm.height();
height += 2*12; //margin
return QSize( option.rect.width(), height );
}
void
ProgressTreeDelegate::paint( QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
QStyleOptionViewItemV4 opt = option;
painter->save();
ProgressTreeModel::RowType type =
static_cast< ProgressTreeModel::RowType >(
index.data( ProgressTreeModel::ProgressTreeItemTypeRole ).toInt() );
if ( type == ProgressTreeModel::Invalid )
return;
initStyleOption( &opt, index );
opt.text.clear();
painter->setBrush( QColor( "#292F34" ) );
painter->setPen( QColor( "#FFFFFF" ) );
if ( type == ProgressTreeModel::Category )
paintCategory( painter, opt, index );
else if ( type == ProgressTreeModel::ViewStep )
paintViewStep( painter, opt, index );
painter->restore();
}
void
ProgressTreeDelegate::paintCategory( QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index ) const
{
QRect textRect = option.rect.adjusted( 12, 12, 12, 12 );
QFont font = qApp->font();
font.setPointSize( font.pointSize() + 5 );
font.setBold( false );
painter->setFont( font );
painter->drawText( textRect, index.data().toString() );
}
void
ProgressTreeDelegate::paintViewStep( QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index ) const
{
QRect textRect = option.rect.adjusted( 12 + 32 /*indentation*/, 12, 12, 12 );
QFont font = qApp->font();
font.setPointSize( font.pointSize() + 2 );
font.setBold( false );
painter->setFont( font );
bool isCurrent = false;
isCurrent = index.data( ProgressTreeModel::ProgressTreeItemCurrentRole ).toBool();
if ( isCurrent )
{
painter->setPen( QColor( "#292F34" ) );
painter->setBrush( APP->mainWindow()->palette().background() );
}
painter->fillRect( option.rect, painter->brush().color() );
painter->drawText( textRect, index.data().toString() );
}

View File

@ -0,0 +1,48 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROGRESSTREEDELEGATE_H
#define PROGRESSTREEDELEGATE_H
#include <QStyledItemDelegate>
class ProgressTreeDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit ProgressTreeDelegate( QAbstractItemView* parent = nullptr );
protected:
QSize sizeHint( const QStyleOptionViewItem& option,
const QModelIndex& index ) const override;
void paint( QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index ) const override;
private:
void paintCategory( QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index ) const;
void paintViewStep( QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index ) const;
QAbstractItemView* m_parent;
};
#endif // PROGRESSTREEDELEGATE_H

View File

@ -18,6 +18,8 @@
#include "ProgressTreeItem.h"
#include "ProgressTreeModel.h"
ProgressTreeItem::ProgressTreeItem( ProgressTreeItem* parent )
{
@ -82,8 +84,11 @@ ProgressTreeRoot::ProgressTreeRoot()
QVariant
ProgressTreeRoot::data( int column ) const
ProgressTreeRoot::data( int role ) const
{
Q_UNUSED( column );
if ( role == ProgressTreeModel::ProgressTreeItemTypeRole )
return ProgressTreeModel::Invalid;
if ( role == ProgressTreeModel::ProgressTreeItemRole )
return this;
return QVariant();
}

View File

@ -34,7 +34,7 @@ public:
virtual ProgressTreeItem* child( int row );
virtual int childCount() const;
virtual int columnCount() const;
virtual QVariant data( int column ) const = 0;
virtual QVariant data( int role ) const = 0;
virtual int row() const;
virtual ProgressTreeItem* parent();
@ -48,7 +48,7 @@ class ProgressTreeRoot : public ProgressTreeItem
public:
explicit ProgressTreeRoot();
virtual QVariant data( int column ) const;
virtual QVariant data( int role ) const;
};
#endif // PROGRESSTREEITEM_H

View File

@ -88,12 +88,9 @@ ProgressTreeModel::data( const QModelIndex& index, int role ) const
if ( !index.isValid() )
return QVariant();
if ( role != Qt::DisplayRole )
return QVariant();
ProgressTreeItem *item = static_cast< ProgressTreeItem* >( index.internalPointer() );
return item->data( index.column() );
return item->data( role );
}
@ -147,3 +144,49 @@ ProgressTreeModel::setupModelData()
m_rootItem->appendChild( new CategoryItem( tr( "Install" ), m_rootItem ) );
m_rootItem->appendChild( new CategoryItem( tr( "Finish" ), m_rootItem ) );
}
QModelIndex
ProgressTreeModel::indexFromItem( ProgressTreeItem* item )
{
if ( !item || !item->parent() )
return QModelIndex();
// Reconstructs a QModelIndex from a ProgressTreeItem that is somewhere in the tree.
// Traverses the item to the root node, then rebuilds the qmodeindices from there
// back down; each int is the row of that item in the parent.
/**
* In this diagram, if the \param item is G, childIndexList will contain [0, 2, 0]
*
* A
* D
* E
* F
* G
* H
* B
* C
*
**/
QList< int > childIndexList;
ProgressTreeItem* curItem = item;
while ( curItem != m_rootItem ) {
int row = curItem->row(); //relative to its parent
if ( row < 0 ) // something went wrong, bail
return QModelIndex();
childIndexList << row;
curItem = curItem->parent();
}
// Now we rebuild the QModelIndex we need
QModelIndex idx;
for ( int i = childIndexList.size() - 1; i >= 0 ; i-- )
{
idx = index( childIndexList[ i ], 0, idx );
}
return idx;
}

View File

@ -22,14 +22,30 @@
#include <QAbstractItemModel>
class ProgressTreeRoot;
class ProgressTreeItem;
class ProgressTreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
enum RowType
{
Invalid = -1,
Category = 0,
ViewStep = 1
};
enum Role
{
ProgressTreeItemRole = Qt::UserRole + 10,
ProgressTreeItemTypeRole = Qt::UserRole + 11,
ProgressTreeItemCurrentRole = Qt::UserRole + 12
};
explicit ProgressTreeModel( QObject* parent = nullptr );
virtual ~ProgressTreeModel();
// Reimplemented from QAbstractItemModel
Qt::ItemFlags flags( const QModelIndex& index ) const override;
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const override;
QModelIndex parent( const QModelIndex& index ) const override;
@ -40,6 +56,7 @@ public:
private:
void setupModelData();
QModelIndex indexFromItem( ProgressTreeItem* item );
ProgressTreeRoot* m_rootItem;
};

View File

@ -18,6 +18,9 @@
#include "ProgressTreeView.h"
#include "ProgressTreeDelegate.h"
#include "ViewManager.h"
ProgressTreeView* ProgressTreeView::s_instance = nullptr;
ProgressTreeView*
@ -43,7 +46,15 @@ ProgressTreeView::ProgressTreeView( QWidget* parent )
setAcceptDrops( false );
setUniformRowHeights( false );
setIndentation( 0 );
setSortingEnabled( false );
m_delegate = new ProgressTreeDelegate( this );
setItemDelegate( m_delegate );
QPalette plt = palette();
plt.setColor( QPalette::Base, QColor( "#292F34" ) );
setPalette( plt );
}
@ -56,6 +67,17 @@ ProgressTreeView::~ProgressTreeView()
void
ProgressTreeView::setModel( QAbstractItemModel* model )
{
if ( ProgressTreeView::model() )
return;
QTreeView::setModel( model );
expandAll();
connect( Calamares::ViewManager::instance(),
&Calamares::ViewManager::currentStepChanged,
this, [this]()
{
viewport()->update();
},
Qt::UniqueConnection );
}

View File

@ -21,6 +21,8 @@
#include <QTreeView>
class ProgressTreeDelegate;
class ProgressTreeView : public QTreeView
{
Q_OBJECT
@ -34,6 +36,7 @@ public:
private:
static ProgressTreeView* s_instance;
ProgressTreeDelegate* m_delegate;
};
#endif // PROGRESSTREEVIEW_H

View File

@ -18,6 +18,8 @@
#include "ViewStepItem.h"
#include "ProgressTreeModel.h"
#include "ViewManager.h"
#include "viewpages/ViewStep.h"
@ -36,8 +38,15 @@ ViewStepItem::appendChild( ProgressTreeItem* item )
QVariant
ViewStepItem::data( int column ) const
ViewStepItem::data( int role ) const
{
Q_UNUSED( column );
return m_step->prettyName();
if ( role == ProgressTreeModel::ProgressTreeItemTypeRole )
return ProgressTreeModel::ViewStep;
if ( role == ProgressTreeModel::ProgressTreeItemRole )
return this;
if ( role == Qt::DisplayRole )
return m_step->prettyName();
if ( role == ProgressTreeModel::ProgressTreeItemCurrentRole )
return Calamares::ViewManager::instance()->currentStep() == m_step;
return QVariant();
}

View File

@ -33,7 +33,7 @@ public:
void appendChild( ProgressTreeItem* item ) override;
QVariant data( int column ) const override;
QVariant data( int role ) const override;
private:
const Calamares::ViewStep* m_step;

View File

@ -49,7 +49,6 @@ public:
signals:
void nextStatusChanged( bool status );
void done();
};
}