Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (3)
......@@ -111,7 +111,6 @@ Widgets.NavigableFocusScope {
width: VLCStyle.expandCover_music_width
radius: VLCStyle.expandCover_music_radius
source: model.cover || VLCStyle.noArtAlbum
sourceSize: Qt.size(width, height)
}
Widgets.ListCoverShadow {
......
......@@ -100,7 +100,6 @@ Widgets.NavigableFocusScope {
anchors.fill: parent
source: model.thumbnail || VLCStyle.noArtCover
sourceSize: Qt.size(width, height)
radius: VLCStyle.gridCover_radius
}
......
......@@ -27,12 +27,15 @@
#include "roundimage.hpp"
#include <QBrush>
#include <qhashfunctions.h>
#include <QBuffer>
#include <QCache>
#include <QImage>
#include <QImageReader>
#include <QPainter>
#include <QPainterPath>
#include <QPen>
#include <QQuickWindow>
#include <QSvgRenderer>
#include <QGuiApplication>
#ifdef QT_NETWORK_LIB
......@@ -43,6 +46,31 @@
namespace
{
struct ImageCacheKey
{
QUrl url;
QSize size;
qreal radius;
};
bool operator ==(const ImageCacheKey &lhs, const ImageCacheKey &rhs)
{
return lhs.radius == rhs.radius && lhs.size == rhs.size && lhs.url == rhs.url;
}
uint qHash(const ImageCacheKey &key, uint seed)
{
QtPrivate::QHashCombine hash;
seed = hash(seed, key.url);
seed = hash(seed, key.size.width());
seed = hash(seed, key.size.height());
seed = hash(seed, key.radius);
return seed;
}
// images are cached (result of RoundImageGenerator) with the cost calculated from QImage::sizeInBytes
QCache<ImageCacheKey, QImage> imageCache(2 * 1024 * 1024); // 2 MiB
QString getPath(const QUrl &url)
{
QString path = url.isLocalFile() ? url.toLocalFile() : url.toString();
......@@ -51,7 +79,7 @@ namespace
return path;
}
QByteArray readFile(const QUrl &url)
std::unique_ptr<QIODevice> getReadable(const QUrl &url)
{
#ifdef QT_NETWORK_LIB
if (url.scheme() == "http" || url.scheme() == "https")
......@@ -62,16 +90,34 @@ namespace
QEventLoop loop;
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
return reply->readAll();
class DataOwningBuffer : public QBuffer
{
public:
DataOwningBuffer(const QByteArray &data) : m_data {data}
{
setBuffer(&m_data);
}
~DataOwningBuffer()
{
close();
setBuffer(nullptr);
}
private:
QByteArray m_data;
};
auto file = std::make_unique<DataOwningBuffer>(reply->readAll());
file->open(QIODevice::ReadOnly);
return file;
}
#endif
QByteArray data;
QString path = getPath(url);
QFile file(path);
if (file.open(QIODevice::ReadOnly))
data = file.readAll();
return data;
auto file = std::make_unique<QFile>(getPath(url));
file->open(QIODevice::ReadOnly);
return file;
}
}
......@@ -86,6 +132,8 @@ RoundImage::RoundImage(QQuickItem *parent) : QQuickPaintedItem {parent}
void RoundImage::paint(QPainter *painter)
{
if (m_roundImage.isNull())
return;
painter->drawImage(QPointF {0., 0.}, m_roundImage, m_roundImage.rect());
}
......@@ -103,7 +151,9 @@ void RoundImage::componentComplete()
Q_ASSERT(!m_isComponentComplete); // classBegin is not called?
m_isComponentComplete = true;
if (!m_source.isEmpty())
updateSource();
regenerateRoundImage();
else
m_roundImage = {};
}
QUrl RoundImage::source() const
......@@ -116,11 +166,6 @@ qreal RoundImage::radius() const
return m_radius;
}
QSizeF RoundImage::sourceSize() const
{
return m_sourceSize;
}
void RoundImage::setSource(QUrl source)
{
if (m_source == source)
......@@ -128,7 +173,7 @@ void RoundImage::setSource(QUrl source)
m_source = source;
emit sourceChanged(m_source);
updateSource();
regenerateRoundImage();
}
void RoundImage::setRadius(qreal radius)
......@@ -141,16 +186,6 @@ void RoundImage::setRadius(qreal radius)
regenerateRoundImage();
}
void RoundImage::setSourceSize(QSizeF sourceSize)
{
if (m_sourceSize == sourceSize)
return;
m_sourceSize = sourceSize;
emit sourceSizeChanged(m_sourceSize);
updateSource();
}
void RoundImage::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
{
if (change == QQuickItem::ItemDevicePixelRatioHasChanged)
......@@ -165,35 +200,12 @@ void RoundImage::setDPR(const qreal value)
return;
m_dpr = value;
if (m_sourceSize.isValid())
updateSource(); // "effectiveSourceSize" is changed
else
regenerateRoundImage();
}
void RoundImage::updateSource()
{
if (!m_isComponentComplete)
return;
const QSizeF effectiveSourceSize = m_sourceSize.isValid() ? m_sourceSize * m_dpr : QSize {};
m_loader.reset(new Loader({m_source, effectiveSourceSize}));
connect(m_loader.get(), &BaseAsyncTask::result, this, [this]()
{
m_sourceImage = m_loader->takeResult();
m_loader.reset();
regenerateRoundImage();
});
m_loader->start(*QThreadPool::globalInstance());
regenerateRoundImage();
}
void RoundImage::regenerateRoundImage()
{
if (!m_isComponentComplete
|| m_enqueuedGeneration
|| m_loader /* when loader ends it will call regenerateRoundImage */)
if (!m_isComponentComplete || m_enqueuedGeneration)
return;
// use Qt::QueuedConnection to delay generation, so that dependent properties
......@@ -204,15 +216,30 @@ void RoundImage::regenerateRoundImage()
{
m_enqueuedGeneration = false;
const qreal scaleWidth = this->width() * m_dpr;
const qreal scaledHeight = this->height() * m_dpr;
const qreal scaledRadius = this->radius() * m_dpr;
const ImageCacheKey key {source(), QSizeF {scaleWidth, scaledHeight}.toSize(), scaledRadius};
if (auto image = imageCache.object(key)) // should only by called in mainthread
{
m_roundImage = *image;
update();
return;
}
// Image is generated in size factor of `m_dpr` to avoid scaling artefacts when
// generated image is set with device pixel ratio
m_roundImageGenerator.reset(new RoundImageGenerator({width() * m_dpr, height() * m_dpr, radius() * m_dpr, m_sourceImage}));
connect(m_roundImageGenerator.get(), &BaseAsyncTask::result, this, [this]()
m_roundImageGenerator.reset(new RoundImageGenerator(m_source, scaleWidth, scaledHeight, scaledRadius));
connect(m_roundImageGenerator.get(), &BaseAsyncTask::result, this, [this, key]()
{
m_roundImage = m_roundImageGenerator->takeResult();
m_roundImage.setDevicePixelRatio(m_dpr);
m_roundImageGenerator.reset();
if (!m_roundImage.isNull())
imageCache.insert(key, new QImage(m_roundImage), m_roundImage.sizeInBytes());
update();
});
......@@ -220,27 +247,41 @@ void RoundImage::regenerateRoundImage()
}, Qt::QueuedConnection);
}
RoundImage::Loader::Loader(const Params &params) : params {params} {}
RoundImage::ImagePtr RoundImage::Loader::execute()
RoundImage::RoundImageGenerator::RoundImageGenerator(const QUrl &source, qreal width, qreal height, qreal radius)
: source(source)
, width(width)
, height(height)
, radius(radius)
{
return Image::getImage(params.source, params.sourceSize);
}
RoundImage::RoundImageGenerator::RoundImageGenerator(const RoundImage::RoundImageGenerator::Params &params) : params {params} {}
QImage RoundImage::RoundImageGenerator::execute()
{
if (params.width <= 0 || params.height <= 0)
if (width <= 0 || height <= 0)
return {};
auto file = getReadable(source);
if (!file || !file->isOpen())
return {};
QImage target(params.width, params.height, QImage::Format_ARGB32);
QImageReader sourceReader(file.get());
// do PreserveAspectCrop
const QSizeF size {width, height};
QSizeF defaultSize = sourceReader.size();
if (!defaultSize.isValid())
defaultSize = size;
const qreal ratio = std::max(size.width() / defaultSize.width(), size.height() / defaultSize.height());
const QSizeF targetSize = defaultSize * ratio;
const QPointF alignedCenteredTopLeft {(size.width() - targetSize.width()) / 2., (size.height() - targetSize.height()) / 2.};
sourceReader.setScaledSize(targetSize.toSize());
QImage target(width, height, QImage::Format_ARGB32);
if (target.isNull())
return target;
target.fill(Qt::transparent);
if (Q_UNLIKELY(!params.image))
return target;
QPainter painter;
painter.begin(&target);
......@@ -248,77 +289,11 @@ QImage RoundImage::RoundImageGenerator::execute()
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
QPainterPath path;
path.addRoundedRect(0, 0, params.width, params.height, params.radius, params.radius);
path.addRoundedRect(0, 0, width, height, radius, radius);
painter.setClipPath(path);
params.image->paint(&painter, {params.width, params.height});
painter.drawImage({alignedCenteredTopLeft, targetSize}, sourceReader.read());
painter.end();
return target;
}
std::shared_ptr<RoundImage::Image> RoundImage::Image::getImage(const QUrl &source, const QSizeF &sourceSize)
{
class QtImage : public Image
{
public:
QtImage(const QByteArray &data, const QSizeF &sourceSize)
{
m_image.loadFromData(data);
if (sourceSize.isValid())
m_image = m_image.scaled(sourceSize.toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
void paint(QPainter *painter, const QSizeF &size) override
{
if (m_image.isNull() || !painter || !size.isValid())
return;
auto image = m_image;
// do PreserveAspectCrop
const qreal ratio = std::max(qreal(size.width()) / image.width(), qreal(size.height()) / image.height());
if (ratio != 0.0)
image = image.scaled(qRound(image.width() * ratio), qRound(image.height() * ratio),
Qt::IgnoreAspectRatio, // aspect ratio handled manually by using `ratio`
Qt::SmoothTransformation);
const QPointF alignedCenteredTopLeft {(size.width() - image.width()) / 2, (size.height() - image.height()) / 2};
painter->drawImage(alignedCenteredTopLeft, image);
}
private:
QImage m_image;
};
class SVGImage : public Image
{
public:
SVGImage(const QByteArray &data)
{
m_svg.load(data);
}
void paint(QPainter *painter, const QSizeF &size) override
{
if (!m_svg.isValid() || !painter || !size.isValid())
return;
// do PreserveAspectCrop
const QSizeF defaultSize = m_svg.defaultSize();
const qreal ratio = std::max(size.width() / defaultSize.width(), size.height() / defaultSize.height());
const QSizeF targetSize = defaultSize * ratio;
const QPointF alignedCenteredTopLeft {(size.width() - targetSize.width()) / 2., (size.height() - targetSize.height()) / 2.};
m_svg.render(painter, QRectF {alignedCenteredTopLeft, targetSize});
}
private:
QSvgRenderer m_svg;
};
const QByteArray data = readFile(source);
if (source.toString().endsWith(".svg"))
return std::make_shared<SVGImage>(data);
return std::make_shared<QtImage>(data, sourceSize);
}
......@@ -27,8 +27,7 @@
#include "util/asynctask.hpp"
#include <QPixmap>
#include <QPainter>
#include <QImage>
#include <QQuickPaintedItem>
#include <QUrl>
......@@ -39,9 +38,6 @@ class RoundImage : public QQuickPaintedItem
// url of the image
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
// sets the maximum number of pixels stored for the loaded image so that large images do not use more memory than necessary
Q_PROPERTY(QSizeF sourceSize READ sourceSize WRITE setSourceSize NOTIFY sourceSizeChanged)
Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
public:
......@@ -54,12 +50,10 @@ public:
QUrl source() const;
qreal radius() const;
QSizeF sourceSize() const;
public slots:
void setSource(QUrl source);
void setRadius(qreal radius);
void setSourceSize(QSizeF sourceSize);
signals:
void sourceChanged(QUrl source);
......@@ -70,65 +64,27 @@ protected:
void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override;
private:
class Image
{
public:
static std::shared_ptr<Image> getImage(const QUrl &source, const QSizeF &sourceSize);
virtual ~Image() = default;
// must be reentrant
virtual void paint(QPainter *painter, const QSizeF &size) = 0;
};
using ImagePtr = std::shared_ptr<Image>;
class Loader : public AsyncTask<ImagePtr>
{
public:
struct Params
{
QUrl source;
QSizeF sourceSize;
};
Loader(const Params &params);
ImagePtr execute();
private:
const Params params;
};
class RoundImageGenerator : public AsyncTask<QImage>
{
public:
struct Params
{
qreal width;
qreal height;
qreal radius;
ImagePtr image;
};
RoundImageGenerator(const Params &params);
RoundImageGenerator(const QUrl &source, qreal width, qreal height, qreal radius);
QImage execute();
private:
const Params params;
QUrl source;
qreal width;
qreal height;
qreal radius;
};
void setDPR(qreal value);
void updateSource();
void regenerateRoundImage();
QUrl m_source;
ImagePtr m_sourceImage;
qreal m_radius = 0.0;
QSizeF m_sourceSize;
qreal m_dpr = 1.0; // device pixel ratio
QImage m_roundImage;
TaskHandle<Loader> m_loader {};
TaskHandle<RoundImageGenerator> m_roundImageGenerator {};
bool m_enqueuedGeneration = false;
......
......@@ -37,7 +37,6 @@ RoundImage {
height: VLCStyle.listAlbumCover_height
width: VLCStyle.listAlbumCover_width
sourceSize: Qt.size(width, height)
Loader {
id: overlay
......