Skip to content

Commit

Permalink
Move project list item delegate to new file
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed May 27, 2019
1 parent 4baafa9 commit 1da8eec
Show file tree
Hide file tree
Showing 7 changed files with 263 additions and 198 deletions.
2 changes: 2 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -64,6 +64,7 @@ SET(QGIS_APP_SRCS
qgsmaplayerstylecategoriesmodel.cpp
qgsmaplayerstyleguiutils.cpp
qgsmapsavedialog.cpp
qgsprojectlistitemdelegate.cpp
qgspuzzlewidget.cpp
qgsversionmigration.cpp
qgsrulebasedlabelingwidget.cpp
Expand Down Expand Up @@ -305,6 +306,7 @@ SET (QGIS_APP_MOC_HDRS
qgsmaplayerstyleguiutils.h
qgsmapsavedialog.h
qgspuzzlewidget.h
qgsprojectlistitemdelegate.h
qgsrulebasedlabelingwidget.h
qgssnappinglayertreemodel.h
qgssnappingwidget.h
Expand Down
173 changes: 173 additions & 0 deletions src/app/qgsprojectlistitemdelegate.cpp
@@ -0,0 +1,173 @@
/***************************************************************************
----------------------------------------------------
date : 22.5.2019
copyright : (C) 2019 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsprojectlistitemdelegate.h"
#include "qgis.h"

#include <QApplication>
#include <QPainter>
#include <QTextDocument>
#include <QAbstractTextDocumentLayout>

QgsProjectListItemDelegate::QgsProjectListItemDelegate( QObject *parent )
: QStyledItemDelegate( parent )
, mRoundedRectSizePixels( static_cast<int>( Qgis::UI_SCALE_FACTOR * QApplication::fontMetrics().height() * 0.5 ) )
{

}

void QgsProjectListItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
painter->save();

QTextDocument doc;
QPixmap icon = qvariant_cast<QPixmap>( index.data( Qt::DecorationRole ) );

QAbstractTextDocumentLayout::PaintContext ctx;
QStyleOptionViewItem optionV4 = option;

QColor color = optionV4.palette.color( QPalette::Active, QPalette::Window );
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_HasFocus )
{
color.setAlpha( 40 );
ctx.palette.setColor( QPalette::Text, optionV4.palette.color( QPalette::Active, QPalette::HighlightedText ) );

QStyle *style = QApplication::style();
style->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter, nullptr );
}
else if ( option.state & QStyle::State_Enabled )
{
if ( option.state & QStyle::State_Selected )
{
color.setAlpha( 40 );
}
ctx.palette.setColor( QPalette::Text, optionV4.palette.color( QPalette::Active, QPalette::Text ) );

QStyle *style = QApplication::style();
style->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter, nullptr );
}
else
{
ctx.palette.setColor( QPalette::Text, optionV4.palette.color( QPalette::Disabled, QPalette::Text ) );
}

painter->setRenderHint( QPainter::Antialiasing );
painter->setPen( QColor( 0, 0, 0, 0 ) );
painter->setBrush( QBrush( color ) );
painter->drawRoundedRect( option.rect.left() + 0.625 * mRoundedRectSizePixels, option.rect.top() + 0.625 * mRoundedRectSizePixels,
option.rect.width() - 2 * 0.625 * mRoundedRectSizePixels, option.rect.height() - 2 * 0.625 * mRoundedRectSizePixels, mRoundedRectSizePixels, mRoundedRectSizePixels );

int titleSize = static_cast<int>( QApplication::fontMetrics().height() * 1.1 );
int textSize = static_cast<int>( titleSize * 0.85 );

doc.setHtml( QStringLiteral( "<div style='font-size:%1px'><span style='font-size:%2px;font-weight:bold;'>%3%4</span><br>%5<br>%6</div>" ).arg( textSize ).arg( QString::number( titleSize ),
index.data( QgsProjectListItemDelegate::TitleRole ).toString(),
index.data( QgsProjectListItemDelegate::PinRole ).toBool() ? QStringLiteral( "<img src=\"qrc:/images/themes/default/pin.svg\">" ) : QString(),
mShowPath ? index.data( QgsProjectListItemDelegate::NativePathRole ).toString() : QString(),
index.data( QgsProjectListItemDelegate::CrsRole ).toString() ) );
doc.setTextWidth( option.rect.width() - ( !icon.isNull() ? icon.width() + 4.375 * mRoundedRectSizePixels : 4.375 * mRoundedRectSizePixels ) );

if ( !icon.isNull() )
{
painter->drawPixmap( option.rect.left() + 1.25 * mRoundedRectSizePixels, option.rect.top() + 1.25 * mRoundedRectSizePixels, icon );
}

painter->translate( option.rect.left() + ( !icon.isNull() ? icon.width() + 3.125 * mRoundedRectSizePixels : 1.875 * mRoundedRectSizePixels ), option.rect.top() + 1.875 * mRoundedRectSizePixels );
ctx.clip = QRect( 0, 0, option.rect.width() - ( !icon.isNull() ? icon.width() - 4.375 * mRoundedRectSizePixels : 3.125 * mRoundedRectSizePixels ), option.rect.height() - 3.125 * mRoundedRectSizePixels );
doc.documentLayout()->draw( painter, ctx );

painter->restore();
}

QSize QgsProjectListItemDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
QTextDocument doc;
QPixmap icon = qvariant_cast<QPixmap>( index.data( Qt::DecorationRole ) );

int width;
if ( option.rect.width() < 450 )
{
width = 450;
}
else
{
width = option.rect.width();
}

int titleSize = QApplication::fontMetrics().height() * 1.1;
int textSize = titleSize * 0.85;

doc.setHtml( QStringLiteral( "<div style='font-size:%1px;'><span style='font-size:%2px;font-weight:bold;'>%3%4</span><br>%5<br>%6</div>" ).arg( textSize ).arg( titleSize )
.arg( index.data( QgsProjectListItemDelegate::TitleRole ).toString(),
index.data( QgsProjectListItemDelegate::PinRole ).toBool() ? QStringLiteral( "<img src=\"qrc:/images/themes/default/pin.svg\">" ) : QString(),
index.data( QgsProjectListItemDelegate::NativePathRole ).toString(),
index.data( QgsProjectListItemDelegate::CrsRole ).toString() ) );
doc.setTextWidth( width - ( !icon.isNull() ? icon.width() + 4.375 * mRoundedRectSizePixels : 4.375 * mRoundedRectSizePixels ) );

return QSize( width, std::max( ( double ) doc.size().height() + 1.25 * mRoundedRectSizePixels, static_cast<double>( icon.height() ) ) + 2.5 * mRoundedRectSizePixels );
}

bool QgsProjectListItemDelegate::showPath() const
{
return mShowPath;
}

void QgsProjectListItemDelegate::setShowPath( bool value )
{
mShowPath = value;
}

QgsProjectPreviewImage::QgsProjectPreviewImage() = default;

QgsProjectPreviewImage::QgsProjectPreviewImage( const QString &path )
{
loadImageFromFile( path );
}

QgsProjectPreviewImage::QgsProjectPreviewImage( const QImage &image )
{
mImage = image;
}

void QgsProjectPreviewImage::loadImageFromFile( const QString &path )
{
mImage = QImage( path );
}

void QgsProjectPreviewImage::setImage( const QImage &image )
{
mImage = image;
}

QPixmap QgsProjectPreviewImage::pixmap() const
{
//nicely round corners so users don't get paper cuts
QImage previewImage( mImage.size(), QImage::Format_ARGB32 );
previewImage.fill( Qt::transparent );
QPainter previewPainter( &previewImage );
previewPainter.setRenderHint( QPainter::Antialiasing, true );
previewPainter.setPen( Qt::NoPen );
previewPainter.setBrush( Qt::black );
previewPainter.drawRoundedRect( 0, 0, previewImage.width(), previewImage.height(), 8, 8 );
previewPainter.setCompositionMode( QPainter::CompositionMode_SourceIn );
previewPainter.drawImage( 0, 0, mImage );
previewPainter.end();
return QPixmap::fromImage( previewImage );
}

bool QgsProjectPreviewImage::isNull() const
{
return mImage.isNull();
}
66 changes: 66 additions & 0 deletions src/app/qgsprojectlistitemdelegate.h
@@ -0,0 +1,66 @@
/***************************************************************************
----------------------------------------------------
date : 22.5.2019
copyright : (C) 2019 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSPROJECTLISTITEMDELEGATE_H
#define QGSPROJECTLISTITEMDELEGATE_H

#include <QStyledItemDelegate>

class QgsProjectPreviewImage
{
public:
QgsProjectPreviewImage();
QgsProjectPreviewImage( const QString &path );
QgsProjectPreviewImage( const QImage &image );

void loadImageFromFile( const QString &path );
void setImage( const QImage &image );
QPixmap pixmap() const;

bool isNull() const;

private:
QImage mImage;
};

class QgsProjectListItemDelegate : public QStyledItemDelegate
{
Q_OBJECT

public:
enum Role
{
TitleRole = Qt::UserRole + 1,
PathRole = Qt::UserRole + 2,
NativePathRole = Qt::UserRole + 3,
CrsRole = Qt::UserRole + 4,
PinRole = Qt::UserRole + 5
};

explicit QgsProjectListItemDelegate( QObject *parent = nullptr );
void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const override;

bool showPath() const;
void setShowPath( bool value );

private:

int mRoundedRectSizePixels = 5;
bool mShowPath = true;
QColor mColor = Qt::white;
};

#endif // QGSPROJECTLISTITEMDELEGATE_H

0 comments on commit 1da8eec

Please sign in to comment.