added possibility to change the aspect ratio of thumbnails and replaced image warping by largest centered cropping

This commit is contained in:
csoler 2020-09-04 23:36:41 +02:00
parent bebc9f2863
commit af16659783
5 changed files with 93 additions and 26 deletions

View File

@ -24,6 +24,8 @@
#include "gui/common/FilesDefs.h"
#include "gui/gxschannels/GxsChannelPostThumbnail.h"
const float ChannelPostThumbnailView::DEFAULT_SIZE_IN_FONT_HEIGHT = 5.0;
ChannelPostThumbnailView::ChannelPostThumbnailView(const RsGxsChannelPost& post,uint32_t flags,QWidget *parent)
: QWidget(parent),mPostTitle(nullptr),mFlags(flags), mAspectRatio(ASPECT_RATIO_2_3)
{
@ -115,8 +117,6 @@ void ChannelPostThumbnailView::init(const RsGxsChannelPost& post)
layout->addWidget(mPostImage);
setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);
QFontMetricsF fm(font());
int W = THUMBNAIL_OVERSAMPLE_FACTOR * thumbnail_w() * fm.height() ;
int H = THUMBNAIL_OVERSAMPLE_FACTOR * thumbnail_h() * fm.height() ;
@ -134,31 +134,56 @@ void ChannelPostThumbnailView::init(const RsGxsChannelPost& post)
QFont font = mPostTitle->font();
font.setPointSizeF(DEFAULT_SIZE_IN_FONT_HEIGHT / 5.0 * font.pointSizeF());
if(is_msg_new)
{
font.setBold(true);
mPostTitle->setFont(font);
}
mPostTitle->setFont(font);
mPostTitle->setMaximumWidth(W);
mPostTitle->setMaximumHeight(3*fm.height());
mPostTitle->setWordWrap(true);
mPostTitle->adjustSize();
setMinimumHeight(H + mPostTitle->height() + 0.5*fm.height());
setMaximumHeight(H + mPostTitle->height() + 0.5*fm.height());
}
setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::MinimumExpanding);
layout->addStretch();
setLayout(layout);
adjustSize();
update();
}
QSize ChannelPostThumbnailView::actualSize() const
{
QFontMetricsF fm(font());
if(mPostTitle != nullptr)
{
QMargins cm = layout()->contentsMargins();
return QSize(width(),
mPostTitle->height() + mPostImage->height() + 0.5*fm.height()
+ cm.top() + cm.bottom() + layout()->spacing());
}
else
return size();
}
float ChannelPostThumbnailView::thumbnail_w() const
{
switch(mAspectRatio)
{
default:
case ASPECT_RATIO_1_1:
case ASPECT_RATIO_UNKNOWN: return 5;
case ASPECT_RATIO_UNKNOWN: return DEFAULT_SIZE_IN_FONT_HEIGHT;
case ASPECT_RATIO_2_3: return 4;
case ASPECT_RATIO_16_9: return 5 * 16.0/9.0;
case ASPECT_RATIO_2_3: return DEFAULT_SIZE_IN_FONT_HEIGHT;
case ASPECT_RATIO_16_9: return DEFAULT_SIZE_IN_FONT_HEIGHT;
}
}
float ChannelPostThumbnailView::thumbnail_h() const
@ -167,17 +192,17 @@ float ChannelPostThumbnailView::thumbnail_h() const
{
default:
case ASPECT_RATIO_1_1:
case ASPECT_RATIO_UNKNOWN: return 5;
case ASPECT_RATIO_UNKNOWN: return DEFAULT_SIZE_IN_FONT_HEIGHT;
case ASPECT_RATIO_2_3: return 6;
case ASPECT_RATIO_16_9: return 5;
case ASPECT_RATIO_2_3: return DEFAULT_SIZE_IN_FONT_HEIGHT * 3.0/2.0;
case ASPECT_RATIO_16_9: return DEFAULT_SIZE_IN_FONT_HEIGHT * 9.0/16.0;
}
}
void ZoomableLabel::reset()
{
mCenterX = mFullImage.width()/2.0;
mCenterX = mFullImage.height()/2.0;
mCenterY = mFullImage.height()/2.0;
mZoomFactor = 1.0/std::max(width() / (float)mFullImage.width(), height()/(float)mFullImage.height());
updateView();
@ -257,9 +282,7 @@ void ZoomableLabel::setPicture(const QPixmap& pix)
{
mFullImage = pix;
mCenterX = pix.width()/2.0;
mCenterY = pix.height()/2.0;
reset();
updateView();
}
void ZoomableLabel::resizeEvent(QResizeEvent *e)

View File

@ -78,7 +78,7 @@ public:
} AspectRatio;
// This variable determines the zoom factor on the text below thumbnails. 2.0 is mostly correct for all screen.
static constexpr float THUMBNAIL_OVERSAMPLE_FACTOR = 2.0;
static constexpr float THUMBNAIL_OVERSAMPLE_FACTOR = 2.0;
static constexpr uint32_t FLAG_NONE = 0x00;
static constexpr uint32_t FLAG_SHOW_TEXT = 0x01;
@ -102,7 +102,15 @@ public:
QPixmap getCroppedScaledPicture() const { return mPostImage->extractCroppedScaledPicture() ; }
void setText(const QString& s);
// This is used to allow to render the widget into a pixmap without the white space that Qt adds vertically. There is *no way* apparently
// to get rid of that bloody space. It depends on the aspect ratio of the image and it only shows up when the text label is shown.
// The label however has a correct size. It seems that Qt doesn't like widgets with horizontal aspect ratio and forces the size accordingly.
QSize actualSize() const ;
private:
static const float DEFAULT_SIZE_IN_FONT_HEIGHT ;
float thumbnail_w() const;
float thumbnail_h() const;

