2017-06-22 09:45:47 +00:00
|
|
|
#include "ThumbnailImageItem.hxx"
|
|
|
|
|
|
|
|
#include <QSGSimpleTextureNode>
|
|
|
|
#include <QQuickWindow>
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QDir>
|
|
|
|
|
|
|
|
#include <Main/globals.hxx>
|
|
|
|
|
|
|
|
#include <simgear/package/Root.hxx>
|
|
|
|
#include <simgear/package/Package.hxx>
|
|
|
|
#include <simgear/package/Delegate.hxx>
|
|
|
|
#include <simgear/package/Catalog.hxx>
|
2017-09-29 08:51:20 +00:00
|
|
|
#include <simgear/package/Install.hxx>
|
2017-06-22 09:45:47 +00:00
|
|
|
|
|
|
|
using namespace simgear;
|
|
|
|
|
|
|
|
const int STANDARD_THUMBNAIL_HEIGHT = 128;
|
|
|
|
const int STANDARD_THUMBNAIL_WIDTH = 172;
|
|
|
|
|
|
|
|
class ThumbnailImageItem::ThumbnailPackageDelegate : public pkg::Delegate
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ThumbnailPackageDelegate(ThumbnailImageItem* o) : owner(o) {}
|
|
|
|
|
|
|
|
void catalogRefreshed(pkg::CatalogRef, StatusCode) override {}
|
|
|
|
void startInstall(pkg::InstallRef) override {}
|
|
|
|
void installProgress(pkg::InstallRef, unsigned int, unsigned int) override {}
|
|
|
|
void finishInstall(pkg::InstallRef, StatusCode ) override {}
|
|
|
|
|
|
|
|
void dataForThumbnail(const std::string& aThumbnailUrl,
|
|
|
|
size_t length, const uint8_t* bytes) override
|
|
|
|
{
|
|
|
|
if (aThumbnailUrl != owner->url().toString().toStdString()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QImage img = QImage::fromData(QByteArray::fromRawData(reinterpret_cast<const char*>(bytes), length));
|
|
|
|
if (img.isNull()) {
|
|
|
|
qWarning() << "failed to load image data for URL:" <<
|
|
|
|
QString::fromStdString(aThumbnailUrl);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
owner->setImage(img);
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbnailImageItem* owner;
|
|
|
|
};
|
|
|
|
|
2017-10-09 09:37:50 +00:00
|
|
|
ThumbnailImageItem::ThumbnailImageItem(QQuickItem* parent) :
|
|
|
|
QQuickItem(parent),
|
2017-06-22 09:45:47 +00:00
|
|
|
m_delegate(new ThumbnailPackageDelegate(this)),
|
|
|
|
m_maximumSize(9999, 9999)
|
|
|
|
{
|
|
|
|
globals->packageRoot()->addDelegate(m_delegate.get());
|
|
|
|
setFlag(ItemHasContents);
|
|
|
|
setImplicitWidth(STANDARD_THUMBNAIL_WIDTH);
|
|
|
|
setImplicitHeight(STANDARD_THUMBNAIL_HEIGHT);
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbnailImageItem::~ThumbnailImageItem()
|
|
|
|
{
|
|
|
|
globals->packageRoot()->removeDelegate(m_delegate.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
QSGNode *ThumbnailImageItem::updatePaintNode(QSGNode* oldNode, QQuickItem::UpdatePaintNodeData *)
|
|
|
|
{
|
|
|
|
if (m_image.isNull()) {
|
2017-10-09 09:37:50 +00:00
|
|
|
delete oldNode;
|
2017-06-22 09:45:47 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
QSGSimpleTextureNode* textureNode = static_cast<QSGSimpleTextureNode*>(oldNode);
|
2017-10-09 09:37:50 +00:00
|
|
|
if (m_imageDirty || !textureNode) {
|
|
|
|
if (!textureNode) {
|
|
|
|
textureNode = new QSGSimpleTextureNode;
|
|
|
|
textureNode->setOwnsTexture(true);
|
|
|
|
}
|
2017-06-22 09:45:47 +00:00
|
|
|
|
|
|
|
QSGTexture* tex = window()->createTextureFromImage(m_image);
|
|
|
|
textureNode->setTexture(tex);
|
2017-10-09 09:37:50 +00:00
|
|
|
textureNode->markDirty(QSGBasicGeometryNode::DirtyMaterial);
|
2017-06-22 09:45:47 +00:00
|
|
|
m_imageDirty = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
textureNode->setRect(QRectF(0, 0, width(), height()));
|
|
|
|
return textureNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
QUrl ThumbnailImageItem::url() const
|
|
|
|
{
|
|
|
|
return m_imageUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString ThumbnailImageItem::aircraftUri() const
|
|
|
|
{
|
|
|
|
return m_aircraftUri;
|
|
|
|
}
|
|
|
|
|
|
|
|
QSize ThumbnailImageItem::sourceSize() const
|
|
|
|
{
|
|
|
|
return m_image.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
QSize ThumbnailImageItem::maximumSize() const
|
|
|
|
{
|
|
|
|
return m_maximumSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbnailImageItem::setAircraftUri(QString uri)
|
|
|
|
{
|
|
|
|
if (m_aircraftUri == uri)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_aircraftUri = uri;
|
|
|
|
|
|
|
|
if (uri.startsWith("package:")) {
|
|
|
|
const std::string packageId = m_aircraftUri.toStdString().substr(8);
|
|
|
|
pkg::Root* root = globals->packageRoot();
|
|
|
|
pkg::PackageRef package = root->getPackageById(packageId);
|
|
|
|
if (package) {
|
|
|
|
int variant = package->indexOfVariant(packageId);
|
|
|
|
const auto thumbnail = package->thumbnailForVariant(variant);
|
|
|
|
m_imageUrl = QUrl(QString::fromStdString(thumbnail.url));
|
|
|
|
globals->packageRoot()->requestThumbnailData(m_imageUrl.toString().toStdString());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
QFileInfo aircraftSetPath(QUrl(uri).toLocalFile());
|
|
|
|
const QString thumbnailPath = aircraftSetPath.dir().filePath("thumbnail.jpg");
|
|
|
|
m_imageUrl = QUrl::fromLocalFile(thumbnailPath);
|
|
|
|
|
|
|
|
QImage img;
|
|
|
|
if (img.load(thumbnailPath)) {
|
|
|
|
setImage(img);
|
|
|
|
} else {
|
|
|
|
qWarning() << Q_FUNC_INFO << "failed to load thumbnail from:" << thumbnailPath;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
emit aircraftUriChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbnailImageItem::setMaximumSize(QSize maximumSize)
|
|
|
|
{
|
|
|
|
if (m_maximumSize == maximumSize)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_maximumSize = maximumSize;
|
|
|
|
emit maximumSizeChanged(m_maximumSize);
|
|
|
|
|
|
|
|
if (!m_image.isNull()) {
|
|
|
|
setImplicitSize(qMin(m_maximumSize.width(), m_image.width()),
|
|
|
|
qMin(m_maximumSize.height(), m_image.height()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbnailImageItem::setImage(QImage image)
|
|
|
|
{
|
|
|
|
m_image = image;
|
|
|
|
m_imageDirty = true;
|
|
|
|
setImplicitSize(qMin(m_maximumSize.width(), m_image.width()),
|
|
|
|
qMin(m_maximumSize.height(), m_image.height()));
|
|
|
|
emit sourceSizeChanged();
|
|
|
|
update();
|
|
|
|
}
|