GH-1072 split resource system to UI and logic parts
This commit is contained in:
parent
cca6700134
commit
271ad9e4fd
@ -120,6 +120,12 @@ SET(MULTIMC_SOURCES
|
|||||||
BuildConfig.h
|
BuildConfig.h
|
||||||
${PROJECT_BINARY_DIR}/BuildConfig.cpp
|
${PROJECT_BINARY_DIR}/BuildConfig.cpp
|
||||||
|
|
||||||
|
# Resource handlers and transformers
|
||||||
|
handlers/IconResourceHandler.cpp
|
||||||
|
handlers/IconResourceHandler.h
|
||||||
|
handlers/WebResourceHandler.cpp
|
||||||
|
handlers/WebResourceHandler.h
|
||||||
|
|
||||||
# GUI - general utilities
|
# GUI - general utilities
|
||||||
GuiUtil.h
|
GuiUtil.h
|
||||||
GuiUtil.cpp
|
GuiUtil.cpp
|
||||||
|
@ -48,7 +48,8 @@
|
|||||||
|
|
||||||
#include "trans/TranslationDownloader.h"
|
#include "trans/TranslationDownloader.h"
|
||||||
#include "resources/Resource.h"
|
#include "resources/Resource.h"
|
||||||
#include "resources/IconResourceHandler.h"
|
#include "handlers/IconResourceHandler.h"
|
||||||
|
#include "handlers/WebResourceHandler.h"
|
||||||
|
|
||||||
#include "ftb/FTBPlugin.h"
|
#include "ftb/FTBPlugin.h"
|
||||||
|
|
||||||
@ -341,36 +342,18 @@ void MultiMC::initIcons()
|
|||||||
ENV.m_icons->directoryChanged(value.toString());
|
ENV.m_icons->directoryChanged(value.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
Resource::registerTransformer([](const QVariantMap &map) -> QIcon
|
//FIXME: none of this should be here.
|
||||||
{
|
Resource::registerHandler<WebResourceHandler>("web");
|
||||||
QIcon icon;
|
Resource::registerHandler<IconResourceHandler>("icon");
|
||||||
for (auto it = map.constBegin(); it != map.constEnd(); ++it)
|
|
||||||
{
|
|
||||||
icon.addFile(it.key(), QSize(it.value().toInt(), it.value().toInt()));
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
});
|
|
||||||
Resource::registerTransformer([](const QVariantMap &map) -> QPixmap
|
|
||||||
{
|
|
||||||
QVariantList sizes = map.values();
|
|
||||||
if (sizes.isEmpty())
|
|
||||||
{
|
|
||||||
return QPixmap();
|
|
||||||
}
|
|
||||||
std::sort(sizes.begin(), sizes.end());
|
|
||||||
if (sizes.last().toInt() != -1) // only scalable available
|
|
||||||
{
|
|
||||||
return QPixmap(map.key(sizes.last()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return QPixmap();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Resource::registerTransformer([](const QByteArray &data) -> QPixmap
|
Resource::registerTransformer([](const QByteArray &data) -> QPixmap
|
||||||
{ return QPixmap::fromImage(QImage::fromData(data)); });
|
{
|
||||||
|
return QPixmap::fromImage(QImage::fromData(data));
|
||||||
|
});
|
||||||
Resource::registerTransformer([](const QByteArray &data) -> QIcon
|
Resource::registerTransformer([](const QByteArray &data) -> QIcon
|
||||||
{ return QIcon(QPixmap::fromImage(QImage::fromData(data))); });
|
{
|
||||||
|
return QIcon(QPixmap::fromImage(QImage::fromData(data)));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,16 +46,12 @@ set(LOGIC_SOURCES
|
|||||||
QObjectPtr.h
|
QObjectPtr.h
|
||||||
|
|
||||||
# Resources
|
# Resources
|
||||||
resources/IconResourceHandler.cpp
|
|
||||||
resources/IconResourceHandler.h
|
|
||||||
resources/Resource.cpp
|
resources/Resource.cpp
|
||||||
resources/Resource.h
|
resources/Resource.h
|
||||||
resources/ResourceHandler.cpp
|
resources/ResourceHandler.cpp
|
||||||
resources/ResourceHandler.h
|
resources/ResourceHandler.h
|
||||||
resources/ResourceObserver.cpp
|
resources/ResourceObserver.cpp
|
||||||
resources/ResourceObserver.h
|
resources/ResourceObserver.h
|
||||||
resources/WebResourceHandler.cpp
|
|
||||||
resources/WebResourceHandler.h
|
|
||||||
resources/ResourceProxyModel.h
|
resources/ResourceProxyModel.h
|
||||||
resources/ResourceProxyModel.cpp
|
resources/ResourceProxyModel.cpp
|
||||||
|
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
#include "IconResourceHandler.h"
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
QString IconResourceHandler::m_theme = "multimc";
|
|
||||||
QList<std::weak_ptr<IconResourceHandler>> IconResourceHandler::m_iconHandlers;
|
|
||||||
|
|
||||||
IconResourceHandler::IconResourceHandler(const QString &key)
|
|
||||||
: m_key(key)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void IconResourceHandler::setTheme(const QString &theme)
|
|
||||||
{
|
|
||||||
m_theme = theme;
|
|
||||||
|
|
||||||
// notify everyone
|
|
||||||
for (auto handler : m_iconHandlers)
|
|
||||||
{
|
|
||||||
std::shared_ptr<IconResourceHandler> ptr = handler.lock();
|
|
||||||
if (ptr)
|
|
||||||
{
|
|
||||||
ptr->setResult(ptr->get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void IconResourceHandler::init(std::shared_ptr<ResourceHandler> &ptr)
|
|
||||||
{
|
|
||||||
m_iconHandlers.append(std::dynamic_pointer_cast<IconResourceHandler>(ptr));
|
|
||||||
// we always have a result, so lets report it now!
|
|
||||||
setResult(get());
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant IconResourceHandler::get() const
|
|
||||||
{
|
|
||||||
const QDir iconsDir = QDir(":/icons/" + m_theme);
|
|
||||||
|
|
||||||
QVariantMap out;
|
|
||||||
for (const QFileInfo &sizeInfo : iconsDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot))
|
|
||||||
{
|
|
||||||
const QDir dir = QDir(sizeInfo.absoluteFilePath());
|
|
||||||
const QString dirName = sizeInfo.fileName();
|
|
||||||
const int size = dirName.left(dirName.indexOf('x')).toInt();
|
|
||||||
if (dir.exists(m_key + ".png") && dirName != "scalable")
|
|
||||||
{
|
|
||||||
out.insert(dir.absoluteFilePath(m_key + ".png"), size);
|
|
||||||
}
|
|
||||||
else if (dir.exists(m_key + ".svg") && dirName == "scalable")
|
|
||||||
{
|
|
||||||
out.insert(dir.absoluteFilePath(m_key + ".svg"), size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out.isEmpty())
|
|
||||||
{
|
|
||||||
qWarning() << "Couldn't find any icons for" << m_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "ResourceHandler.h"
|
|
||||||
|
|
||||||
#include "multimc_logic_export.h"
|
|
||||||
|
|
||||||
class MULTIMC_LOGIC_EXPORT IconResourceHandler : public ResourceHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit IconResourceHandler(const QString &key);
|
|
||||||
|
|
||||||
/// Sets the current theme and notifies all IconResourceHandlers of the change
|
|
||||||
static void setTheme(const QString &theme);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// we need to keep track of all IconResourceHandlers so that we can update them if the theme changes
|
|
||||||
void init(std::shared_ptr<ResourceHandler> &ptr) override;
|
|
||||||
static QList<std::weak_ptr<IconResourceHandler>> m_iconHandlers;
|
|
||||||
|
|
||||||
QString m_key;
|
|
||||||
static QString m_theme;
|
|
||||||
|
|
||||||
// the workhorse, returns QVariantMap (filename => size) for m_key/m_theme
|
|
||||||
QVariant get() const;
|
|
||||||
};
|
|
@ -2,29 +2,30 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include "WebResourceHandler.h"
|
|
||||||
#include "IconResourceHandler.h"
|
|
||||||
#include "ResourceObserver.h"
|
#include "ResourceObserver.h"
|
||||||
|
#include "ResourceHandler.h"
|
||||||
|
|
||||||
// definition of static members of Resource
|
// definition of static members of Resource
|
||||||
QMap<QString, std::function<std::shared_ptr<ResourceHandler>(const QString &)>> Resource::m_handlers;
|
QMap<QString, std::function<std::shared_ptr<ResourceHandler>(const QString &)>> Resource::m_handlers;
|
||||||
QMap<QPair<int, int>, std::function<QVariant(QVariant)>> Resource::m_transfomers;
|
QMap<QPair<int, int>, std::function<QVariant(QVariant)>> Resource::m_transfomers;
|
||||||
QMap<QString, std::weak_ptr<Resource>> Resource::m_resources;
|
QMap<QString, std::weak_ptr<Resource>> Resource::m_resources;
|
||||||
|
|
||||||
|
struct NullResourceResult {};
|
||||||
|
Q_DECLARE_METATYPE(NullResourceResult)
|
||||||
|
class NullResourceHandler : public ResourceHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit NullResourceHandler()
|
||||||
|
{
|
||||||
|
setResult(QVariant::fromValue<NullResourceResult>(NullResourceResult()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Resource::Resource(const QString &resource)
|
Resource::Resource(const QString &resource)
|
||||||
: m_resource(resource)
|
: m_resource(resource)
|
||||||
{
|
{
|
||||||
// register default handlers
|
if (!resource.isEmpty())
|
||||||
// QUESTION: move elsewhere?
|
|
||||||
if (!m_handlers.contains("web"))
|
|
||||||
{
|
{
|
||||||
registerHandler<WebResourceHandler>("web");
|
|
||||||
}
|
|
||||||
if (!m_handlers.contains("icon"))
|
|
||||||
{
|
|
||||||
registerHandler<IconResourceHandler>("icon");
|
|
||||||
}
|
|
||||||
|
|
||||||
// a valid resource identifier has the format <id>:<data>
|
// a valid resource identifier has the format <id>:<data>
|
||||||
Q_ASSERT(resource.contains(':'));
|
Q_ASSERT(resource.contains(':'));
|
||||||
// "parse" the resource identifier into id and data
|
// "parse" the resource identifier into id and data
|
||||||
@ -34,6 +35,12 @@ Resource::Resource(const QString &resource)
|
|||||||
// create and set up the handler
|
// create and set up the handler
|
||||||
Q_ASSERT(m_handlers.contains(resourceId));
|
Q_ASSERT(m_handlers.contains(resourceId));
|
||||||
m_handler = m_handlers.value(resourceId)(resourceData);
|
m_handler = m_handlers.value(resourceId)(resourceData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_handler = std::make_shared<NullResourceHandler>();
|
||||||
|
}
|
||||||
|
|
||||||
Q_ASSERT(m_handler);
|
Q_ASSERT(m_handler);
|
||||||
m_handler->init(m_handler);
|
m_handler->init(m_handler);
|
||||||
m_handler->setResource(this);
|
m_handler->setResource(this);
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
#include <QIdentityProxyModel>
|
#include <QIdentityProxyModel>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "multimc_logic_export.h"
|
||||||
|
|
||||||
/// Convenience proxy model that transforms resource identifiers (strings) for Qt::DecorationRole into other types.
|
/// Convenience proxy model that transforms resource identifiers (strings) for Qt::DecorationRole into other types.
|
||||||
class ResourceProxyModel : public QIdentityProxyModel
|
class MULTIMC_LOGIC_EXPORT ResourceProxyModel : public QIdentityProxyModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
#include "WebResourceHandler.h"
|
|
||||||
|
|
||||||
#include "net/CacheDownload.h"
|
|
||||||
#include "net/HttpMetaCache.h"
|
|
||||||
#include "net/NetJob.h"
|
|
||||||
#include "FileSystem.h"
|
|
||||||
#include "Env.h"
|
|
||||||
|
|
||||||
QMap<QString, NetJob *> WebResourceHandler::m_activeDownloads;
|
|
||||||
|
|
||||||
WebResourceHandler::WebResourceHandler(const QString &url)
|
|
||||||
: QObject(), m_url(url)
|
|
||||||
{
|
|
||||||
MetaEntryPtr entry = ENV.metacache()->resolveEntry("icons", url);
|
|
||||||
if (!entry->stale)
|
|
||||||
{
|
|
||||||
setResultFromFile(entry->getFullPath());
|
|
||||||
}
|
|
||||||
else if (m_activeDownloads.contains(url))
|
|
||||||
{
|
|
||||||
NetJob *job = m_activeDownloads.value(url);
|
|
||||||
connect(job, &NetJob::succeeded, this, &WebResourceHandler::succeeded);
|
|
||||||
connect(job, &NetJob::failed, this, [job, this]() {setFailure(job->failReason());});
|
|
||||||
connect(job, &NetJob::progress, this, &WebResourceHandler::progress);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NetJob *job = new NetJob("Icon download");
|
|
||||||
job->addNetAction(CacheDownload::make(QUrl(url), entry));
|
|
||||||
connect(job, &NetJob::succeeded, this, &WebResourceHandler::succeeded);
|
|
||||||
connect(job, &NetJob::failed, this, [job, this]() {setFailure(job->failReason());});
|
|
||||||
connect(job, &NetJob::progress, this, &WebResourceHandler::progress);
|
|
||||||
connect(job, &NetJob::finished, job, [job](){m_activeDownloads.remove(m_activeDownloads.key(job));job->deleteLater();});
|
|
||||||
m_activeDownloads.insert(url, job);
|
|
||||||
job->start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebResourceHandler::succeeded()
|
|
||||||
{
|
|
||||||
MetaEntryPtr entry = ENV.metacache()->resolveEntry("icons", m_url);
|
|
||||||
setResultFromFile(entry->getFullPath());
|
|
||||||
m_activeDownloads.remove(m_activeDownloads.key(qobject_cast<NetJob *>(sender())));
|
|
||||||
}
|
|
||||||
void WebResourceHandler::progress(qint64 current, qint64 total)
|
|
||||||
{
|
|
||||||
if (total == 0)
|
|
||||||
{
|
|
||||||
setProgress(101);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setProgress(current / total);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebResourceHandler::setResultFromFile(const QString &file)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
setResult(FS::read(file));
|
|
||||||
}
|
|
||||||
catch (Exception &e)
|
|
||||||
{
|
|
||||||
setFailure(e.cause());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include "ResourceHandler.h"
|
|
||||||
|
|
||||||
class NetJob;
|
|
||||||
|
|
||||||
class WebResourceHandler : public QObject, public ResourceHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit WebResourceHandler(const QString &url);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void succeeded();
|
|
||||||
void progress(qint64 current, qint64 total);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static QMap<QString, NetJob *> m_activeDownloads;
|
|
||||||
|
|
||||||
QString m_url;
|
|
||||||
|
|
||||||
void setResultFromFile(const QString &file);
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user