mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
fix(file transfer widget): QPushButton allows image to overflow
Introduced in 857dfbcd4c
Regression was due to fact that QPushButton allows icon to overflow.
This patch does:
1. Scale and crop icon to fit into button.
2. Avoid upscaling small images.
3. Refactor FileTransferWidget::showPreview() to load image from file
only once.
Closes #3042
This commit is contained in:
parent
8fa40d5c4f
commit
32d588a499
|
@ -502,22 +502,24 @@ void FileTransferWidget::showPreview(const QString &filename)
|
||||||
|
|
||||||
if (previewExtensions.contains(QFileInfo(filename).suffix()))
|
if (previewExtensions.contains(QFileInfo(filename).suffix()))
|
||||||
{
|
{
|
||||||
const int size = qMax(ui->previewButton->width(), ui->previewButton->height());
|
// Subtract to make border visible
|
||||||
|
const int size = qMax(ui->previewButton->width(), ui->previewButton->height()) - 4;
|
||||||
|
|
||||||
QPixmap pmap = QPixmap(filename).scaled(QSize(size, size),
|
const QImage image = QImage(filename);
|
||||||
Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
const QPixmap iconPixmap = scaleCropIntoSquare(QPixmap::fromImage(image), size);
|
||||||
ui->previewButton->setIcon(QIcon(pmap));
|
|
||||||
ui->previewButton->setIconSize(pmap.size());
|
ui->previewButton->setIcon(QIcon(iconPixmap));
|
||||||
|
ui->previewButton->setIconSize(iconPixmap.size());
|
||||||
ui->previewButton->show();
|
ui->previewButton->show();
|
||||||
// Show mouseover preview, but make sure it's not larger than 50% of the screen width/height
|
// Show mouseover preview, but make sure it's not larger than 50% of the screen width/height
|
||||||
QRect desktopSize = QApplication::desktop()->screenGeometry();
|
const QRect desktopSize = QApplication::desktop()->screenGeometry();
|
||||||
QImage image = QImage(filename).scaled(0.5 * desktopSize.width(),
|
const QImage previewImage = image.scaled(0.5 * desktopSize.width(),
|
||||||
0.5 * desktopSize.height(),
|
0.5 * desktopSize.height(),
|
||||||
Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
QByteArray imageData;
|
QByteArray imageData;
|
||||||
QBuffer buffer(&imageData);
|
QBuffer buffer(&imageData);
|
||||||
buffer.open(QIODevice::WriteOnly);
|
buffer.open(QIODevice::WriteOnly);
|
||||||
image.save(&buffer, "PNG");
|
previewImage.save(&buffer, "PNG");
|
||||||
buffer.close();
|
buffer.close();
|
||||||
ui->previewButton->setToolTip("<img src=data:image/png;base64," + imageData.toBase64() + "/>");
|
ui->previewButton->setToolTip("<img src=data:image/png;base64," + imageData.toBase64() + "/>");
|
||||||
}
|
}
|
||||||
|
@ -537,3 +539,30 @@ void FileTransferWidget::onPreviewButtonClicked()
|
||||||
{
|
{
|
||||||
handleButton(ui->previewButton);
|
handleButton(ui->previewButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPixmap FileTransferWidget::scaleCropIntoSquare(const QPixmap &source, const int targetSize)
|
||||||
|
{
|
||||||
|
QPixmap result;
|
||||||
|
|
||||||
|
// Make sure smaller-than-icon images (at least one dimension is smaller) will not be upscaled
|
||||||
|
if (source.width() < targetSize || source.height() < targetSize)
|
||||||
|
{
|
||||||
|
result = source;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = source.scaled(targetSize, targetSize,
|
||||||
|
Qt::KeepAspectRatioByExpanding,
|
||||||
|
Qt::SmoothTransformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then, image has to be cropped (if needed) so it will not overflow rectangle
|
||||||
|
// Only one dimension will be bigger after Qt::KeepAspectRatioByExpanding
|
||||||
|
if (result.width() > targetSize)
|
||||||
|
return result.copy((result.width() - targetSize) / 2, 0, targetSize, targetSize);
|
||||||
|
else if (result.height() > targetSize)
|
||||||
|
return result.copy(0, (result.height() - targetSize) / 2, targetSize, targetSize);
|
||||||
|
|
||||||
|
// Picture was rectangle in the first place, no cropping
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -72,6 +72,9 @@ private slots:
|
||||||
void onBottomButtonClicked();
|
void onBottomButtonClicked();
|
||||||
void onPreviewButtonClicked();
|
void onPreviewButtonClicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QPixmap scaleCropIntoSquare(const QPixmap &source, int targetSize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::FileTransferWidget *ui;
|
Ui::FileTransferWidget *ui;
|
||||||
ToxFile fileInfo;
|
ToxFile fileInfo;
|
||||||
|
|
|
@ -292,6 +292,9 @@
|
||||||
<property name="cursor">
|
<property name="cursor">
|
||||||
<cursorShape>PointingHandCursor</cursorShape>
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QPushButton{ border: 2px solid white }</string>
|
||||||
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../../res.qrc">
|
<iconset resource="../../../res.qrc">
|
||||||
<normaloff>:/ui/fileTransferInstance/no.svg</normaloff>:/ui/fileTransferInstance/no.svg</iconset>
|
<normaloff>:/ui/fileTransferInstance/no.svg</normaloff>:/ui/fileTransferInstance/no.svg</iconset>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user