forked from qt-creator/qt-creator
QmlDesigner: Add font asset preview tooltip
Refactored item library component preview tooltip to be also suitable for asset previews. Also now using the same image cache for font asset icons. Fixes: QDS-3254 Fixes: QDS-3470 Change-Id: I34c1278be2e5697e01eaedabe2798104507a6ad8 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Marco Bubke <marco.bubke@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -44,10 +44,10 @@ QImage renderImage(ServerNodeInstance rootNodeInstance)
|
||||
|
||||
QSize previewImageSize = rootNodeInstance.boundingRect().size().toSize();
|
||||
if (previewImageSize.isEmpty())
|
||||
previewImageSize = {640, 480};
|
||||
previewImageSize = {300, 300};
|
||||
|
||||
if (previewImageSize.width() > 800 || previewImageSize.height() > 800)
|
||||
previewImageSize.scale({800, 800}, Qt::KeepAspectRatio);
|
||||
if (previewImageSize.width() > 300 || previewImageSize.height() > 300)
|
||||
previewImageSize.scale({300, 300}, Qt::KeepAspectRatio);
|
||||
|
||||
QImage previewImage = rootNodeInstance.renderPreviewImage(previewImageSize);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ MouseArea {
|
||||
onExited: tooltipBackend.hideTooltip()
|
||||
onCanceled: tooltipBackend.hideTooltip()
|
||||
onClicked: forceActiveFocus()
|
||||
onPositionChanged: tooltipBackend.reposition()
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
@@ -40,8 +41,8 @@ MouseArea {
|
||||
interval: 1000
|
||||
running: mouseArea.containsMouse
|
||||
onTriggered: {
|
||||
tooltipBackend.componentName = itemName
|
||||
tooltipBackend.componentPath = componentPath
|
||||
tooltipBackend.name = itemName
|
||||
tooltipBackend.path = componentPath
|
||||
tooltipBackend.showTooltip()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,6 +599,8 @@ extend_qtc_plugin(QmlDesigner
|
||||
|
||||
imagecache/imagecachecollector.h
|
||||
imagecache/imagecachecollector.cpp
|
||||
imagecache/imagecachefontcollector.h
|
||||
imagecache/imagecachefontcollector.cpp
|
||||
imagecache/imagecache.cpp
|
||||
imagecache/imagecachecollectorinterface.h
|
||||
imagecache/imagecacheconnectionmanager.cpp
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "customfilesystemmodel.h"
|
||||
|
||||
#include <theme.h>
|
||||
#include <imagecache.h>
|
||||
|
||||
#include <utils/filesystemwatcher.h>
|
||||
|
||||
@@ -37,8 +38,10 @@
|
||||
#include <QImageReader>
|
||||
#include <QPainter>
|
||||
#include <QRawFont>
|
||||
#include <QGlyphRun>
|
||||
#include <QPair>
|
||||
#include <qmath.h>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
@@ -84,68 +87,6 @@ static QPixmap defaultPixmapForType(const QString &type, const QSize &size)
|
||||
return QPixmap(QStringLiteral(":/ItemLibrary/images/asset_%1_%2.png").arg(type).arg(size.width()));
|
||||
}
|
||||
|
||||
static QPixmap generateFontImage(const QFileInfo &info, const QSize &size)
|
||||
{
|
||||
static QHash<QString, QPixmap> fontImageCache;
|
||||
const QString file = info.absoluteFilePath();
|
||||
const QString key = QStringLiteral("%1@%2@%3").arg(file).arg(size.width()).arg(size.height());
|
||||
if (!fontImageCache.contains(key)) {
|
||||
QPixmap pixmap(size);
|
||||
pixmap.fill(Qt::transparent);
|
||||
qreal pixelSize = size.width() / 2.;
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
QRawFont font(file, pixelSize);
|
||||
if (!font.isValid())
|
||||
break;
|
||||
QGlyphRun gr;
|
||||
gr.setRawFont(font);
|
||||
QVector<quint32> indices = font.glyphIndexesForString("Abc");
|
||||
if (indices.isEmpty())
|
||||
break;
|
||||
const QVector<QPointF> advances = font.advancesForGlyphIndexes(indices);
|
||||
QVector<QPointF> positions;
|
||||
QPointF totalAdvance;
|
||||
for (const QPointF &advance : advances) {
|
||||
positions.append(totalAdvance);
|
||||
totalAdvance += advance;
|
||||
}
|
||||
|
||||
gr.setGlyphIndexes(indices);
|
||||
gr.setPositions(positions);
|
||||
QRectF bounds = gr.boundingRect();
|
||||
if (bounds.width() <= 0 || bounds.height() <= 0)
|
||||
break;
|
||||
|
||||
bounds.moveCenter({size.width() / 2., size.height() / 2.});
|
||||
|
||||
// Bounding rectangle doesn't necessarily contain the entirety of glyphs for some
|
||||
// reason, so also check totalAdvance for overflow.
|
||||
qreal limitX = qMax(bounds.width(), totalAdvance.x());
|
||||
if (size.width() < limitX) {
|
||||
pixelSize = qreal(qFloor(pixelSize * size.width() / limitX));
|
||||
continue;
|
||||
}
|
||||
qreal limitY = qMax(bounds.height(), totalAdvance.y());
|
||||
if (size.height() < limitY) {
|
||||
pixelSize = qreal(qFloor(pixelSize * size.height() / limitY));
|
||||
continue;
|
||||
}
|
||||
|
||||
QPainter painter(&pixmap);
|
||||
painter.setPen(Theme::getColor(Theme::DStextColor));
|
||||
painter.drawGlyphRun(bounds.bottomLeft(), gr);
|
||||
done = true;
|
||||
}
|
||||
|
||||
if (!done)
|
||||
pixmap = defaultPixmapForType("font", size);
|
||||
|
||||
fontImageCache[key] = pixmap;
|
||||
}
|
||||
return fontImageCache[key];
|
||||
}
|
||||
|
||||
QString fontFamily(const QFileInfo &info)
|
||||
{
|
||||
QRawFont font(info.absoluteFilePath(), 10);
|
||||
@@ -157,21 +98,27 @@ QString fontFamily(const QFileInfo &info)
|
||||
class ItemLibraryFileIconProvider : public QFileIconProvider
|
||||
{
|
||||
public:
|
||||
ItemLibraryFileIconProvider() = default;
|
||||
ItemLibraryFileIconProvider(ImageCache &fontImageCache)
|
||||
: QFileIconProvider()
|
||||
, m_fontImageCache(fontImageCache)
|
||||
{
|
||||
}
|
||||
|
||||
QIcon icon( const QFileInfo & info ) const override
|
||||
{
|
||||
QIcon icon;
|
||||
const QString suffix = info.suffix();
|
||||
const QString filePath = info.absoluteFilePath();
|
||||
|
||||
if (supportedFontSuffixes().contains(suffix))
|
||||
return generateFontIcons(filePath);
|
||||
|
||||
for (auto iconSize : iconSizes) {
|
||||
// Provide icon depending on suffix
|
||||
QPixmap pixmap;
|
||||
|
||||
if (supportedImageSuffixes().contains(suffix))
|
||||
pixmap.load(info.absoluteFilePath());
|
||||
else if (supportedFontSuffixes().contains(suffix))
|
||||
pixmap = generateFontImage(info, iconSize);
|
||||
pixmap.load(filePath);
|
||||
else if (supportedAudioSuffixes().contains(suffix))
|
||||
pixmap = defaultPixmapForType("sound", iconSize);
|
||||
else if (supportedShaderSuffixes().contains(suffix))
|
||||
@@ -189,6 +136,61 @@ public:
|
||||
return icon;
|
||||
}
|
||||
|
||||
QIcon generateFontIcons(const QString &filePath) const
|
||||
{
|
||||
QIcon icon;
|
||||
QString colorName = Theme::getColor(Theme::DStextColor).name();
|
||||
std::condition_variable condition;
|
||||
int count = iconSizes.size();
|
||||
std::mutex mutex;
|
||||
QList<QPair<QSize, QImage>> images;
|
||||
|
||||
for (auto iconSize : iconSizes) {
|
||||
m_fontImageCache.requestImage(
|
||||
filePath,
|
||||
[&images, &condition, &count, &mutex, iconSize](const QImage &image) {
|
||||
int currentCount;
|
||||
{
|
||||
std::unique_lock lock{mutex};
|
||||
currentCount = --count;
|
||||
images.append({iconSize, image});
|
||||
}
|
||||
if (currentCount <= 0)
|
||||
condition.notify_all();
|
||||
},
|
||||
[&images, &condition, &count, &mutex, iconSize] {
|
||||
int currentCount;
|
||||
{
|
||||
std::unique_lock lock{mutex};
|
||||
currentCount = --count;
|
||||
images.append({iconSize, {}});
|
||||
}
|
||||
if (currentCount <= 0)
|
||||
condition.notify_all();
|
||||
},
|
||||
QStringLiteral("%1@%2@Abc").arg(QString::number(iconSize.width()),
|
||||
colorName)
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
// Block main thread until icons are generated, as it has to be done synchronously
|
||||
std::unique_lock lock{mutex};
|
||||
if (count > 0)
|
||||
condition.wait(lock, [&]{ return count <= 0; });
|
||||
}
|
||||
|
||||
for (const auto &pair : qAsConst(images)) {
|
||||
QImage image = pair.second;
|
||||
if (image.isNull())
|
||||
icon.addPixmap(defaultPixmapForType("font", pair.first));
|
||||
else
|
||||
icon.addPixmap(QPixmap::fromImage(image));
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
// Generated icon sizes should contain all ItemLibraryResourceView needed icon sizes, and their
|
||||
// x2 versions for HDPI sceens
|
||||
QList<QSize> iconSizes = {{384, 384}, {192, 192}, // Large
|
||||
@@ -197,13 +199,15 @@ public:
|
||||
{48, 48}, // Small
|
||||
{64, 64}, {32, 32}}; // List
|
||||
|
||||
ImageCache &m_fontImageCache;
|
||||
};
|
||||
|
||||
CustomFileSystemModel::CustomFileSystemModel(QObject *parent) : QAbstractListModel(parent)
|
||||
, m_fileSystemModel(new QFileSystemModel(this))
|
||||
, m_fileSystemWatcher(new Utils::FileSystemWatcher(this))
|
||||
CustomFileSystemModel::CustomFileSystemModel(ImageCache &fontImageCache, QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_fileSystemModel(new QFileSystemModel(this))
|
||||
, m_fileSystemWatcher(new Utils::FileSystemWatcher(this))
|
||||
{
|
||||
m_fileSystemModel->setIconProvider(new ItemLibraryFileIconProvider());
|
||||
m_fileSystemModel->setIconProvider(new ItemLibraryFileIconProvider(fontImageCache));
|
||||
|
||||
connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::directoryChanged, [this] {
|
||||
updatePath(m_fileSystemModel->rootPath());
|
||||
@@ -345,6 +349,20 @@ const QSet<QString> &CustomFileSystemModel::supportedSuffixes() const
|
||||
return allSuffixes;
|
||||
}
|
||||
|
||||
const QSet<QString> &CustomFileSystemModel::previewableSuffixes() const
|
||||
{
|
||||
static QSet<QString> previewableSuffixes;
|
||||
if (previewableSuffixes.isEmpty()) {
|
||||
auto insertSuffixes = [](const QStringList &suffixes) {
|
||||
for (const auto &suffix : suffixes)
|
||||
previewableSuffixes.insert(suffix);
|
||||
};
|
||||
insertSuffixes(supportedFontSuffixes());
|
||||
}
|
||||
return previewableSuffixes;
|
||||
|
||||
}
|
||||
|
||||
void CustomFileSystemModel::appendIfNotFiltered(const QString &file)
|
||||
{
|
||||
if (filterMetaIcons(file))
|
||||
|
||||
@@ -39,11 +39,13 @@ namespace Utils { class FileSystemWatcher; }
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ImageCache;
|
||||
|
||||
class CustomFileSystemModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CustomFileSystemModel(QObject *parent = nullptr);
|
||||
CustomFileSystemModel(ImageCache &fontImageCache, QObject *parent = nullptr);
|
||||
|
||||
void setFilter(QDir::Filters filters);
|
||||
QString rootPath() const;
|
||||
@@ -64,6 +66,7 @@ public:
|
||||
|
||||
QPair<QString, QByteArray> resourceTypeAndData(const QModelIndex &index) const;
|
||||
const QSet<QString> &supportedSuffixes() const;
|
||||
const QSet<QString> &previewableSuffixes() const;
|
||||
|
||||
private:
|
||||
QModelIndex updatePath(const QString &newPath);
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
|
||||
#include "customfilesystemmodel.h"
|
||||
|
||||
#include <theme.h>
|
||||
#include <imagecache.h>
|
||||
#include <previewtooltip/previewtooltipbackend.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QActionGroup>
|
||||
#include <QDebug>
|
||||
@@ -35,6 +39,7 @@
|
||||
#include <QMimeData>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QtGui/qevent.h>
|
||||
|
||||
#include <QProxyStyle>
|
||||
|
||||
@@ -58,7 +63,7 @@ void ItemLibraryResourceView::addSizeAction(QActionGroup *group, const QString &
|
||||
});
|
||||
}
|
||||
|
||||
ItemLibraryResourceView::ItemLibraryResourceView(QWidget *parent) :
|
||||
ItemLibraryResourceView::ItemLibraryResourceView(ImageCache &fontImageCache, QWidget *parent) :
|
||||
QListView(parent)
|
||||
{
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
@@ -102,6 +107,20 @@ ItemLibraryResourceView::ItemLibraryResourceView(QWidget *parent) :
|
||||
defaultAction->toggle();
|
||||
|
||||
addActions(actionGroup->actions());
|
||||
|
||||
viewport()->setAttribute(Qt::WA_Hover);
|
||||
m_fontPreviewTooltipBackend = std::make_unique<PreviewTooltipBackend>(fontImageCache);
|
||||
// Note: Though the text specified here appears in UI, it shouldn't be translated, as it's
|
||||
// a commonly used sentence to preview the font glyphs in latin fonts.
|
||||
// For fonts that do not have latin glyphs, the font family name will have to
|
||||
// suffice for preview. Font family name is inserted into %1 at render time.
|
||||
m_fontPreviewTooltipBackend->setState(QStringLiteral("%1@%2@%3")
|
||||
.arg(QString::number(300),
|
||||
Theme::getColor(Theme::DStextColor).name(),
|
||||
QStringLiteral("%1\n\n"
|
||||
"The quick brown fox jumps\n"
|
||||
"over the lazy dog\n"
|
||||
"1234567890")));
|
||||
}
|
||||
|
||||
void ItemLibraryResourceView::startDrag(Qt::DropActions /* supportedActions */)
|
||||
@@ -136,5 +155,51 @@ void ItemLibraryResourceView::startDrag(Qt::DropActions /* supportedActions */)
|
||||
drag->exec();
|
||||
}
|
||||
|
||||
bool ItemLibraryResourceView::viewportEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::ToolTip) {
|
||||
auto fileSystemModel = qobject_cast<CustomFileSystemModel *>(model());
|
||||
Q_ASSERT(fileSystemModel);
|
||||
QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
|
||||
QModelIndex index = indexAt(helpEvent->pos());
|
||||
if (index.isValid()) {
|
||||
QFileInfo fi = fileSystemModel->fileInfo(index);
|
||||
if (fileSystemModel->previewableSuffixes().contains(fi.suffix())) {
|
||||
QString filePath = fi.absoluteFilePath();
|
||||
if (!filePath.isEmpty()) {
|
||||
if (!m_fontPreviewTooltipBackend->isVisible()
|
||||
|| m_fontPreviewTooltipBackend->path() != filePath) {
|
||||
m_fontPreviewTooltipBackend->setPath(filePath);
|
||||
m_fontPreviewTooltipBackend->setName(fi.fileName());
|
||||
m_fontPreviewTooltipBackend->showTooltip();
|
||||
} else {
|
||||
m_fontPreviewTooltipBackend->reposition();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_fontPreviewTooltipBackend->hideTooltip();
|
||||
} else if (event->type() == QEvent::Leave) {
|
||||
m_fontPreviewTooltipBackend->hideTooltip();
|
||||
} else if (event->type() == QEvent::HoverMove) {
|
||||
if (m_fontPreviewTooltipBackend->isVisible()) {
|
||||
auto fileSystemModel = qobject_cast<CustomFileSystemModel *>(model());
|
||||
Q_ASSERT(fileSystemModel);
|
||||
auto *he = static_cast<QHoverEvent *>(event);
|
||||
QModelIndex index = indexAt(he->pos());
|
||||
if (index.isValid()) {
|
||||
QFileInfo fi = fileSystemModel->fileInfo(index);
|
||||
if (fi.absoluteFilePath() != m_fontPreviewTooltipBackend->path())
|
||||
m_fontPreviewTooltipBackend->hideTooltip();
|
||||
else
|
||||
m_fontPreviewTooltipBackend->reposition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QListView::viewportEvent(event);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
|
||||
@@ -33,15 +33,22 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class PreviewTooltipBackend;
|
||||
class ImageCache;
|
||||
|
||||
class ItemLibraryResourceView : public QListView {
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ItemLibraryResourceView(QWidget *parent = nullptr);
|
||||
explicit ItemLibraryResourceView(ImageCache &fontImageCache, QWidget *parent = nullptr);
|
||||
|
||||
void startDrag(Qt::DropActions supportedActions) override;
|
||||
bool viewportEvent(QEvent *event) override;
|
||||
|
||||
private:
|
||||
void addSizeAction(QActionGroup *group, const QString &text, int size, int iconSize);
|
||||
|
||||
std::unique_ptr<PreviewTooltipBackend> m_fontPreviewTooltipBackend;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <imagecache.h>
|
||||
#include <imagecache/imagecachecollector.h>
|
||||
#include <imagecache/imagecachefontcollector.h>
|
||||
#include <imagecache/imagecacheconnectionmanager.h>
|
||||
#include <imagecache/imagecachegenerator.h>
|
||||
#include <imagecache/imagecachestorage.h>
|
||||
@@ -55,9 +56,12 @@ public:
|
||||
ImageCacheStorage<Sqlite::Database> storage{database};
|
||||
ImageCacheConnectionManager connectionManager;
|
||||
ImageCacheCollector collector{connectionManager};
|
||||
ImageCacheFontCollector fontCollector;
|
||||
ImageCacheGenerator generator{collector, storage};
|
||||
ImageCacheGenerator fontGenerator{fontCollector, storage};
|
||||
TimeStampProvider timeStampProvider;
|
||||
ImageCache cache{storage, generator, timeStampProvider};
|
||||
ImageCache fontImageCache{storage, fontGenerator, timeStampProvider};
|
||||
};
|
||||
|
||||
ItemLibraryView::ItemLibraryView(QObject* parent)
|
||||
@@ -78,7 +82,7 @@ bool ItemLibraryView::hasWidget() const
|
||||
WidgetInfo ItemLibraryView::widgetInfo()
|
||||
{
|
||||
if (m_widget.isNull()) {
|
||||
m_widget = new ItemLibraryWidget{m_imageCacheData->cache};
|
||||
m_widget = new ItemLibraryWidget{m_imageCacheData->cache, m_imageCacheData->fontImageCache};
|
||||
m_widget->setImportsWidget(m_importManagerView->widgetInfo().widget);
|
||||
}
|
||||
|
||||
@@ -155,7 +159,7 @@ void ItemLibraryView::importsChanged(const QList<Import> &addedImports, const QL
|
||||
void ItemLibraryView::setResourcePath(const QString &resourcePath)
|
||||
{
|
||||
if (m_widget.isNull())
|
||||
m_widget = new ItemLibraryWidget{m_imageCacheData->cache};
|
||||
m_widget = new ItemLibraryWidget{m_imageCacheData->cache, m_imageCacheData->fontImageCache};
|
||||
|
||||
m_widget->setResourcePath(resourcePath);
|
||||
}
|
||||
|
||||
@@ -83,10 +83,10 @@ static QString propertyEditorResourcesPath() {
|
||||
return Core::ICore::resourcePath() + QStringLiteral("/qmldesigner/propertyEditorQmlSources");
|
||||
}
|
||||
|
||||
ItemLibraryWidget::ItemLibraryWidget(ImageCache &imageCache)
|
||||
ItemLibraryWidget::ItemLibraryWidget(ImageCache &imageCache, ImageCache &fontImageCache)
|
||||
: m_itemIconSize(24, 24)
|
||||
, m_itemViewQuickWidget(new QQuickWidget(this))
|
||||
, m_resourcesView(new ItemLibraryResourceView(this))
|
||||
, m_resourcesView(new ItemLibraryResourceView(fontImageCache, this))
|
||||
, m_importTagsWidget(new QWidget(this))
|
||||
, m_addResourcesWidget(new QWidget(this))
|
||||
, m_imageCache{imageCache}
|
||||
@@ -115,12 +115,11 @@ ItemLibraryWidget::ItemLibraryWidget(ImageCache &imageCache)
|
||||
m_previewTooltipBackend = std::make_unique<PreviewTooltipBackend>(m_imageCache);
|
||||
m_itemViewQuickWidget->rootContext()->setContextProperty("tooltipBackend",
|
||||
m_previewTooltipBackend.get());
|
||||
|
||||
m_itemViewQuickWidget->setClearColor(
|
||||
Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
||||
|
||||
/* create Resources view and its model */
|
||||
m_resourcesFileSystemModel = new CustomFileSystemModel(this);
|
||||
m_resourcesFileSystemModel = new CustomFileSystemModel(fontImageCache, this);
|
||||
m_resourcesView->setModel(m_resourcesFileSystemModel.data());
|
||||
|
||||
/* create image provider for loading item icons */
|
||||
|
||||
@@ -69,7 +69,7 @@ class ItemLibraryWidget : public QFrame
|
||||
};
|
||||
|
||||
public:
|
||||
ItemLibraryWidget(ImageCache &imageCache);
|
||||
ItemLibraryWidget(ImageCache &imageCache, ImageCache &fontImageCache);
|
||||
~ItemLibraryWidget();
|
||||
|
||||
void setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo);
|
||||
|
||||
@@ -36,28 +36,36 @@ PreviewImageTooltip::PreviewImageTooltip(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(std::make_unique<Ui::PreviewImageTooltip>())
|
||||
{
|
||||
// setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
setWindowFlags(Qt::ToolTip);
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowTransparentForInput
|
||||
| Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus);
|
||||
m_ui->setupUi(this);
|
||||
m_ui->nameLabel->setElideMode(Qt::ElideLeft);
|
||||
m_ui->pathLabel->setElideMode(Qt::ElideLeft);
|
||||
m_ui->infoLabel->setElideMode(Qt::ElideLeft);
|
||||
setStyleSheet(QString("QWidget { background-color: %1 }").arg(Utils::creatorTheme()->color(Utils::Theme::BackgroundColorNormal).name()));
|
||||
}
|
||||
|
||||
PreviewImageTooltip::~PreviewImageTooltip() = default;
|
||||
|
||||
void PreviewImageTooltip::setComponentPath(const QString &path)
|
||||
void PreviewImageTooltip::setName(const QString &name)
|
||||
{
|
||||
m_ui->componentPathLabel->setText(path);
|
||||
m_ui->nameLabel->setText(name);
|
||||
}
|
||||
|
||||
void PreviewImageTooltip::setComponentName(const QString &name)
|
||||
void PreviewImageTooltip::setPath(const QString &path)
|
||||
{
|
||||
m_ui->componentNameLabel->setText(name);
|
||||
m_ui->pathLabel->setText(path);
|
||||
}
|
||||
|
||||
void PreviewImageTooltip::setInfo(const QString &info)
|
||||
{
|
||||
m_ui->infoLabel->setText(info);
|
||||
}
|
||||
|
||||
void PreviewImageTooltip::setImage(const QImage &image)
|
||||
{
|
||||
resize(image.width() + 20 + m_ui->componentNameLabel->width(),
|
||||
std::max(image.height() + 20, height()));
|
||||
m_ui->imageLabel->setPixmap(QPixmap::fromImage({image}));
|
||||
m_ui->imageLabel->setPixmap(QPixmap::fromImage({image}).scaled(m_ui->imageLabel->width(),
|
||||
m_ui->imageLabel->height(),
|
||||
Qt::KeepAspectRatio));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,8 +43,9 @@ public:
|
||||
explicit PreviewImageTooltip(QWidget *parent = {});
|
||||
~PreviewImageTooltip();
|
||||
|
||||
void setComponentPath(const QString &path);
|
||||
void setComponentName(const QString &name);
|
||||
void setName(const QString &name);
|
||||
void setPath(const QString &path);
|
||||
void setInfo(const QString &info);
|
||||
void setImage(const QImage &pixmap);
|
||||
|
||||
private:
|
||||
|
||||
@@ -6,20 +6,20 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
<width>651</width>
|
||||
<height>318</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>200</height>
|
||||
<width>300</width>
|
||||
<height>140</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
@@ -64,37 +64,36 @@
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="componentPathLabel">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="imageLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
<width>300</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::NoTextInteraction</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="imageLabel">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
@@ -102,43 +101,89 @@
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Utils::ElidingLabel" name="componentNameLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::NoTextInteraction</set>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="Utils::ElidingLabel" name="nameLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"><name label></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::NoTextInteraction</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Utils::ElidingLabel" name="pathLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"><path label></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::NoTextInteraction</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Utils::ElidingLabel" name="infoLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"><info label></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::NoTextInteraction</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMetaObject>
|
||||
#include <QScreen>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
@@ -46,28 +47,25 @@ PreviewTooltipBackend::~PreviewTooltipBackend()
|
||||
|
||||
void PreviewTooltipBackend::showTooltip()
|
||||
{
|
||||
if (m_componentPath.isEmpty())
|
||||
return;
|
||||
|
||||
m_tooltip = std::make_unique<PreviewImageTooltip>();
|
||||
|
||||
m_tooltip->setComponentName(m_componentName);
|
||||
m_tooltip->setComponentPath(m_componentPath);
|
||||
m_tooltip->setName(m_name);
|
||||
m_tooltip->setPath(m_path);
|
||||
m_tooltip->setInfo(m_info);
|
||||
|
||||
m_cache.requestImage(
|
||||
m_componentPath,
|
||||
m_path,
|
||||
[tooltip = QPointer<PreviewImageTooltip>(m_tooltip.get())](const QImage &image) {
|
||||
QMetaObject::invokeMethod(tooltip, [tooltip, image] {
|
||||
if (tooltip)
|
||||
tooltip->setImage(image);
|
||||
});
|
||||
},
|
||||
[] {});
|
||||
[] {},
|
||||
m_state
|
||||
);
|
||||
|
||||
auto mousePosition = QCursor::pos();
|
||||
|
||||
mousePosition += {20, 20};
|
||||
m_tooltip->move(mousePosition);
|
||||
reposition();
|
||||
m_tooltip->show();
|
||||
}
|
||||
|
||||
@@ -79,30 +77,94 @@ void PreviewTooltipBackend::hideTooltip()
|
||||
m_tooltip.reset();
|
||||
}
|
||||
|
||||
QString QmlDesigner::PreviewTooltipBackend::componentPath() const
|
||||
bool PreviewTooltipBackend::isVisible() const
|
||||
{
|
||||
return m_componentPath;
|
||||
if (m_tooltip)
|
||||
return m_tooltip->isVisible();
|
||||
return false;
|
||||
}
|
||||
|
||||
void QmlDesigner::PreviewTooltipBackend::setComponentPath(const QString &path)
|
||||
void PreviewTooltipBackend::reposition()
|
||||
{
|
||||
m_componentPath = path;
|
||||
if (m_tooltip) {
|
||||
// By default tooltip is placed right and below the cursor, but if the screen
|
||||
// doesn't have sufficient space in that direction, position is adjusted.
|
||||
// It is assumed that some diagonal direction will have enough space.
|
||||
const QPoint mousePos = QCursor::pos();
|
||||
QScreen *screen = qApp->screenAt(mousePos);
|
||||
QRect tipRect = m_tooltip->geometry();
|
||||
QPoint offset(10, 5);
|
||||
QPoint pos = mousePos + offset;
|
||||
if (screen) {
|
||||
QRect rect = screen->geometry();
|
||||
tipRect.moveTo(pos);
|
||||
if (!rect.contains(tipRect)) {
|
||||
pos = mousePos + QPoint(-offset.x() - m_tooltip->size().width(),
|
||||
offset.y());
|
||||
tipRect.moveTo(pos);
|
||||
if (!rect.contains(tipRect)) {
|
||||
pos = mousePos + QPoint(offset.x(), -offset.y() - m_tooltip->size().height());
|
||||
tipRect.moveTo(pos);
|
||||
if (!rect.contains(tipRect)) {
|
||||
pos = mousePos + QPoint(-offset.x() - m_tooltip->size().width(),
|
||||
-offset.y() - m_tooltip->size().height());
|
||||
tipRect.moveTo(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_componentPath != path)
|
||||
emit componentPathChanged();
|
||||
m_tooltip->move(pos);
|
||||
}
|
||||
}
|
||||
|
||||
QString QmlDesigner::PreviewTooltipBackend::componentName() const
|
||||
QString PreviewTooltipBackend::name() const
|
||||
{
|
||||
return m_componentName;
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void QmlDesigner::PreviewTooltipBackend::setComponentName(const QString &name)
|
||||
void PreviewTooltipBackend::setName(const QString &name)
|
||||
{
|
||||
m_componentName = name;
|
||||
m_name = name;
|
||||
if (m_name != name)
|
||||
emit nameChanged();
|
||||
}
|
||||
|
||||
if (m_componentName != name)
|
||||
emit componentNameChanged();
|
||||
QString PreviewTooltipBackend::path() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
void PreviewTooltipBackend::setPath(const QString &path)
|
||||
{
|
||||
m_path = path;
|
||||
if (m_path != path)
|
||||
emit pathChanged();
|
||||
}
|
||||
|
||||
QString PreviewTooltipBackend::info() const
|
||||
{
|
||||
return m_info;
|
||||
}
|
||||
|
||||
void PreviewTooltipBackend::setInfo(const QString &info)
|
||||
{
|
||||
m_info = info;
|
||||
if (m_info != info)
|
||||
emit infoChanged();
|
||||
}
|
||||
|
||||
QString PreviewTooltipBackend::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
// Sets the imageCache state hint. Valid content depends on image cache collector used.
|
||||
void PreviewTooltipBackend::setState(const QString &state)
|
||||
{
|
||||
m_state = state;
|
||||
if (m_state != state)
|
||||
emit stateChanged();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -39,8 +39,10 @@ class PreviewTooltipBackend : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString componentPath READ componentPath WRITE setComponentPath NOTIFY componentPathChanged)
|
||||
Q_PROPERTY(QString componentName READ componentName WRITE setComponentName NOTIFY componentNameChanged)
|
||||
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
|
||||
Q_PROPERTY(QString info READ info WRITE setInfo NOTIFY infoChanged)
|
||||
Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged)
|
||||
|
||||
public:
|
||||
PreviewTooltipBackend(ImageCache &cache);
|
||||
@@ -48,20 +50,30 @@ public:
|
||||
|
||||
Q_INVOKABLE void showTooltip();
|
||||
Q_INVOKABLE void hideTooltip();
|
||||
Q_INVOKABLE void reposition();
|
||||
|
||||
QString componentPath() const;
|
||||
void setComponentPath(const QString &path);
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
QString path() const;
|
||||
void setPath(const QString &path);
|
||||
QString info() const;
|
||||
void setInfo(const QString &info);
|
||||
QString state() const;
|
||||
void setState(const QString &state);
|
||||
|
||||
QString componentName() const;
|
||||
void setComponentName(const QString &path);
|
||||
bool isVisible() const;
|
||||
|
||||
signals:
|
||||
void componentPathChanged();
|
||||
void componentNameChanged();
|
||||
void nameChanged();
|
||||
void pathChanged();
|
||||
void infoChanged();
|
||||
void stateChanged();
|
||||
|
||||
private:
|
||||
QString m_componentPath;
|
||||
QString m_componentName;
|
||||
QString m_name;
|
||||
QString m_path;
|
||||
QString m_info;
|
||||
QString m_state;
|
||||
std::unique_ptr<PreviewImageTooltip> m_tooltip;
|
||||
ImageCache &m_cache;
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ include (../../../../share/qtcreator/qml/qmlpuppet/types/types.pri)
|
||||
|
||||
SOURCES += $$PWD/model/abstractview.cpp \
|
||||
$$PWD/imagecache/imagecachecollector.cpp \
|
||||
$$PWD/imagecache/imagecachefontcollector.cpp \
|
||||
$$PWD/model/rewriterview.cpp \
|
||||
$$PWD/model/documentmessage.cpp \
|
||||
$$PWD/metainfo/metainfo.cpp \
|
||||
@@ -95,6 +96,7 @@ SOURCES += $$PWD/model/abstractview.cpp \
|
||||
|
||||
HEADERS += $$PWD/include/qmldesignercorelib_global.h \
|
||||
$$PWD/imagecache/imagecachecollector.h \
|
||||
$$PWD/imagecache/imagecachefontcollector.h \
|
||||
$$PWD/include/abstractview.h \
|
||||
$$PWD/include/nodeinstanceview.h \
|
||||
$$PWD/include/rewriterview.h \
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "imagecachefontcollector.h"
|
||||
|
||||
#include <theme.h>
|
||||
|
||||
#include <QtGui/qrawfont.h>
|
||||
#include <QtGui/qpainter.h>
|
||||
#include <QtGui/qimage.h>
|
||||
#include <QtGui/qfontdatabase.h>
|
||||
#include <QtGui/qfontmetrics.h>
|
||||
#include <QtCore/qfileinfo.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
ImageCacheFontCollector::ImageCacheFontCollector() = default;
|
||||
|
||||
ImageCacheFontCollector::~ImageCacheFontCollector() = default;
|
||||
|
||||
QByteArray fileToByteArray(QString const &filename)
|
||||
{
|
||||
QFile file(filename);
|
||||
QFileInfo fileInfo(file);
|
||||
|
||||
if (fileInfo.exists() && file.open(QFile::ReadOnly))
|
||||
return file.readAll();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ImageCacheFontCollector::start(Utils::SmallStringView name,
|
||||
Utils::SmallStringView state,
|
||||
CaptureCallback captureCallback,
|
||||
AbortCallback abortCallback)
|
||||
{
|
||||
// State contains size, text color, and sample text
|
||||
QStringList hints = QString(state).split('@');
|
||||
int dim(300);
|
||||
if (hints.size() >= 1) {
|
||||
bool ok = false;
|
||||
int newDim = QString(hints[0]).toInt(&ok);
|
||||
if (ok)
|
||||
dim = newDim;
|
||||
}
|
||||
QColor textColor(Theme::getColor(Theme::DStextColor));
|
||||
if (hints.size() >= 2)
|
||||
textColor.setNamedColor(hints[1]);
|
||||
QString text = hints.size() >= 3 ? hints[2] : "Abc";
|
||||
QSize size(dim, dim);
|
||||
QRect rect({0, 0}, size);
|
||||
|
||||
QByteArray fontData(fileToByteArray(QString(name)));
|
||||
if (!fontData.isEmpty()) {
|
||||
int fontId = QFontDatabase::addApplicationFontFromData(fontData);
|
||||
if (fontId != -1) {
|
||||
QRawFont rawFont(fontData, 10.); // Pixel size is irrelevant, we only need style/weight
|
||||
const QStringList families = QFontDatabase::applicationFontFamilies(fontId);
|
||||
if (!families.isEmpty()) {
|
||||
QString fontFamily = families.first();
|
||||
if (text.contains("%1"))
|
||||
text = text.arg(fontFamily);
|
||||
QFont font(fontFamily);
|
||||
font.setStyle(rawFont.style());
|
||||
font.setStyleName(rawFont.styleName());
|
||||
font.setWeight(rawFont.weight());
|
||||
QImage image(size, QImage::Format_ARGB32);
|
||||
image.fill(Qt::transparent);
|
||||
int pixelSize(200);
|
||||
int flags = Qt::AlignCenter;
|
||||
while (pixelSize >= 2) {
|
||||
font.setPixelSize(pixelSize);
|
||||
QFontMetrics fm(font, &image);
|
||||
QRect bounds = fm.boundingRect(rect, flags, text);
|
||||
if (bounds.width() < rect.width() && bounds.height() < rect.height()) {
|
||||
break;
|
||||
} else {
|
||||
int newPixelSize = pixelSize - 1;
|
||||
if (bounds.width() >= rect.width())
|
||||
newPixelSize = int(qreal(pixelSize) * qreal(rect.width()) / qreal(bounds.width()));
|
||||
else if (bounds.height() >= rect.height())
|
||||
newPixelSize = int(qreal(pixelSize) * qreal(rect.height()) / qreal(bounds.height()));
|
||||
if (newPixelSize < pixelSize)
|
||||
pixelSize = newPixelSize;
|
||||
else
|
||||
--pixelSize;
|
||||
}
|
||||
}
|
||||
|
||||
QPainter painter(&image);
|
||||
painter.setPen(textColor);
|
||||
painter.setFont(font);
|
||||
painter.drawText(rect, flags, text);
|
||||
|
||||
captureCallback(std::move(image));
|
||||
return;
|
||||
}
|
||||
QFontDatabase::removeApplicationFont(fontId);
|
||||
}
|
||||
}
|
||||
abortCallback();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imagecachecollectorinterface.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ImageCacheFontCollector final : public ImageCacheCollectorInterface
|
||||
{
|
||||
public:
|
||||
ImageCacheFontCollector();
|
||||
|
||||
~ImageCacheFontCollector();
|
||||
|
||||
void start(Utils::SmallStringView filePath,
|
||||
Utils::SmallStringView state,
|
||||
CaptureCallback captureCallback,
|
||||
AbortCallback abortCallback) override;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -418,6 +418,8 @@ Project {
|
||||
"include/imagecacheinterface.h",
|
||||
"imagecache/imagecachecollector.cpp",
|
||||
"imagecache/imagecachecollector.h",
|
||||
"imagecache/imagecachefontcollector.cpp",
|
||||
"imagecache/imagecachefontcollector.h",
|
||||
"imagecache/imagecache.cpp",
|
||||
"imagecache/imagecachecollectorinterface.h",
|
||||
"imagecache/imagecacheconnectionmanager.cpp",
|
||||
|
||||
Reference in New Issue
Block a user