forked from qt-creator/qt-creator
QmlDesigner: Add navigator preview tooltip for images and textures
Show custom tooltip for image and texture items that shows the source image. Task-number: QDS-2750 Change-Id: If8c491f513d9fcada74300206d6cbc3af80c7663 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -336,6 +336,8 @@ extend_qtc_plugin(QmlDesigner
|
||||
navigatorwidget.cpp navigatorwidget.h
|
||||
choosetexturepropertydialog.cpp choosetexturepropertydialog.h
|
||||
choosetexturepropertydialog.ui
|
||||
previewtooltip.cpp previewtooltip.h
|
||||
previewtooltip.ui
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
|
@@ -6,7 +6,8 @@ SOURCES += navigatorview.cpp \
|
||||
nameitemdelegate.cpp \
|
||||
iconcheckboxitemdelegate.cpp \
|
||||
navigatortreeview.cpp \
|
||||
choosetexturepropertydialog.cpp
|
||||
choosetexturepropertydialog.cpp \
|
||||
previewtooltip.cpp
|
||||
|
||||
HEADERS += navigatorview.h \
|
||||
navigatortreemodel.h \
|
||||
@@ -15,8 +16,10 @@ HEADERS += navigatorview.h \
|
||||
iconcheckboxitemdelegate.h \
|
||||
navigatortreeview.h \
|
||||
navigatormodelinterface.h \
|
||||
choosetexturepropertydialog.h
|
||||
choosetexturepropertydialog.h \
|
||||
previewtooltip.h
|
||||
|
||||
RESOURCES += navigator.qrc
|
||||
|
||||
FORMS += choosetexturepropertydialog.ui
|
||||
FORMS += choosetexturepropertydialog.ui \
|
||||
previewtooltip.ui
|
||||
|
@@ -53,6 +53,7 @@
|
||||
#include <QPointF>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QDateTime>
|
||||
|
||||
#include <coreplugin/messagebox.h>
|
||||
|
||||
@@ -200,6 +201,13 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
||||
if (role == ItemIsVisibleRole) //independent of column
|
||||
return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked;
|
||||
|
||||
auto hasImageToolTip = [modelNode]() -> bool {
|
||||
if (modelNode.isValid() && modelNode.metaInfo().isValid())
|
||||
return modelNode.type() == "QtQuick.Image" || modelNode.type() == "QtQuick3D.Texture";
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
if (index.column() == 0) {
|
||||
if (role == Qt::DisplayRole) {
|
||||
return modelNode.displayName();
|
||||
@@ -212,17 +220,81 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
||||
} else if (role == Qt::ToolTipRole) {
|
||||
if (currentQmlObjectNode.hasError()) {
|
||||
QString errorString = currentQmlObjectNode.error();
|
||||
if (DesignerSettings::getValue(DesignerSettingsKey::STANDALONE_MODE).toBool() &&
|
||||
currentQmlObjectNode.isRootNode())
|
||||
if (DesignerSettings::getValue(DesignerSettingsKey::STANDALONE_MODE).toBool()
|
||||
&& currentQmlObjectNode.isRootNode()) {
|
||||
errorString.append(QString("\n%1").arg(tr("Changing the setting \"%1\" might solve the issue.").arg(
|
||||
tr("Use QML emulation layer that is built with the selected Qt"))));
|
||||
|
||||
}
|
||||
return errorString;
|
||||
}
|
||||
if (modelNode.metaInfo().isValid())
|
||||
return modelNode.type();
|
||||
else
|
||||
|
||||
if (modelNode.metaInfo().isValid()) {
|
||||
if (hasImageToolTip())
|
||||
return {}; // Images have special tooltip popup, so suppress regular one
|
||||
else
|
||||
return modelNode.type();
|
||||
} else {
|
||||
return msgUnknownItem(QString::fromUtf8(modelNode.type()));
|
||||
}
|
||||
} else if (role == ToolTipImageRole) {
|
||||
if (currentQmlObjectNode.hasError()) // Error already shown on regular tooltip
|
||||
return {};
|
||||
|
||||
if (hasImageToolTip()) {
|
||||
VariantProperty prop = modelNode.variantProperty("source");
|
||||
QString imageSource = prop.value().toString();
|
||||
QFileInfo fi(imageSource);
|
||||
if (fi.isRelative())
|
||||
imageSource = QmlDesignerPlugin::instance()->documentManager().currentFilePath().toFileInfo().dir().absoluteFilePath(imageSource);
|
||||
fi = QFileInfo(imageSource);
|
||||
QDateTime modified = fi.lastModified();
|
||||
|
||||
struct ImageData {
|
||||
QDateTime time;
|
||||
QImage image;
|
||||
QString type;
|
||||
QString id;
|
||||
QString info;
|
||||
};
|
||||
|
||||
static QHash<QString, ImageData> toolTipImageMap;
|
||||
|
||||
ImageData imageData;
|
||||
bool reload = true;
|
||||
if (toolTipImageMap.contains(imageSource)) {
|
||||
imageData = toolTipImageMap[imageSource];
|
||||
if (modified == imageData.time)
|
||||
reload = false;
|
||||
}
|
||||
|
||||
if (reload) {
|
||||
QImage originalImage;
|
||||
originalImage.load(imageSource);
|
||||
if (!originalImage.isNull()) {
|
||||
imageData.image = originalImage.scaled(150, 150, Qt::KeepAspectRatio);
|
||||
double imgSize = double(fi.size());
|
||||
imageData.type = QStringLiteral("%1 (%2)").arg(QString::fromLatin1(modelNode.type())).arg(fi.suffix());
|
||||
imageData.id = modelNode.id();
|
||||
static QStringList units({tr("B"), tr("KB"), tr("MB"), tr("GB")});
|
||||
int unitIndex = 0;
|
||||
while (imgSize > 1024. && unitIndex < units.size() - 1) {
|
||||
++unitIndex;
|
||||
imgSize /= 1024.;
|
||||
}
|
||||
imageData.info = QStringLiteral("%1 x %2 (%3%4)").arg(originalImage.width()).arg(originalImage.height())
|
||||
.arg(QString::number(imgSize, 'g', 3)).arg(units[unitIndex]);
|
||||
toolTipImageMap.insert(imageSource, imageData);
|
||||
}
|
||||
}
|
||||
if (!imageData.image.isNull()) {
|
||||
QVariantMap map;
|
||||
map.insert("type", imageData.type);
|
||||
map.insert("image", QVariant::fromValue<QImage>(imageData.image));
|
||||
map.insert("id", imageData.id);
|
||||
map.insert("info", imageData.info);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
} else if (role == ModelNodeRole) {
|
||||
return QVariant::fromValue<ModelNode>(modelNode);
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "navigatorview.h"
|
||||
#include "navigatortreemodel.h"
|
||||
#include "qproxystyle.h"
|
||||
#include "previewtooltip.h"
|
||||
|
||||
#include <metainfo.h>
|
||||
|
||||
@@ -42,7 +43,9 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QStyleFactory>
|
||||
|
||||
#include <QEvent>
|
||||
#include <QImage>
|
||||
#include <QApplication>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
@@ -174,5 +177,36 @@ void NavigatorTreeView::drawSelectionBackground(QPainter *painter, const QStyleO
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
bool NavigatorTreeView::viewportEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::ToolTip) {
|
||||
auto navModel = qobject_cast<NavigatorTreeModel *>(model());
|
||||
if (navModel) {
|
||||
QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
|
||||
QModelIndex index = indexAt(helpEvent->pos());
|
||||
QVariantMap imgMap = navModel->data(index, ToolTipImageRole).toMap();
|
||||
|
||||
if (!imgMap.isEmpty()) {
|
||||
if (!m_previewToolTip)
|
||||
m_previewToolTip = new PreviewToolTip(QApplication::activeWindow());
|
||||
m_previewToolTip->setId(imgMap["id"].toString());
|
||||
m_previewToolTip->setType(imgMap["type"].toString());
|
||||
m_previewToolTip->setInfo(imgMap["info"].toString());
|
||||
m_previewToolTip->setImage(imgMap["image"].value<QImage>());
|
||||
m_previewToolTip->move(helpEvent->pos());
|
||||
if (!m_previewToolTip->isVisible())
|
||||
m_previewToolTip->show();
|
||||
} else if (m_previewToolTip) {
|
||||
m_previewToolTip->hide();
|
||||
}
|
||||
}
|
||||
} else if (event->type() == QEvent::Leave) {
|
||||
if (m_previewToolTip)
|
||||
m_previewToolTip->hide();
|
||||
}
|
||||
|
||||
return QTreeView::viewportEvent(event);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -29,6 +29,8 @@
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class PreviewToolTip;
|
||||
|
||||
class NavigatorTreeView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -36,5 +38,9 @@ class NavigatorTreeView : public QTreeView
|
||||
public:
|
||||
NavigatorTreeView(QWidget *parent = nullptr);
|
||||
static void drawSelectionBackground(QPainter *painter, const QStyleOption &option);
|
||||
bool viewportEvent(QEvent *event) override;
|
||||
|
||||
private:
|
||||
PreviewToolTip *m_previewToolTip = nullptr;
|
||||
};
|
||||
}
|
||||
|
@@ -48,7 +48,8 @@ class NavigatorTreeModel;
|
||||
enum NavigatorRoles {
|
||||
ItemIsVisibleRole = Qt::UserRole,
|
||||
RowIsPropertyRole = Qt::UserRole + 1,
|
||||
ModelNodeRole = Qt::UserRole + 2
|
||||
ModelNodeRole = Qt::UserRole + 2,
|
||||
ToolTipImageRole = Qt::UserRole + 3
|
||||
};
|
||||
|
||||
class NavigatorView : public AbstractView
|
||||
|
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 "previewtooltip.h"
|
||||
#include "ui_previewtooltip.h"
|
||||
|
||||
#include <utils/theme/theme.h>
|
||||
|
||||
#include <QtGui/qpixmap.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
PreviewToolTip::PreviewToolTip(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::PreviewToolTip)
|
||||
{
|
||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
setWindowFlags(Qt::Widget);
|
||||
m_ui->setupUi(this);
|
||||
setStyleSheet(QString("QWidget { background-color: %1 }").arg(Utils::creatorTheme()->color(Utils::Theme::BackgroundColorNormal).name()));
|
||||
}
|
||||
|
||||
PreviewToolTip::~PreviewToolTip()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void PreviewToolTip::setId(const QString &id)
|
||||
{
|
||||
m_ui->idLabel->setText(id);
|
||||
}
|
||||
|
||||
void PreviewToolTip::setType(const QString &type)
|
||||
{
|
||||
m_ui->typeLabel->setText(type);
|
||||
}
|
||||
|
||||
void PreviewToolTip::setInfo(const QString &info)
|
||||
{
|
||||
m_ui->infoLabel->setText(info);
|
||||
}
|
||||
|
||||
void PreviewToolTip::setImage(const QImage &image)
|
||||
{
|
||||
m_ui->imageLabel->setPixmap(QPixmap::fromImage(image));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 <QtWidgets/qwidget.h>
|
||||
#include <QtGui/qimage.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Ui {
|
||||
class PreviewToolTip;
|
||||
}
|
||||
|
||||
class PreviewToolTip : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PreviewToolTip(QWidget *parent = nullptr);
|
||||
~PreviewToolTip();
|
||||
|
||||
void setId(const QString &id);
|
||||
void setType(const QString &type);
|
||||
void setInfo(const QString &info);
|
||||
void setImage(const QImage &image);
|
||||
|
||||
private:
|
||||
Ui::PreviewToolTip *m_ui;
|
||||
};
|
||||
}
|
190
src/plugins/qmldesigner/components/navigator/previewtooltip.ui
Normal file
190
src/plugins/qmldesigner/components/navigator/previewtooltip.ui
Normal file
@@ -0,0 +1,190 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QmlDesigner::PreviewToolTip</class>
|
||||
<widget class="QWidget" name="QmlDesigner::PreviewToolTip">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>160</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>1000</width>
|
||||
<height>1000</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizeGripEnabled" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<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="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>140</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"><image></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="idLabel">
|
||||
<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"><id label></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="typeLabel">
|
||||
<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"><type label></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="infoLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>3</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>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@@ -613,6 +613,9 @@ Project {
|
||||
"navigator/choosetexturepropertydialog.cpp",
|
||||
"navigator/choosetexturepropertydialog.h",
|
||||
"navigator/choosetexturepropertydialog.ui",
|
||||
"navigator/previewtooltip.cpp",
|
||||
"navigator/previewtooltip.h",
|
||||
"navigator/previewtooltip.ui",
|
||||
"propertyeditor/aligndistribute.cpp",
|
||||
"propertyeditor/aligndistribute.h",
|
||||
"propertyeditor/designerpropertymap.cpp",
|
||||
|
Reference in New Issue
Block a user