|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/gutil.h"
|
|
Kite |
521c84 |
#include "toonz/preferences.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzQt includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/dvdialog.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "traster.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpixelutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfilepath.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfiletype.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcurves.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trop.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmsgcore.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Qt includes
|
|
konero |
7bed16 |
#include <qdiriterator></qdiriterator>
|
|
Toshihiro Shimizu |
890ddd |
#include <qpixmap></qpixmap>
|
|
Toshihiro Shimizu |
890ddd |
#include <qimage></qimage>
|
|
Toshihiro Shimizu |
890ddd |
#include <qpainter></qpainter>
|
|
Toshihiro Shimizu |
890ddd |
#include <qpainterpath></qpainterpath>
|
|
Toshihiro Shimizu |
890ddd |
#include <qicon></qicon>
|
|
Toshihiro Shimizu |
890ddd |
#include <qstring></qstring>
|
|
Toshihiro Shimizu |
890ddd |
#include <qapplication></qapplication>
|
|
Toshihiro Shimizu |
890ddd |
#include <qmouseevent></qmouseevent>
|
|
Toshihiro Shimizu |
890ddd |
#include <qtabletevent></qtabletevent>
|
|
Toshihiro Shimizu |
890ddd |
#include <qkeyevent></qkeyevent>
|
|
Toshihiro Shimizu |
890ddd |
#include <qurl></qurl>
|
|
Toshihiro Shimizu |
890ddd |
#include <qfileinfo></qfileinfo>
|
|
shun_iwasawa |
3cc41f |
#include <qdesktopwidget></qdesktopwidget>
|
|
shun_iwasawa |
3cc41f |
#include <qsvgrenderer></qsvgrenderer>
|
|
shun-iwasawa |
f2e168 |
#include <qscreen></qscreen>
|
|
shun-iwasawa |
f2e168 |
#include <qwindow></qwindow>
|
|
konero |
7bed16 |
#include <qdebug></qdebug>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace DVGui;
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
f2e168 |
namespace {
|
|
shun-iwasawa |
f2e168 |
inline bool hasScreensWithDifferentDevPixRatio() {
|
|
shun-iwasawa |
f2e168 |
static bool ret = false;
|
|
shun-iwasawa |
f2e168 |
static bool checked = false;
|
|
shun-iwasawa |
f2e168 |
if (!checked) { // check once
|
|
shun-iwasawa |
f2e168 |
int dpr = QApplication::desktop()->devicePixelRatio();
|
|
shun-iwasawa |
f2e168 |
for (auto screen : QGuiApplication::screens()) {
|
|
shun-iwasawa |
f2e168 |
if ((int)screen->devicePixelRatio() != dpr) {
|
|
shun-iwasawa |
f2e168 |
ret = true;
|
|
shun-iwasawa |
f2e168 |
break;
|
|
shun-iwasawa |
f2e168 |
}
|
|
shun-iwasawa |
f2e168 |
}
|
|
shun-iwasawa |
f2e168 |
checked = true;
|
|
shun-iwasawa |
f2e168 |
}
|
|
shun-iwasawa |
f2e168 |
return ret;
|
|
shun-iwasawa |
f2e168 |
}
|
|
shun-iwasawa |
f2e168 |
|
|
shun-iwasawa |
f2e168 |
int getHighestDevicePixelRatio() {
|
|
shun-iwasawa |
f2e168 |
static int highestDevPixRatio = 0;
|
|
shun-iwasawa |
f2e168 |
if (highestDevPixRatio == 0) {
|
|
shun-iwasawa |
f2e168 |
for (auto screen : QGuiApplication::screens())
|
|
shun-iwasawa |
f2e168 |
highestDevPixRatio =
|
|
shun-iwasawa |
f2e168 |
std::max(highestDevPixRatio, (int)screen->devicePixelRatio());
|
|
shun-iwasawa |
f2e168 |
}
|
|
shun-iwasawa |
f2e168 |
return highestDevPixRatio;
|
|
shun-iwasawa |
f2e168 |
}
|
|
shun-iwasawa |
f2e168 |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QString fileSizeString(qint64 size, int precision) {
|
|
Shinya Kitaoka |
120a6e |
if (size < 1024)
|
|
Shinya Kitaoka |
120a6e |
return QString::number(size) + " Bytes";
|
|
Shinya Kitaoka |
120a6e |
else if (size < 1024 * 1024)
|
|
Shinya Kitaoka |
120a6e |
return QString::number(size / (1024.0), 'f', precision) + " KB";
|
|
Shinya Kitaoka |
120a6e |
else if (size < 1024 * 1024 * 1024)
|
|
Shinya Kitaoka |
120a6e |
return QString::number(size / (1024 * 1024.0), 'f', precision) + " MB";
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return QString::number(size / (1024 * 1024 * 1024.0), 'f', precision) +
|
|
Shinya Kitaoka |
120a6e |
" GB";
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QImage rasterToQImage(const TRasterP &ras, bool premultiplied, bool mirrored) {
|
|
Shinya Kitaoka |
120a6e |
if (TRaster32P ras32 = ras) {
|
|
Shinya Kitaoka |
120a6e |
QImage image(ras->getRawData(), ras->getLx(), ras->getLy(),
|
|
Shinya Kitaoka |
120a6e |
premultiplied ? QImage::Format_ARGB32_Premultiplied
|
|
Shinya Kitaoka |
120a6e |
: QImage::Format_ARGB32);
|
|
Shinya Kitaoka |
120a6e |
if (mirrored) return image.mirrored();
|
|
Shinya Kitaoka |
120a6e |
return image;
|
|
Shinya Kitaoka |
120a6e |
} else if (TRasterGR8P ras8 = ras) {
|
|
Shinya Kitaoka |
120a6e |
QImage image(ras->getRawData(), ras->getLx(), ras->getLy(), ras->getWrap(),
|
|
Shinya Kitaoka |
120a6e |
QImage::Format_Indexed8);
|
|
Shinya Kitaoka |
120a6e |
static QVector<qrgb> colorTable;</qrgb>
|
|
Shinya Kitaoka |
120a6e |
if (colorTable.size() == 0) {
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < 256; i++) colorTable.append(QColor(i, i, i).rgb());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
image.setColorTable(colorTable);
|
|
Shinya Kitaoka |
120a6e |
if (mirrored) return image.mirrored();
|
|
Shinya Kitaoka |
120a6e |
return image;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return QImage();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun_iwasawa |
3cc41f |
QPixmap rasterToQPixmap(const TRaster32P &ras, bool premultiplied,
|
|
shun_iwasawa |
3cc41f |
bool setDevPixRatio) {
|
|
shun_iwasawa |
3cc41f |
QPixmap pixmap = QPixmap::fromImage(rasterToQImage(ras, premultiplied));
|
|
shun_iwasawa |
3cc41f |
if (setDevPixRatio) {
|
|
shun-iwasawa |
f2e168 |
pixmap.setDevicePixelRatio(getDevicePixelRatio());
|
|
shun_iwasawa |
3cc41f |
}
|
|
shun_iwasawa |
3cc41f |
return pixmap;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRaster32P rasterFromQImage(
|
|
Shinya Kitaoka |
120a6e |
QImage image, bool premultiply,
|
|
Shinya Kitaoka |
120a6e |
bool mirror) // no need of const& - Qt uses implicit sharing...
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
QImage copyImage = mirror ? image.mirrored() : image;
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ras(image.width(), image.height(), image.width(),
|
|
Shinya Kitaoka |
120a6e |
(TPixelRGBM32 *)copyImage.bits(), false);
|
|
Shinya Kitaoka |
120a6e |
if (premultiply) TRop::premultiply(ras);
|
|
Shinya Kitaoka |
120a6e |
return ras->clone();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRaster32P rasterFromQPixmap(
|
|
Shinya Kitaoka |
120a6e |
QPixmap pixmap, bool premultiply,
|
|
Shinya Kitaoka |
120a6e |
bool mirror) // no need of const& - Qt uses implicit sharing...
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
QImage image = pixmap.toImage();
|
|
Shinya Kitaoka |
120a6e |
return rasterFromQImage(image, premultiply, mirror);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawPolygon(QPainter &p, const std::vector<qpointf> &points, bool fill,</qpointf>
|
|
Shinya Kitaoka |
120a6e |
const QColor colorFill, const QColor colorLine) {
|
|
Shinya Kitaoka |
120a6e |
if (points.size() == 0) return;
|
|
Shinya Kitaoka |
120a6e |
p.setPen(colorLine);
|
|
Shinya Kitaoka |
120a6e |
QPolygonF E0Polygon;
|
|
Shinya Kitaoka |
120a6e |
int i = 0;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)points.size(); i++) E0Polygon << QPointF(points[i]);
|
|
Shinya Kitaoka |
120a6e |
E0Polygon << QPointF(points[0]);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QPainterPath E0Path;
|
|
Shinya Kitaoka |
120a6e |
E0Path.addPolygon(E0Polygon);
|
|
Shinya Kitaoka |
120a6e |
if (fill) p.fillPath(E0Path, QBrush(colorFill));
|
|
Shinya Kitaoka |
120a6e |
p.drawPath(E0Path);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawArrow(QPainter &p, const QPointF a, const QPointF b, const QPointF c,
|
|
Shinya Kitaoka |
120a6e |
bool fill, const QColor colorFill, const QColor colorLine) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<qpointf> pts;</qpointf>
|
|
Shinya Kitaoka |
120a6e |
pts.push_back(a);
|
|
Shinya Kitaoka |
120a6e |
pts.push_back(b);
|
|
Shinya Kitaoka |
120a6e |
pts.push_back(c);
|
|
Shinya Kitaoka |
120a6e |
drawPolygon(p, pts, fill, colorFill, colorLine);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QPixmap scalePixmapKeepingAspectRatio(QPixmap pixmap, QSize size,
|
|
Shinya Kitaoka |
120a6e |
QColor color) {
|
|
shun_iwasawa |
3cc41f |
if (pixmap.isNull()) return pixmap;
|
|
shun_iwasawa |
3cc41f |
if (pixmap.devicePixelRatio() > 1.0) size *= pixmap.devicePixelRatio();
|
|
shun_iwasawa |
3cc41f |
if (pixmap.size() == size) return pixmap;
|
|
Shinya Kitaoka |
120a6e |
QPixmap scaledPixmap =
|
|
Shinya Kitaoka |
120a6e |
pixmap.scaled(size.width(), size.height(), Qt::KeepAspectRatio,
|
|
Shinya Kitaoka |
120a6e |
Qt::SmoothTransformation);
|
|
Shinya Kitaoka |
120a6e |
QPixmap newPixmap(size);
|
|
Shinya Kitaoka |
120a6e |
newPixmap.fill(color);
|
|
Shinya Kitaoka |
120a6e |
QPainter painter(&newPixmap);
|
|
Shinya Kitaoka |
120a6e |
painter.drawPixmap(double(size.width() - scaledPixmap.width()) * 0.5,
|
|
Shinya Kitaoka |
120a6e |
double(size.height() - scaledPixmap.height()) * 0.5,
|
|
Shinya Kitaoka |
120a6e |
scaledPixmap);
|
|
shun_iwasawa |
3cc41f |
newPixmap.setDevicePixelRatio(pixmap.devicePixelRatio());
|
|
Shinya Kitaoka |
120a6e |
return newPixmap;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
konero |
7bed16 |
int getDevicePixelRatio(const QWidget *widget) {
|
|
konero |
7bed16 |
if (hasScreensWithDifferentDevPixRatio() && widget) {
|
|
konero |
7bed16 |
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
|
konero |
7bed16 |
return widget->screen()->devicePixelRatio();
|
|
konero |
7bed16 |
#else
|
|
konero |
7bed16 |
if (!widget->windowHandle()) widget->winId();
|
|
konero |
7bed16 |
if (widget->windowHandle())
|
|
konero |
7bed16 |
return widget->windowHandle()->devicePixelRatio();
|
|
konero |
7bed16 |
#endif
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
static int devPixRatio = QApplication::desktop()->devicePixelRatio();
|
|
konero |
7bed16 |
return devPixRatio;
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Calculate render params for use by svgToImage() and svgToPixmap()
|
|
konero |
7bed16 |
SvgRenderParams calculateSvgRenderParams(const QSize &desiredSize,
|
|
konero |
7bed16 |
QSize &imageSize,
|
|
konero |
7bed16 |
Qt::AspectRatioMode aspectRatioMode) {
|
|
konero |
7bed16 |
SvgRenderParams params;
|
|
konero |
7bed16 |
if (desiredSize.isEmpty()) {
|
|
konero |
7bed16 |
params.size = imageSize;
|
|
konero |
7bed16 |
params.rect = QRectF(QPointF(), QSizeF(params.size));
|
|
shun_iwasawa |
3cc41f |
} else {
|
|
konero |
7bed16 |
params.size = desiredSize;
|
|
shun_iwasawa |
3cc41f |
if (aspectRatioMode == Qt::KeepAspectRatio ||
|
|
shun_iwasawa |
3cc41f |
aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
|
|
konero |
7bed16 |
QPointF scaleFactor(
|
|
konero |
7bed16 |
(float)params.size.width() / (float)imageSize.width(),
|
|
konero |
7bed16 |
(float)params.size.height() / (float)imageSize.height());
|
|
shun_iwasawa |
3cc41f |
float factor = (aspectRatioMode == Qt::KeepAspectRatio)
|
|
shun_iwasawa |
3cc41f |
? std::min(scaleFactor.x(), scaleFactor.y())
|
|
shun_iwasawa |
3cc41f |
: std::max(scaleFactor.x(), scaleFactor.y());
|
|
konero |
7bed16 |
QSizeF renderSize(factor * (float)imageSize.width(),
|
|
konero |
7bed16 |
factor * (float)imageSize.height());
|
|
shun_iwasawa |
3cc41f |
QPointF topLeft(
|
|
konero |
7bed16 |
((float)params.size.width() - renderSize.width()) * 0.5f,
|
|
konero |
7bed16 |
((float)params.size.height() - renderSize.height()) * 0.5f);
|
|
konero |
7bed16 |
params.rect = QRectF(topLeft, renderSize);
|
|
shun_iwasawa |
3cc41f |
} else { // Qt::IgnoreAspectRatio:
|
|
konero |
7bed16 |
params.rect = QRectF(QPointF(), QSizeF(params.size));
|
|
shun_iwasawa |
3cc41f |
}
|
|
shun_iwasawa |
3cc41f |
}
|
|
konero |
7bed16 |
return params;
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QPixmap svgToPixmap(const QString &svgFilePath, QSize size,
|
|
konero |
7bed16 |
Qt::AspectRatioMode aspectRatioMode, QColor bgColor) {
|
|
konero |
7bed16 |
if (svgFilePath.isEmpty()) return QPixmap();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QSvgRenderer svgRenderer(svgFilePath);
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Check if SVG file was loaded correctly
|
|
konero |
7bed16 |
if (!svgRenderer.isValid()) {
|
|
konero |
7bed16 |
qDebug() << "Invalid SVG file:" << svgFilePath;
|
|
konero |
7bed16 |
return QPixmap();
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
static int devPixRatio = getHighestDevicePixelRatio();
|
|
konero |
7bed16 |
if (!size.isEmpty()) size *= devPixRatio;
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QSize imageSize = svgRenderer.defaultSize() * devPixRatio;
|
|
konero |
7bed16 |
SvgRenderParams params =
|
|
konero |
7bed16 |
calculateSvgRenderParams(size, imageSize, aspectRatioMode);
|
|
konero |
7bed16 |
QPixmap pixmap(params.size);
|
|
shun_iwasawa |
3cc41f |
QPainter painter;
|
|
shun_iwasawa |
3cc41f |
pixmap.fill(bgColor);
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
if (!painter.begin(&pixmap)) {
|
|
konero |
7bed16 |
qDebug() << "Failed to begin QPainter on pixmap";
|
|
konero |
7bed16 |
return QPixmap();
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
svgRenderer.render(&painter, params.rect);
|
|
shun_iwasawa |
3cc41f |
painter.end();
|
|
shun_iwasawa |
3cc41f |
pixmap.setDevicePixelRatio(devPixRatio);
|
|
shun_iwasawa |
3cc41f |
return pixmap;
|
|
shun_iwasawa |
3cc41f |
}
|
|
shun_iwasawa |
3cc41f |
|
|
shun_iwasawa |
3cc41f |
//-----------------------------------------------------------------------------
|
|
shun_iwasawa |
3cc41f |
|
|
konero |
7bed16 |
QImage svgToImage(const QString &svgFilePath, QSize size,
|
|
konero |
7bed16 |
Qt::AspectRatioMode aspectRatioMode, QColor bgColor) {
|
|
konero |
7bed16 |
if (svgFilePath.isEmpty()) return QImage();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QSvgRenderer svgRenderer(svgFilePath);
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Check if SVG file was loaded correctly
|
|
konero |
7bed16 |
if (!svgRenderer.isValid()) {
|
|
konero |
7bed16 |
qDebug() << "Invalid SVG file:" << svgFilePath;
|
|
konero |
7bed16 |
return QImage();
|
|
shun-iwasawa |
f2e168 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
static int devPixRatio = getHighestDevicePixelRatio();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QSize imageSize = svgRenderer.defaultSize() * devPixRatio;
|
|
konero |
7bed16 |
SvgRenderParams params =
|
|
konero |
7bed16 |
calculateSvgRenderParams(size, imageSize, aspectRatioMode);
|
|
konero |
7bed16 |
QImage image(params.size, QImage::Format_ARGB32_Premultiplied);
|
|
konero |
7bed16 |
QPainter painter;
|
|
konero |
7bed16 |
image.fill(bgColor);
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
if (!painter.begin(&image)) {
|
|
konero |
7bed16 |
qDebug() << "Failed to begin QPainter on image";
|
|
konero |
7bed16 |
return QImage();
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
svgRenderer.render(&painter, params.rect);
|
|
konero |
7bed16 |
painter.end();
|
|
konero |
7bed16 |
return image;
|
|
shun_iwasawa |
3cc41f |
}
|
|
shun_iwasawa |
3cc41f |
|
|
shun_iwasawa |
3cc41f |
//-----------------------------------------------------------------------------
|
|
shun_iwasawa |
3cc41f |
|
|
konero |
7bed16 |
// Change the opacity of a QImage (0.0 - 1.0)
|
|
konero |
7bed16 |
QImage adjustImageOpacity(const QImage &input, qreal opacity) {
|
|
konero |
7bed16 |
if (input.isNull()) return QImage();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QImage result(input.size(), QImage::Format_ARGB32_Premultiplied);
|
|
Toshihiro Shimizu |
890ddd |
|
|
konero |
7bed16 |
QPainter painter(&result);
|
|
konero |
7bed16 |
if (!painter.isActive()) return QImage();
|
|
Kite |
521c84 |
|
|
konero |
7bed16 |
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
|
konero |
7bed16 |
painter.fillRect(result.rect(), Qt::transparent);
|
|
konero |
7bed16 |
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
|
konero |
7bed16 |
painter.drawImage(0, 0, input);
|
|
konero |
7bed16 |
painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
|
konero |
7bed16 |
painter.fillRect(
|
|
konero |
7bed16 |
result.rect(),
|
|
konero |
7bed16 |
QColor(0, 0, 0, qBound(0, static_cast<int>(opacity * 255), 255)));</int>
|
|
konero |
7bed16 |
painter.end();
|
|
Kite |
521c84 |
|
|
konero |
7bed16 |
return result;
|
|
Kite |
521c84 |
}
|
|
Kite |
521c84 |
|
|
Kite |
521c84 |
//-----------------------------------------------------------------------------
|
|
Kite |
521c84 |
|
|
konero |
7bed16 |
// Resizes a QImage, if scaleInput is true then input image will scale according
|
|
konero |
7bed16 |
// to newSize otherwise the input image will be centered and not scaled
|
|
konero |
7bed16 |
QImage compositeImage(const QImage &input, QSize newSize, bool scaleInput,
|
|
konero |
7bed16 |
QColor bgColor) {
|
|
konero |
7bed16 |
if (input.isNull()) return QImage();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
int devPixRatio = getHighestDevicePixelRatio();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
int w, h, x = 0, y = 0;
|
|
konero |
7bed16 |
if (newSize.isEmpty()) {
|
|
konero |
7bed16 |
w = input.width();
|
|
konero |
7bed16 |
h = input.height();
|
|
konero |
7bed16 |
} else {
|
|
konero |
7bed16 |
w = newSize.width() * devPixRatio;
|
|
konero |
7bed16 |
h = newSize.height() * devPixRatio;
|
|
konero |
7bed16 |
if (!scaleInput) {
|
|
konero |
7bed16 |
x = (w - input.width()) / 2;
|
|
konero |
7bed16 |
y = (h - input.height()) / 2;
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QImage newImage(w, h, QImage::Format_ARGB32_Premultiplied);
|
|
konero |
7bed16 |
newImage.fill(bgColor);
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
if (scaleInput) {
|
|
konero |
7bed16 |
return input.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
konero |
7bed16 |
} else {
|
|
konero |
7bed16 |
QPainter painter(&newImage);
|
|
konero |
7bed16 |
if (!painter.isActive()) return QImage();
|
|
konero |
7bed16 |
painter.drawImage(QPoint(x, y), input);
|
|
konero |
7bed16 |
painter.end();
|
|
Kite |
521c84 |
|
|
konero |
7bed16 |
return newImage;
|
|
Kite |
521c84 |
}
|
|
Kite |
521c84 |
}
|
|
Kite |
521c84 |
|
|
Kite |
521c84 |
//-----------------------------------------------------------------------------
|
|
Kite |
521c84 |
|
|
konero |
7bed16 |
// Convert QImage to QPixmap and set device pixel ratio
|
|
konero |
7bed16 |
QPixmap convertImageToPixmap(const QImage &image) {
|
|
konero |
7bed16 |
if (image.isNull()) return QPixmap();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QPixmap pixmap(QPixmap::fromImage(image));
|
|
konero |
7bed16 |
int devPixRatio = getHighestDevicePixelRatio();
|
|
konero |
7bed16 |
pixmap.setDevicePixelRatio(devPixRatio);
|
|
konero |
7bed16 |
|
|
Kite |
52018c |
return pixmap;
|
|
Kite |
52018c |
}
|
|
Kite |
52018c |
|
|
Kite |
52018c |
//-----------------------------------------------------------------------------
|
|
Kite |
52018c |
|
|
konero |
7bed16 |
// Load, theme colorize and change opacity of an icon image
|
|
konero |
7bed16 |
QImage generateIconImage(const QString &iconSVGName, qreal opacity,
|
|
konero |
7bed16 |
QSize newSize, Qt::AspectRatioMode aspectRatioMode) {
|
|
konero |
7bed16 |
static ThemeManager &themeManager = ThemeManager::getInstance();
|
|
Kite |
521c84 |
|
|
konero |
7bed16 |
if (iconSVGName.isEmpty() || !themeManager.hasIcon(iconSVGName)) {
|
|
konero |
7bed16 |
return QImage();
|
|
konero |
7bed16 |
}
|
|
Kite |
c50ec4 |
|
|
konero |
7bed16 |
int devPixRatio = getHighestDevicePixelRatio();
|
|
konero |
7bed16 |
newSize *= devPixRatio;
|
|
Kite |
c50ec4 |
|
|
konero |
7bed16 |
// Path to icon image
|
|
konero |
7bed16 |
const QString imgPath = themeManager.getIconPath(iconSVGName);
|
|
Kite |
c50ec4 |
|
|
konero |
7bed16 |
// Convert SVG to QImage
|
|
konero |
7bed16 |
QImage image(svgToImage(imgPath, newSize, aspectRatioMode));
|
|
Kite |
c50ec4 |
|
|
konero |
7bed16 |
// Colorize QImage
|
|
konero |
7bed16 |
image = themeManager.recolorBlackPixels(image);
|
|
Kite |
c50ec4 |
|
|
konero |
7bed16 |
// Change opacity if required
|
|
konero |
7bed16 |
if (opacity != qreal(1.0)) image = adjustImageOpacity(image, opacity);
|
|
Kite |
c50ec4 |
|
|
konero |
7bed16 |
return image;
|
|
konero |
7bed16 |
}
|
|
Kite |
c50ec4 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
Kite |
c50ec4 |
|
|
konero |
7bed16 |
// Load, theme colorize and change opacity of an icon image file
|
|
konero |
7bed16 |
QPixmap generateIconPixmap(const QString &iconSVGName, qreal opacity,
|
|
konero |
7bed16 |
QSize newSize, Qt::AspectRatioMode aspectRatioMode) {
|
|
konero |
7bed16 |
QImage image =
|
|
konero |
7bed16 |
generateIconImage(iconSVGName, opacity, newSize, aspectRatioMode);
|
|
konero |
7bed16 |
return convertImageToPixmap(image);
|
|
konero |
7bed16 |
}
|
|
Kite |
c50ec4 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
konero |
7bed16 |
// Process and populate all modes and states of a QIcon
|
|
konero |
7bed16 |
void addImagesToIcon(QIcon &icon, const QImage &baseImg, const QImage &overImg,
|
|
konero |
7bed16 |
const QImage &onImg, bool useFullOpacity) {
|
|
konero |
7bed16 |
if (baseImg.isNull()) return;
|
|
shun-iwasawa |
bb8132 |
|
|
konero |
7bed16 |
ThemeManager &themeManager = ThemeManager::getInstance();
|
|
konero |
7bed16 |
const qreal offOpacity = useFullOpacity ? 1.0 : themeManager.getOffOpacity();
|
|
konero |
7bed16 |
const qreal onOpacity = themeManager.getOnOpacity();
|
|
konero |
7bed16 |
const qreal disabledOpacity = themeManager.getDisabledOpacity();
|
|
Kite |
c50ec4 |
|
|
konero |
7bed16 |
// Generate more images using input images for other modes and states
|
|
konero |
7bed16 |
QImage offImg = adjustImageOpacity(baseImg, offOpacity);
|
|
konero |
7bed16 |
QImage disabledImg = adjustImageOpacity(baseImg, disabledOpacity);
|
|
konero |
7bed16 |
QImage onDisabledImg =
|
|
konero |
7bed16 |
!onImg.isNull() ? adjustImageOpacity(onImg, disabledOpacity) : QImage();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Convert images to pixmaps and set device pixel ratio
|
|
konero |
7bed16 |
QPixmap basePm(convertImageToPixmap(baseImg));
|
|
konero |
7bed16 |
QPixmap offPm(convertImageToPixmap(offImg));
|
|
konero |
7bed16 |
QPixmap disabledPm(convertImageToPixmap(disabledImg));
|
|
konero |
7bed16 |
QPixmap overPm(convertImageToPixmap(overImg));
|
|
konero |
7bed16 |
QPixmap onPm(convertImageToPixmap(onImg));
|
|
konero |
7bed16 |
QPixmap onDisabledPm(convertImageToPixmap(onDisabledImg));
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Add pixmaps to icon and fallback to basePm if 'over' and 'on' are null
|
|
konero |
7bed16 |
icon.addPixmap(offPm, QIcon::Normal, QIcon::Off);
|
|
konero |
7bed16 |
icon.addPixmap(disabledPm, QIcon::Disabled, QIcon::Off);
|
|
konero |
7bed16 |
icon.addPixmap(!overPm.isNull() ? overPm : basePm, QIcon::Active);
|
|
konero |
7bed16 |
icon.addPixmap(!onPm.isNull() ? onPm : basePm, QIcon::Normal, QIcon::On);
|
|
konero |
7bed16 |
icon.addPixmap(!onPm.isNull() ? onDisabledPm : disabledPm, QIcon::Disabled,
|
|
konero |
7bed16 |
QIcon::On);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
konero |
d3dd18 |
void addSpecifiedSizedImageToIcon(QIcon &icon, const char *iconSVGName,
|
|
konero |
d3dd18 |
QSize newSize) {
|
|
konero |
d3dd18 |
static int devPixRatio = getHighestDevicePixelRatio();
|
|
konero |
d3dd18 |
newSize *= devPixRatio;
|
|
konero |
d3dd18 |
|
|
konero |
d3dd18 |
// Construct icon filenames
|
|
konero |
d3dd18 |
QString iconName = QString::fromUtf8(iconSVGName);
|
|
konero |
d3dd18 |
QString overIconName = iconName + "_over";
|
|
konero |
d3dd18 |
QString onIconName = iconName + "_on";
|
|
konero |
d3dd18 |
|
|
konero |
d3dd18 |
// Generate icon images
|
|
konero |
d3dd18 |
QImage baseImg = generateIconImage(iconName, 1.0, newSize);
|
|
konero |
d3dd18 |
QImage overImg = generateIconImage(overIconName, 1.0, newSize);
|
|
konero |
d3dd18 |
QImage onImg = generateIconImage(onIconName, 1.0, newSize);
|
|
konero |
d3dd18 |
|
|
konero |
d3dd18 |
// Add newly sized images to the icon
|
|
konero |
d3dd18 |
addImagesToIcon(icon, baseImg, overImg, onImg);
|
|
konero |
d3dd18 |
}
|
|
konero |
d3dd18 |
|
|
konero |
d3dd18 |
//-----------------------------------------------------------------------------
|
|
konero |
d3dd18 |
|
|
konero |
7bed16 |
// Add the same pixmap to all modes and states of a QIcon
|
|
konero |
7bed16 |
void addPixmapToAllModesAndStates(QIcon &icon, const QPixmap &pixmap) {
|
|
konero |
4823ff |
QIcon::Mode modes[] = {QIcon::Normal, QIcon::Disabled, QIcon::Selected};
|
|
konero |
7bed16 |
QIcon::State states[] = {QIcon::On, QIcon::Off};
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
for (const auto &mode : modes) {
|
|
konero |
7bed16 |
for (const auto &state : states) {
|
|
konero |
7bed16 |
icon.addPixmap(pixmap, mode, state);
|
|
konero |
7bed16 |
}
|
|
shun-iwasawa |
9b2afe |
}
|
|
konero |
4823ff |
icon.addPixmap(pixmap, QIcon::Active, QIcon::Off);
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
shun-iwasawa |
9b2afe |
|
|
konero |
7bed16 |
/// @brief Return a themed icon
|
|
konero |
7bed16 |
/// @param iconSVGName Name of the icon (SVG file base name)
|
|
konero |
7bed16 |
/// @param useFullOpacity If true the icon will be max brightness
|
|
konero |
7bed16 |
/// @param isForMenuItem For special handling of menu icons
|
|
konero |
7bed16 |
/// @param newSize Render the SVG images of the icon at the specified size
|
|
konero |
7bed16 |
/// @return QIcon
|
|
konero |
7bed16 |
QIcon createQIcon(const QString &iconSVGName, bool useFullOpacity,
|
|
konero |
7bed16 |
bool isForMenuItem, QSize newSize) {
|
|
konero |
7bed16 |
static ThemeManager &themeManager = ThemeManager::getInstance();
|
|
konero |
7bed16 |
if (iconSVGName.isEmpty() || !themeManager.hasIcon(iconSVGName)) {
|
|
konero |
7bed16 |
// Use debug to check if something calls for an icon that doesn't exist
|
|
konero |
7bed16 |
//qDebug () << "File not found:" << iconSVGName;
|
|
konero |
7bed16 |
return QIcon();
|
|
shun-iwasawa |
9b2afe |
}
|
|
shun-iwasawa |
9b2afe |
|
|
konero |
7bed16 |
static int devPixRatio = getHighestDevicePixelRatio();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QImage baseImg(generateIconImage(iconSVGName, qreal(1.0), newSize));
|
|
konero |
7bed16 |
QImage overImg(generateIconImage(iconSVGName + "_over", qreal(1.0), newSize));
|
|
konero |
7bed16 |
QImage onImg(generateIconImage(iconSVGName + "_on", qreal(1.0), newSize));
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QIcon icon;
|
|
konero |
543cca |
|
|
konero |
7bed16 |
// START_BUG_WORKAROUND: #20230627
|
|
konero |
7bed16 |
// Set an empty pixmap for menu icons when hiding icons from menus is true,
|
|
konero |
7bed16 |
// search bug ID for more info.
|
|
konero |
7bed16 |
#ifdef _WIN32
|
|
konero |
7bed16 |
bool showIconInMenu = Preferences::instance()->getBoolValue(showIconsInMenu);
|
|
konero |
7bed16 |
if (isForMenuItem && baseImg.width() == (16 * devPixRatio) &&
|
|
konero |
7bed16 |
baseImg.height() == (16 * devPixRatio) && !showIconInMenu) {
|
|
konero |
7bed16 |
static QPixmap emptyPm(16 * devPixRatio, 16 * devPixRatio);
|
|
konero |
7bed16 |
emptyPm.fill(Qt::transparent);
|
|
konero |
7bed16 |
addPixmapToAllModesAndStates(icon, emptyPm);
|
|
konero |
7bed16 |
} else
|
|
konero |
7bed16 |
#endif // END_BUG_WORKAROUND
|
|
konero |
7bed16 |
{
|
|
konero |
7bed16 |
addImagesToIcon(icon, baseImg, overImg, onImg, useFullOpacity);
|
|
shun-iwasawa |
9b2afe |
}
|
|
shun-iwasawa |
9b2afe |
|
|
konero |
7bed16 |
// For tool bars we draw menu sized icons onto tool bar sized images otherwise
|
|
konero |
7bed16 |
// there can be scaling artifacts with high dpi and load these in addition
|
|
konero |
7bed16 |
if (baseImg.width() == (16 * devPixRatio) &&
|
|
konero |
7bed16 |
baseImg.height() == (16 * devPixRatio)) {
|
|
konero |
3a5304 |
for (auto screen : QApplication::screens()) {
|
|
konero |
3a5304 |
QSize expandSize(20, 20);
|
|
konero |
3a5304 |
int otherDevPixRatio = screen->devicePixelRatio();
|
|
konero |
3a5304 |
if (otherDevPixRatio != devPixRatio) {
|
|
konero |
3a5304 |
expandSize.setWidth(16 * otherDevPixRatio);
|
|
konero |
3a5304 |
expandSize.setHeight(16 * otherDevPixRatio);
|
|
konero |
3a5304 |
}
|
|
konero |
3a5304 |
QImage toolBaseImg(compositeImage(baseImg, expandSize));
|
|
konero |
3a5304 |
QImage toolOverImg(compositeImage(overImg, expandSize));
|
|
konero |
3a5304 |
QImage toolOnImg(compositeImage(onImg, expandSize));
|
|
konero |
3a5304 |
addImagesToIcon(icon, toolBaseImg, toolOverImg, toolOnImg,
|
|
konero |
3a5304 |
useFullOpacity);
|
|
konero |
3a5304 |
}
|
|
shun-iwasawa |
9b2afe |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
return icon;
|
|
shun-iwasawa |
9b2afe |
}
|
|
shun-iwasawa |
9b2afe |
|
|
shun-iwasawa |
9b2afe |
//-----------------------------------------------------------------------------
|
|
shun-iwasawa |
9b2afe |
|
|
Shinya Kitaoka |
120a6e |
QIcon createQIconPNG(const char *iconPNGName) {
|
|
Shinya Kitaoka |
120a6e |
QString normal = QString(":Resources/") + iconPNGName + ".png";
|
|
Shinya Kitaoka |
120a6e |
QString click = QString(":Resources/") + iconPNGName + "_click.png";
|
|
Shinya Kitaoka |
120a6e |
QString over = QString(":Resources/") + iconPNGName + "_over.png";
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QIcon icon;
|
|
Shinya Kitaoka |
120a6e |
icon.addFile(normal, QSize(), QIcon::Normal, QIcon::Off);
|
|
Shinya Kitaoka |
120a6e |
icon.addFile(click, QSize(), QIcon::Normal, QIcon::On);
|
|
Shinya Kitaoka |
120a6e |
icon.addFile(over, QSize(), QIcon::Active);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return icon;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QIcon createQIconOnOffPNG(const char *iconPNGName, bool withOver) {
|
|
Shinya Kitaoka |
120a6e |
QString on = QString(":Resources/") + iconPNGName + "_on.png";
|
|
Shinya Kitaoka |
120a6e |
QString off = QString(":Resources/") + iconPNGName + "_off.png";
|
|
Shinya Kitaoka |
120a6e |
QString over = QString(":Resources/") + iconPNGName + "_over.png";
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QIcon icon;
|
|
Shinya Kitaoka |
120a6e |
icon.addFile(off, QSize(), QIcon::Normal, QIcon::Off);
|
|
Shinya Kitaoka |
120a6e |
icon.addFile(on, QSize(), QIcon::Normal, QIcon::On);
|
|
Shinya Kitaoka |
120a6e |
if (withOver)
|
|
Shinya Kitaoka |
120a6e |
icon.addFile(over, QSize(), QIcon::Active);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
icon.addFile(on, QSize(), QIcon::Active);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return icon;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
75b9b0 |
QIcon createTemporaryIconFromName(const char *commandName) {
|
|
konero |
7bed16 |
const int visibleIconSize = 20;
|
|
konero |
7bed16 |
const int menubarIconSize = 16;
|
|
shun-iwasawa |
75b9b0 |
QString name(commandName);
|
|
shun-iwasawa |
75b9b0 |
QList<qchar> iconChar;</qchar>
|
|
shun-iwasawa |
75b9b0 |
|
|
shun-iwasawa |
75b9b0 |
for (int i = 0; i < name.length(); i++) {
|
|
shun-iwasawa |
75b9b0 |
QChar c = name.at(i);
|
|
shun-iwasawa |
75b9b0 |
if (c.isUpper() && iconChar.size() < 2)
|
|
shun-iwasawa |
75b9b0 |
iconChar.append(c);
|
|
shun-iwasawa |
75b9b0 |
else if (c.isDigit()) {
|
|
shun-iwasawa |
75b9b0 |
if (iconChar.isEmpty())
|
|
shun-iwasawa |
75b9b0 |
iconChar.append(c);
|
|
shun-iwasawa |
75b9b0 |
else if (iconChar.size() <= 2) {
|
|
shun-iwasawa |
75b9b0 |
if (iconChar.size() == 2) iconChar.removeLast();
|
|
shun-iwasawa |
75b9b0 |
iconChar.append(c);
|
|
shun-iwasawa |
75b9b0 |
break;
|
|
shun-iwasawa |
75b9b0 |
}
|
|
shun-iwasawa |
75b9b0 |
}
|
|
shun-iwasawa |
75b9b0 |
}
|
|
shun-iwasawa |
75b9b0 |
|
|
shun-iwasawa |
75b9b0 |
if (iconChar.isEmpty()) iconChar.append(name.at(0));
|
|
shun-iwasawa |
75b9b0 |
|
|
shun-iwasawa |
75b9b0 |
QString iconStr;
|
|
shun-iwasawa |
75b9b0 |
for (auto c : iconChar) iconStr.append(c);
|
|
shun-iwasawa |
75b9b0 |
|
|
shun-iwasawa |
75b9b0 |
QIcon icon;
|
|
konero |
7bed16 |
// Prepare for both normal and high dpi
|
|
shun-iwasawa |
75b9b0 |
for (int devPixelRatio = 1; devPixelRatio <= 2; devPixelRatio++) {
|
|
konero |
7bed16 |
QImage transparentImg(menubarIconSize * devPixelRatio,
|
|
konero |
7bed16 |
menubarIconSize * devPixelRatio,
|
|
konero |
7bed16 |
QImage::Format_ARGB32);
|
|
konero |
7bed16 |
transparentImg.fill(Qt::transparent);
|
|
shun-iwasawa |
75b9b0 |
|
|
shun-iwasawa |
75b9b0 |
int pxSize = visibleIconSize * devPixelRatio;
|
|
shun-iwasawa |
75b9b0 |
|
|
konero |
7bed16 |
QImage charImg(pxSize, pxSize, QImage::Format_ARGB32_Premultiplied);
|
|
shun-iwasawa |
75b9b0 |
QPainter painter;
|
|
konero |
7bed16 |
charImg.fill(Qt::transparent);
|
|
konero |
7bed16 |
painter.begin(&charImg);
|
|
shun-iwasawa |
75b9b0 |
|
|
shun-iwasawa |
75b9b0 |
painter.setPen(Preferences::instance()->getIconTheme() ? Qt::black
|
|
shun-iwasawa |
75b9b0 |
: Qt::white);
|
|
shun-iwasawa |
75b9b0 |
|
|
shun-iwasawa |
75b9b0 |
QRect rect(0, -2, pxSize, pxSize);
|
|
shun-iwasawa |
75b9b0 |
if (iconStr.size() == 2) {
|
|
shun-iwasawa |
75b9b0 |
painter.scale(0.6, 1.0);
|
|
shun-iwasawa |
75b9b0 |
rect.setRight(pxSize / 0.6);
|
|
shun-iwasawa |
75b9b0 |
}
|
|
shun-iwasawa |
75b9b0 |
QFont font = painter.font();
|
|
shun-iwasawa |
75b9b0 |
font.setPixelSize(pxSize);
|
|
shun-iwasawa |
75b9b0 |
painter.setFont(font);
|
|
shun-iwasawa |
75b9b0 |
painter.drawText(rect, Qt::AlignCenter, iconStr);
|
|
shun-iwasawa |
75b9b0 |
|
|
shun-iwasawa |
75b9b0 |
painter.end();
|
|
shun-iwasawa |
75b9b0 |
|
|
Kite |
c50ec4 |
// For menu only
|
|
konero |
7bed16 |
addPixmapToAllModesAndStates(icon, QPixmap::fromImage(transparentImg));
|
|
Kite |
c50ec4 |
|
|
Kite |
c50ec4 |
// For toolbars
|
|
konero |
7bed16 |
addImagesToIcon(icon, charImg);
|
|
shun-iwasawa |
75b9b0 |
}
|
|
konero |
7bed16 |
|
|
shun-iwasawa |
75b9b0 |
return icon;
|
|
shun-iwasawa |
75b9b0 |
}
|
|
shun-iwasawa |
75b9b0 |
|
|
shun-iwasawa |
75b9b0 |
//-----------------------------------------------------------------------------
|
|
shun-iwasawa |
75b9b0 |
|
|
Shinya Kitaoka |
120a6e |
QString toQString(const TFilePath &path) {
|
|
Shinya Kitaoka |
120a6e |
return QString::fromStdWString(path.getWideString());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool isSpaceString(const QString &str) {
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
QString space(" ");
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < str.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (str.at(i) != space.at(0)) return false;
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool isValidFileName(const QString &fileName) {
|
|
Shinya Kitaoka |
120a6e |
if (fileName.isEmpty() || fileName.contains(":") || fileName.contains("\\") ||
|
|
Shinya Kitaoka |
120a6e |
fileName.contains("/") || fileName.contains(">") ||
|
|
Shinya Kitaoka |
120a6e |
fileName.contains("<") || fileName.contains("*") ||
|
|
Shinya Kitaoka |
120a6e |
fileName.contains("|") || fileName.contains("\"") ||
|
|
Shinya Kitaoka |
120a6e |
fileName.contains("?") || fileName.trimmed().isEmpty())
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool isValidFileName_message(const QString &fileName) {
|
|
Shinya Kitaoka |
120a6e |
return isValidFileName(fileName)
|
|
Shinya Kitaoka |
120a6e |
? true
|
|
Shinya Kitaoka |
120a6e |
: (DVGui::error(
|
|
Shinya Kitaoka |
120a6e |
QObject::tr("The file name cannot be empty or contain any "
|
|
Shinya Kitaoka |
120a6e |
"of the following "
|
|
Shinya Kitaoka |
120a6e |
"characters: (new line) \\ / : * ? \" |")),
|
|
Shinya Kitaoka |
120a6e |
false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
manongjohn |
7f3150 |
bool isReservedFileName(const QString &fileName) {
|
|
manongjohn |
7f3150 |
#ifdef _WIN32
|
|
manongjohn |
7f3150 |
std::vector<qstring> invalidNames{</qstring>
|
|
manongjohn |
7f3150 |
"AUX", "CON", "NUL", "PRN", "COM1", "COM2", "COM3", "COM4",
|
|
manongjohn |
7f3150 |
"COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3",
|
|
manongjohn |
7f3150 |
"LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"};
|
|
manongjohn |
7f3150 |
|
|
manongjohn |
7f3150 |
if (std::find(invalidNames.begin(), invalidNames.end(), fileName) !=
|
|
manongjohn |
7f3150 |
invalidNames.end())
|
|
manongjohn |
7f3150 |
return true;
|
|
manongjohn |
7f3150 |
#endif
|
|
manongjohn |
7f3150 |
|
|
manongjohn |
7f3150 |
return false;
|
|
manongjohn |
7f3150 |
}
|
|
manongjohn |
7f3150 |
|
|
manongjohn |
7f3150 |
//-----------------------------------------------------------------------------
|
|
manongjohn |
7f3150 |
|
|
manongjohn |
7f3150 |
bool isReservedFileName_message(const QString &fileName) {
|
|
manongjohn |
7f3150 |
return isReservedFileName(fileName)
|
|
manongjohn |
7f3150 |
? (DVGui::error(QObject::tr(
|
|
manongjohn |
7f3150 |
"That is a reserved file name and cannot be used.")),
|
|
manongjohn |
7f3150 |
true)
|
|
manongjohn |
7f3150 |
: false;
|
|
manongjohn |
7f3150 |
}
|
|
manongjohn |
7f3150 |
|
|
manongjohn |
7f3150 |
//-----------------------------------------------------------------------------
|
|
manongjohn |
7f3150 |
|
|
Shinya Kitaoka |
120a6e |
QString elideText(const QString &srcText, const QFont &font, int width) {
|
|
Shinya Kitaoka |
120a6e |
QFontMetrics metrix(font);
|
|
shun-iwasawa |
443318 |
int srcWidth = metrix.horizontalAdvance(srcText);
|
|
Shinya Kitaoka |
120a6e |
if (srcWidth < width) return srcText;
|
|
shun-iwasawa |
443318 |
int tilde = metrix.horizontalAdvance("~");
|
|
Shinya Kitaoka |
120a6e |
int block = (width - tilde) / 2;
|
|
Shinya Kitaoka |
120a6e |
QString text("");
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < srcText.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
text += srcText.at(i);
|
|
shun-iwasawa |
443318 |
if (metrix.horizontalAdvance(text) > block) break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
text[i] = '~';
|
|
Shinya Kitaoka |
120a6e |
QString endText("");
|
|
Shinya Kitaoka |
120a6e |
for (i = srcText.size() - 1; i >= 0; i--) {
|
|
Shinya Kitaoka |
120a6e |
endText.push_front(srcText.at(i));
|
|
shun-iwasawa |
443318 |
if (metrix.horizontalAdvance(endText) > block) break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
endText.remove(0, 1);
|
|
Shinya Kitaoka |
120a6e |
text += endText;
|
|
Shinya Kitaoka |
120a6e |
return text;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QString elideText(const QString &srcText, const QFontMetrics &fm, int width,
|
|
Shinya Kitaoka |
120a6e |
const QString &elideSymbol) {
|
|
Shinya Kitaoka |
120a6e |
QString text(srcText);
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
443318 |
for (int i = text.size(); i > 1 && fm.horizontalAdvance(text) > width;)
|
|
Shinya Kitaoka |
120a6e |
text = srcText.left(--i).append(elideSymbol);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return text;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QUrl pathToUrl(const TFilePath &path) {
|
|
Shinya Kitaoka |
120a6e |
return QUrl::fromLocalFile(QString::fromStdWString(path.getWideString()));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool isResource(const QString &path) {
|
|
Shinya Kitaoka |
120a6e |
const TFilePath fp(path.toStdWString());
|
|
Shinya Kitaoka |
120a6e |
TFileType::Type type = TFileType::getInfo(fp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return (TFileType::isViewable(type) || type & TFileType::MESH_IMAGE ||
|
|
Shinya Kitaoka |
120a6e |
type == TFileType::AUDIO_LEVEL || type == TFileType::TABSCENE ||
|
|
Shinya Kitaoka |
120a6e |
type == TFileType::TOONZSCENE || fp.getType() == "tpl");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool isResource(const QUrl &url) { return isResource(url.toLocalFile()); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool isResourceOrFolder(const QUrl &url) {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
static inline bool isDir(const QString &path) {
|
|
Shinya Kitaoka |
120a6e |
return QFileInfo(path).isDir();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}; // locals
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const QString &path = url.toLocalFile();
|
|
Shinya Kitaoka |
120a6e |
return (isResource(path) || locals::isDir(path));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool acceptResourceDrop(const QList<qurl> &urls) {</qurl>
|
|
Shinya Kitaoka |
120a6e |
int count = 0;
|
|
otakuto |
dfe1cf |
for (const QUrl &url : urls) {
|
|
Shinya Kitaoka |
120a6e |
if (isResource(url))
|
|
Shinya Kitaoka |
120a6e |
++count;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (count > 0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool acceptResourceOrFolderDrop(const QList<qurl> &urls) {</qurl>
|
|
Shinya Kitaoka |
120a6e |
int count = 0;
|
|
otakuto |
dfe1cf |
for (const QUrl &url : urls) {
|
|
Shinya Kitaoka |
120a6e |
if (isResourceOrFolder(url))
|
|
Shinya Kitaoka |
120a6e |
++count;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (count > 0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QPainterPath strokeToPainterPath(TStroke *stroke) {
|
|
Shinya Kitaoka |
120a6e |
QPainterPath path;
|
|
Shinya Kitaoka |
120a6e |
int i, chunkSize = stroke->getChunkCount();
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < chunkSize; i++) {
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *q = stroke->getChunk(i);
|
|
Shinya Kitaoka |
120a6e |
if (i == 0) path.moveTo(toQPointF(q->getThickP0()));
|
|
Shinya Kitaoka |
120a6e |
path.quadTo(toQPointF(q->getThickP1()), toQPointF(q->getThickP2()));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return path;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// TabBarContainter
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TabBarContainter::TabBarContainter(QWidget *parent) : QFrame(parent) {
|
|
Shinya Kitaoka |
120a6e |
setObjectName("TabBarContainer");
|
|
Shinya Kitaoka |
120a6e |
setFrameStyle(QFrame::StyledPanel);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TabBarContainter::paintEvent(QPaintEvent *event) {
|
|
Shinya Kitaoka |
120a6e |
QPainter p(this);
|
|
Jeremy Bullock |
0f89c5 |
p.setPen(getBottomAboveLineColor());
|
|
Shinya Kitaoka |
120a6e |
p.drawLine(0, height() - 2, width(), height() - 2);
|
|
Jeremy Bullock |
0f89c5 |
p.setPen(getBottomBelowLineColor());
|
|
Shinya Kitaoka |
120a6e |
p.drawLine(0, height() - 1, width(), height() - 1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// ToolBarContainer
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ToolBarContainer::ToolBarContainer(QWidget *parent) : QFrame(parent) {
|
|
Shinya Kitaoka |
120a6e |
setObjectName("ToolBarContainer");
|
|
Shinya Kitaoka |
120a6e |
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Kite |
521c84 |
void ToolBarContainer::paintEvent(QPaintEvent *event) { QPainter p(this); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QString operator+(const QString &a, const TFilePath &fp) {
|
|
Shinya Kitaoka |
120a6e |
return a + QString::fromStdWString(fp.getWideString());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//=============================================================================
|
|
konero |
7bed16 |
// Theme Manager
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
class ThemeManager::ThemeManagerImpl {
|
|
konero |
7bed16 |
public:
|
|
konero |
7bed16 |
QMap<qstring, qstring=""> m_iconPaths;</qstring,>
|
|
konero |
7bed16 |
qreal m_onOpacity = 1.0;
|
|
konero |
7bed16 |
qreal m_offOpacity = 0.8;
|
|
konero |
7bed16 |
qreal m_disabledOpacity = 0.3;
|
|
konero |
7bed16 |
};
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
ThemeManager::ThemeManager() : impl(new ThemeManagerImpl) {}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
ThemeManager::~ThemeManager() {}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
ThemeManager &ThemeManager::getInstance() {
|
|
konero |
7bed16 |
static ThemeManager instance;
|
|
konero |
7bed16 |
return instance;
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Populate a QMap with icon filepaths and assign their basename as the key
|
|
konero |
7bed16 |
void ThemeManager::buildIconPathsMap(const QString &path) {
|
|
konero |
7bed16 |
QDir dir(path);
|
|
konero |
7bed16 |
if (!dir.exists(path)) {
|
|
konero |
7bed16 |
qDebug() << "Resource path does not exist:" << path;
|
|
konero |
7bed16 |
return;
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QDirIterator it(path,
|
|
konero |
7bed16 |
QStringList() << "*.svg"
|
|
konero |
7bed16 |
<< "*.png",
|
|
konero |
7bed16 |
QDir::Files, QDirIterator::Subdirectories);
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
while (it.hasNext()) {
|
|
konero |
7bed16 |
it.next();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
const QString iconPath = it.fileInfo().filePath();
|
|
konero |
7bed16 |
const QString iconName = it.fileInfo().baseName();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
if (!impl->m_iconPaths.contains(iconName)) {
|
|
konero |
7bed16 |
impl->m_iconPaths.insert(iconName, iconPath);
|
|
konero |
7bed16 |
} else {
|
|
konero |
7bed16 |
qDebug() << "Icon with file name already exists in iconPaths, ensure "
|
|
konero |
7bed16 |
"icons have unique file names:"
|
|
konero |
7bed16 |
<< "\nCurrently added:" << getIconPath(iconName)
|
|
konero |
7bed16 |
<< "\nTried to add:" << iconPath;
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Get the full filepath of an icon image by basename
|
|
konero |
7bed16 |
QString ThemeManager::getIconPath(const QString &iconName) const {
|
|
konero |
7bed16 |
return impl->m_iconPaths.value(iconName);
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Boolean to check if iconName is contained within the iconPaths QMap
|
|
konero |
7bed16 |
bool ThemeManager::hasIcon(const QString &iconName) const {
|
|
konero |
7bed16 |
return impl->m_iconPaths.contains(iconName);
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
qreal ThemeManager::getOnOpacity() const { return impl->m_onOpacity; }
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
qreal ThemeManager::getOffOpacity() const { return impl->m_offOpacity; }
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
qreal ThemeManager::getDisabledOpacity() const {
|
|
konero |
7bed16 |
return impl->m_disabledOpacity;
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Colorize black pixels in a QImage while retaining other colors, however be
|
|
konero |
7bed16 |
// mindful that if black pixels overlap color pixels it can cause artifacting
|
|
konero |
7bed16 |
QImage ThemeManager::recolorBlackPixels(const QImage &input, QColor color) {
|
|
konero |
7bed16 |
if (input.isNull() || color == Qt::black) return QImage();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Default is icon theme color
|
|
konero |
7bed16 |
if (!color.isValid())
|
|
konero |
7bed16 |
color = Preferences::instance()->getIconTheme() ? Qt::black : Qt::white;
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QImage image = input.convertToFormat(QImage::Format_ARGB32);
|
|
konero |
7bed16 |
QRgb targetColor = color.rgb();
|
|
konero |
7bed16 |
int height = image.height();
|
|
konero |
7bed16 |
int width = image.width();
|
|
konero |
7bed16 |
for (int y = 0; y < height; ++y) {
|
|
konero |
7bed16 |
QRgb *pixel = reinterpret_cast<qrgb *="">(image.scanLine(y));</qrgb>
|
|
konero |
7bed16 |
QRgb *end = pixel + width;
|
|
konero |
7bed16 |
for (; pixel != end; ++pixel) {
|
|
konero |
7bed16 |
if (qGray(*pixel) == 0) {
|
|
konero |
7bed16 |
*pixel = (targetColor & 0x00FFFFFF) | (qAlpha(*pixel) << 24);
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
return image;
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Colorize black pixels in a QPixmap while retaining other colors, however be
|
|
konero |
7bed16 |
// mindful that if black pixels overlap color pixels if can cause artifacting
|
|
konero |
7bed16 |
QPixmap ThemeManager::recolorBlackPixels(const QPixmap &input, QColor color) {
|
|
konero |
7bed16 |
if (input.isNull() || color == Qt::black) return QPixmap();
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
QImage image = input.toImage();
|
|
konero |
7bed16 |
QImage recoloredImage = recolorBlackPixels(image, color);
|
|
konero |
7bed16 |
QPixmap pixmap = convertImageToPixmap(recoloredImage);
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
return pixmap;
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// For debugging contents
|
|
konero |
7bed16 |
void ThemeManager::printiconPathsMap() {
|
|
konero |
7bed16 |
const QMap<qstring, qstring=""> map = impl->m_iconPaths;</qstring,>
|
|
konero |
7bed16 |
qDebug() << "Contents of QMap:";
|
|
konero |
7bed16 |
for (auto it = map.constBegin(); it != map.constEnd(); ++it) {
|
|
konero |
7bed16 |
qDebug() << it.key() << ":" << it.value();
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
}
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
//-----------------------------------------------------------------------------
|
|
konero |
7bed16 |
|
|
konero |
7bed16 |
// Public version of ThemeManager::getIconPath()
|
|
konero |
7bed16 |
QString getIconPath(const QString &path) {
|
|
konero |
7bed16 |
return ThemeManager::getInstance().getIconPath(path);
|
|
konero |
7bed16 |
}
|