View File

@ -106,6 +106,10 @@ void ChannelPostDelegate::zoom(bool zoom_or_unzoom)
mZoom = 2.0;
}
void ChannelPostDelegate::setAspectRatio(ChannelPostThumbnailView::AspectRatio r)
{
mAspectRatio = r;
}
void ChannelPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
// prepare
@ -119,10 +123,13 @@ void ChannelPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem &
if(mUseGrid || index.column()==0)
{
// Draw a thumnail
// Draw a thumbnail
uint32_t flags = (mUseGrid)?(ChannelPostThumbnailView::FLAG_SHOW_TEXT):0;
ChannelPostThumbnailView w(post,flags);
w.setAspectRatio(mAspectRatio);
w.updateGeometry();
w.adjustSize();
QPixmap pixmap(w.size());
@ -133,6 +140,19 @@ void ChannelPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem &
w.render(&pixmap,QPoint(),QRegion(),QWidget::DrawChildren );// draw the widgets, not the background
// We extract from the pixmap the part of the widget that we want. Saddly enough, Qt adds some white space
// below the widget and there is no way to control that.
pixmap = pixmap.copy(QRect(0,0,w.actualSize().width(),w.actualSize().height()));
if(index.row()==0 && index.column()==0)
{
QFile file("yourFile.png");
file.open(QIODevice::WriteOnly);
pixmap.save(&file, "PNG");
file.close();
}
if(mUseGrid || index.column()==0)
{
if(mZoom != 1.0)
@ -143,15 +163,12 @@ void ChannelPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem &
QPainter p(&pixmap);
QFontMetricsF fm(option.font);
if(mUseGrid)
p.drawPixmap(mZoom*QPoint(6.2*fm.height(),6.9*fm.height()),FilesDefs::getPixmapFromQtResourcePath(STAR_OVERLAY_IMAGE).scaled(mZoom*7*fm.height(),mZoom*7*fm.height(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
else
p.drawPixmap(mZoom*QPoint(6.3*fm.height(),-3.7*fm.height()),FilesDefs::getPixmapFromQtResourcePath(STAR_OVERLAY_IMAGE).scaled(mZoom*7*fm.height(),mZoom*7*fm.height(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
p.drawPixmap(mZoom*QPoint(0.1*fm.height(),-3.6*fm.height()),FilesDefs::getPixmapFromQtResourcePath(STAR_OVERLAY_IMAGE).scaled(mZoom*7*fm.height(),mZoom*7*fm.height(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
}
}
painter->drawPixmap(option.rect.topLeft(),
pixmap.scaled(option.rect.width(),option.rect.width()*w.height()/(float)w.width(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
pixmap.scaled(option.rect.width(),option.rect.width()*pixmap.height()/(float)pixmap.width(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
}
else
{
@ -188,12 +205,25 @@ QSize ChannelPostDelegate::sizeHint(const QStyleOptionViewItem& option, const QM
QFontMetricsF fm(option.font);
uint32_t size_diff = mUseGrid?0:(2*fm.height());
RsGxsChannelPost post = index.data(Qt::UserRole).value<RsGxsChannelPost>() ;
uint32_t flags = (mUseGrid)?(ChannelPostThumbnailView::FLAG_SHOW_TEXT):0;
ChannelPostThumbnailView w(post,flags);
w.setAspectRatio(mAspectRatio);
w.updateGeometry();
w.adjustSize();
//std::cerr << "w.size(): " << w.width() << " x " << w.height() << ". Actual size: " << w.actualSize().width() << " x " << w.actualSize().height() << std::endl;
float aspect_ratio = w.actualSize().height()/(float)w.actualSize().width();
float cell_width = mZoom*COLUMN_SIZE_FONT_FACTOR_W*fm.height();
float cell_height = mZoom*COLUMN_SIZE_FONT_FACTOR_W*fm.height()*aspect_ratio;
if(mUseGrid || index.column()==0)
return QSize(mZoom*COLUMN_SIZE_FONT_FACTOR_W*fm.height(),mZoom*COLUMN_SIZE_FONT_FACTOR_H*fm.height()-size_diff);
return QSize(cell_width,cell_height);
else
return QSize(option.rect.width()-mZoom*COLUMN_SIZE_FONT_FACTOR_W*fm.height(),mZoom*COLUMN_SIZE_FONT_FACTOR_H*fm.height()-size_diff);
return QSize(option.rect.width()-cell_width,cell_height);
}
void ChannelPostDelegate::setWidgetGrid(bool use_grid)
@ -305,6 +335,8 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI
ui->postsTree->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);// more beautiful if we scroll at pixel level
ui->postsTree->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
mChannelPostsDelegate->setAspectRatio(ChannelPostThumbnailView::ASPECT_RATIO_16_9);
connect(ui->postsTree,SIGNAL(zoomRequested(bool)),this,SLOT(updateZoomFactor(bool)));
ui->channelPostFiles_TV->setModel(mChannelPostFilesModel = new RsGxsChannelPostFilesModel(this));

View File

@ -28,6 +28,8 @@
#include "gui/gxs/GxsMessageFramePostWidget.h"
#include "gui/feeds/FeedHolder.h"
#include "GxsChannelPostThumbnail.h"
namespace Ui {
class GxsChannelPostsWidgetWithModel;
}
@ -69,6 +71,7 @@ class ChannelPostDelegate: public QAbstractItemDelegate
int cellSize(int col, const QFont& font, uint32_t parent_width) const;
void zoom(bool zoom_or_unzoom) ;
void setWidgetGrid(bool use_grid) ;
void setAspectRatio(ChannelPostThumbnailView::AspectRatio r) ;
private:
static constexpr float IMAGE_MARGIN_FACTOR = 1.0;
@ -78,6 +81,7 @@ class ChannelPostDelegate: public QAbstractItemDelegate
float mZoom; // zoom factor for the whole thumbnail
bool mUseGrid; // wether we use the grid widget or the list widget
ChannelPostThumbnailView::AspectRatio mAspectRatio;
};
class GxsChannelPostsWidgetWithModel: public GxsMessageFrameWidget

View File

@ -181,7 +181,7 @@
<item>
<widget class="QTabWidget" name="channel_TW">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tab_3">
<attribute name="title">