Add SVG icon rendering/cache
This commit is contained in:
parent
7d7e4034f4
commit
e4806ab08d
@ -31,7 +31,6 @@ ENDIF()
|
||||
# First, include header overrides
|
||||
include_directories(hacks)
|
||||
|
||||
|
||||
######## 3rd Party Libs ########
|
||||
|
||||
# Find the required Qt parts
|
||||
@ -155,7 +154,7 @@ MESSAGE(STATUS "Job URL: ${MultiMC_JOB_URL}")
|
||||
######## Configure header ########
|
||||
configure_file("${PROJECT_SOURCE_DIR}/config.h.in"
|
||||
"${PROJECT_BINARY_DIR}/include/config.h")
|
||||
|
||||
include_directories(${PROJECT_BINARY_DIR}/include)
|
||||
|
||||
################################ FILES ################################
|
||||
|
||||
@ -172,6 +171,7 @@ gui/aboutdialog.h
|
||||
gui/consolewindow.h
|
||||
gui/instancemodel.h
|
||||
gui/instancedelegate.h
|
||||
gui/iconcache.h
|
||||
|
||||
multimc_pragma.h
|
||||
|
||||
@ -200,6 +200,7 @@ gui/aboutdialog.cpp
|
||||
gui/consolewindow.cpp
|
||||
gui/instancemodel.cpp
|
||||
gui/instancedelegate.cpp
|
||||
gui/iconcache.cpp
|
||||
|
||||
java/javautils.cpp
|
||||
java/annotations.cpp
|
||||
|
127
gui/iconcache.cpp
Normal file
127
gui/iconcache.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
#include "iconcache.h"
|
||||
#include <QMap>
|
||||
#include <QWebView>
|
||||
#include <QWebFrame>
|
||||
#include <QEventLoop>
|
||||
#include <QWebElement>
|
||||
|
||||
IconCache* IconCache::m_Instance = 0;
|
||||
QMutex IconCache::mutex;
|
||||
#define MAX_SIZE 1024
|
||||
|
||||
class Private : public QWebView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QString name;
|
||||
QSize size;
|
||||
QMap<QString, QIcon> icons;
|
||||
|
||||
public:
|
||||
Private()
|
||||
{
|
||||
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(svgLoaded(bool)));
|
||||
setFixedSize(MAX_SIZE, MAX_SIZE);
|
||||
|
||||
QPalette pal = palette();
|
||||
pal.setColor(QPalette::Base, Qt::transparent);
|
||||
setPalette(pal);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
||||
size = QSize(128,128);
|
||||
}
|
||||
void renderSVGIcon(QString name);
|
||||
|
||||
signals:
|
||||
void svgRendered();
|
||||
|
||||
private slots:
|
||||
void svgLoaded(bool ok);
|
||||
};
|
||||
|
||||
void Private::svgLoaded(bool ok)
|
||||
{
|
||||
if (!ok)
|
||||
{
|
||||
emit svgRendered();
|
||||
return;
|
||||
}
|
||||
// check for SVG root tag
|
||||
QString root = page()->currentFrame()->documentElement().tagName();
|
||||
if (root.compare("svg", Qt::CaseInsensitive) != 0)
|
||||
{
|
||||
emit svgRendered();
|
||||
return;
|
||||
}
|
||||
|
||||
// get the size of the svg image, check if it's valid
|
||||
auto elem = page()->currentFrame()->documentElement();
|
||||
double width = elem.attribute("width").toDouble();
|
||||
double height = elem.attribute("height").toDouble();
|
||||
if (width == 0.0 || height == 0.0 || width == MAX_SIZE || height == MAX_SIZE)
|
||||
{
|
||||
emit svgRendered();
|
||||
return;
|
||||
}
|
||||
|
||||
// create the target surface
|
||||
QSize t = size.isValid() ? size : QSize(width, height);
|
||||
QImage img(t, QImage::Format_ARGB32_Premultiplied);
|
||||
img.fill(Qt::transparent);
|
||||
|
||||
// prepare the painter, scale to required size
|
||||
QPainter p(&img);
|
||||
if(size.isValid())
|
||||
{
|
||||
p.scale(size.width() / width, size.height() / height);
|
||||
}
|
||||
|
||||
// the best quality
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setRenderHint(QPainter::TextAntialiasing);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
|
||||
page()->mainFrame()->render(&p,QWebFrame::ContentsLayer);
|
||||
p.end();
|
||||
|
||||
icons[name] = QIcon(QPixmap::fromImage(img));
|
||||
emit svgRendered();
|
||||
}
|
||||
|
||||
void Private::renderSVGIcon ( QString name )
|
||||
{
|
||||
// use event loop to wait for signal
|
||||
QEventLoop loop;
|
||||
this->name = name;
|
||||
QString prefix = "qrc:/icons/instances/";
|
||||
QObject::connect(this, SIGNAL(svgRendered()), &loop, SLOT(quit()));
|
||||
load(QUrl(prefix + name));
|
||||
loop.exec();
|
||||
}
|
||||
|
||||
IconCache::IconCache():d(new Private())
|
||||
{
|
||||
}
|
||||
|
||||
QIcon IconCache::getIcon ( QString name )
|
||||
{
|
||||
if(name == "default")
|
||||
name = "infinity";
|
||||
{
|
||||
auto iter = d->icons.find(name);
|
||||
if(iter != d->icons.end())
|
||||
return *iter;
|
||||
}
|
||||
d->renderSVGIcon(name);
|
||||
auto iter = d->icons.find(name);
|
||||
if(iter != d->icons.end())
|
||||
return *iter;
|
||||
|
||||
// Fallback for icons that don't exist.
|
||||
QString path = ":/icons/instances/infinity";
|
||||
//path += name;
|
||||
d->icons[name] = QIcon(path);
|
||||
return d->icons[name];
|
||||
}
|
||||
|
||||
#include "iconcache.moc"
|
43
gui/iconcache.h
Normal file
43
gui/iconcache.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <QMutex>
|
||||
#include <QtGui/QIcon>
|
||||
|
||||
class Private;
|
||||
|
||||
class IconCache
|
||||
{
|
||||
public:
|
||||
static IconCache* instance()
|
||||
{
|
||||
if (!m_Instance)
|
||||
{
|
||||
mutex.lock();
|
||||
if (!m_Instance)
|
||||
m_Instance = new IconCache;
|
||||
mutex.unlock();
|
||||
}
|
||||
return m_Instance;
|
||||
}
|
||||
|
||||
static void drop()
|
||||
{
|
||||
mutex.lock();
|
||||
delete m_Instance;
|
||||
m_Instance = 0;
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
QIcon getIcon(QString name);
|
||||
|
||||
private:
|
||||
IconCache();
|
||||
// hide copy constructor
|
||||
IconCache(const IconCache &);
|
||||
// hide assign op
|
||||
IconCache& operator=(const IconCache &);
|
||||
static IconCache* m_Instance;
|
||||
static QMutex mutex;
|
||||
Private* d;
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "instancemodel.h"
|
||||
#include <instance.h>
|
||||
#include <QIcon>
|
||||
#include "iconcache.h"
|
||||
|
||||
InstanceModel::InstanceModel ( const InstanceList& instances, QObject *parent )
|
||||
: QAbstractListModel ( parent ), m_instances ( &instances )
|
||||
@ -70,11 +71,15 @@ QVariant InstanceModel::data ( const QModelIndex& index, int role ) const
|
||||
}
|
||||
case Qt::DecorationRole:
|
||||
{
|
||||
IconCache * ic = IconCache::instance();
|
||||
// FIXME: replace with an icon cache/renderer
|
||||
/*
|
||||
QString path = ":/icons/instances/";
|
||||
path += pdata->iconKey();
|
||||
QIcon icon(path);
|
||||
return icon;
|
||||
*/
|
||||
QString key = pdata->iconKey();
|
||||
return ic->getIcon(key);
|
||||
//else return QIcon(":/icons/multimc/scalable/apps/multimc.svg");
|
||||
}
|
||||
// for now.
|
||||
|
@ -71,6 +71,7 @@ MainWindow::MainWindow ( QWidget *parent ) :
|
||||
pal.setBrush(QPalette::Base, QBrush(QPixmap(QString::fromUtf8(":/backgrounds/kitteh"))));
|
||||
view->setPalette(pal);
|
||||
*/
|
||||
|
||||
view->setStyleSheet(
|
||||
"QListView\
|
||||
{\
|
||||
|
@ -13,26 +13,13 @@
|
||||
height="32"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="skeleton.svg"
|
||||
inkscape:export-filename="/home/peterix/projects/MultiMC4/src/resources/insticons/skeleton128.png"
|
||||
inkscape:export-xdpi="360"
|
||||
inkscape:export-ydpi="360">
|
||||
<defs
|
||||
id="defs4">
|
||||
<filter
|
||||
color-interpolation-filters="sRGB"
|
||||
inkscape:collect="always"
|
||||
id="filter5719"
|
||||
x="-0.18000001"
|
||||
width="1.36"
|
||||
y="-0.36000001"
|
||||
height="1.72">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="0.15"
|
||||
id="feGaussianBlur5721" />
|
||||
</filter>
|
||||
<filter
|
||||
color-interpolation-filters="sRGB"
|
||||
inkscape:collect="always"
|
||||
@ -46,19 +33,6 @@
|
||||
stdDeviation="0.35"
|
||||
id="feGaussianBlur5725" />
|
||||
</filter>
|
||||
<filter
|
||||
color-interpolation-filters="sRGB"
|
||||
inkscape:collect="always"
|
||||
id="filter5711"
|
||||
x="-0.1728"
|
||||
width="1.3456"
|
||||
y="-0.34560001"
|
||||
height="1.6912">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="0.144"
|
||||
id="feGaussianBlur5713" />
|
||||
</filter>
|
||||
<filter
|
||||
color-interpolation-filters="sRGB"
|
||||
inkscape:collect="always"
|
||||
@ -103,12 +77,12 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="17.044214"
|
||||
inkscape:cy="19.500236"
|
||||
inkscape:cx="-18.309169"
|
||||
inkscape:cy="22.958832"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1607"
|
||||
inkscape:window-width="1614"
|
||||
inkscape:window-height="1030"
|
||||
inkscape:window-x="1676"
|
||||
inkscape:window-y="-3"
|
||||
@ -129,7 +103,7 @@
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
@ -612,7 +586,7 @@
|
||||
x="7.9999995"
|
||||
y="1036.3622" />
|
||||
<rect
|
||||
style="fill:#00ffff;fill-opacity:1;stroke:none;filter:url(#filter5711)"
|
||||
style="fill:#00ffff;fill-opacity:1;stroke:none;"
|
||||
id="rect4084-3"
|
||||
width="2"
|
||||
height="1"
|
||||
@ -626,7 +600,7 @@
|
||||
x="20"
|
||||
y="1036.3622" />
|
||||
<rect
|
||||
style="fill:#00ffff;fill-opacity:1;stroke:none;filter:url(#filter5719)"
|
||||
style="fill:#00ffff;fill-opacity:1;stroke:none;"
|
||||
id="rect4086-7"
|
||||
width="2"
|
||||
height="1"
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 15 KiB |
Loading…
Reference in New Issue
Block a user