mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-17 13:24:15 -05:00
added possibility to change the aspect ratio of thumbnails and replaced image warping by largest centered cropping
This commit is contained in:
parent
bebc9f2863
commit
af16659783
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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">
|
||||
|
Loading…
x
Reference in New Issue
Block a user