aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hartmann <thomas.hartmann@qt.io>2023-06-29 17:22:42 +0200
committerThomas Hartmann <thomas.hartmann@qt.io>2023-07-06 14:08:06 +0000
commitb85eb8aa04df5f7e6fe7c68f6a0e36b739ed781e (patch)
tree514cdf0f7cac92dc361329cc49f50c7c5d441ae5
parentccdf0730dffd7769135dda7e1db866660961d495 (diff)
QmlDesigner: Keep context as background
When drilling into components we keep the context as an image in the background. Change-Id: I12c291ab1cff02d30f53f92ccd9a551a9dd63704 Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io> Reviewed-by: Henning Gründl <henning.gruendl@qt.io>
-rw-r--r--src/plugins/qmldesigner/components/componentcore/viewmanager.cpp5
-rw-r--r--src/plugins/qmldesigner/components/componentcore/viewmanager.h1
-rw-r--r--src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp12
-rw-r--r--src/plugins/qmldesigner/components/formeditor/backgroundaction.h8
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.cpp39
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.h4
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorview.cpp16
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorview.h1
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp56
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorwidget.h5
-rw-r--r--src/plugins/qmldesigner/designercore/include/auxiliarydataproperties.h2
-rw-r--r--src/plugins/qmldesigner/designercore/include/modelnode.h1
-rw-r--r--src/plugins/qmldesigner/designercore/model/model.cpp3
-rw-r--r--src/plugins/qmldesigner/designercore/model/modelnode.cpp6
-rw-r--r--src/plugins/qmldesigner/documentmanager.cpp5
15 files changed, 153 insertions, 11 deletions
diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp
index 29bee73620..fc30ab99f9 100644
--- a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp
@@ -480,6 +480,11 @@ void ViewManager::exportAsImage()
d->formEditorView.exportAsImage();
}
+QImage ViewManager::takeFormEditorScreenshot()
+{
+ return d->formEditorView.takeFormEditorScreenshot();
+}
+
void ViewManager::reformatFileUsingTextEditorView()
{
d->textEditorView.reformatFile();
diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.h b/src/plugins/qmldesigner/components/componentcore/viewmanager.h
index 4201065f99..a3cacbe907 100644
--- a/src/plugins/qmldesigner/components/componentcore/viewmanager.h
+++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.h
@@ -74,6 +74,7 @@ public:
const AbstractView *view() const;
void exportAsImage();
+ QImage takeFormEditorScreenshot();
void reformatFileUsingTextEditorView();
QWidgetAction *componentViewAction() const;
diff --git a/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp b/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp
index 37dfafad9a..07a16de7bb 100644
--- a/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp
@@ -3,6 +3,8 @@
#include "backgroundaction.h"
+#include <theme.h>
+
#include <utils/stylehelper.h>
#include <QComboBox>
@@ -28,6 +30,14 @@ QIcon iconForColor(const QColor &color) {
image.fill(0);
QPainter p(&image);
+ if (color == BackgroundAction::ContextImage) {
+ const QString unicode = Theme::getIconUnicode(Theme::Icon::textures_medium);
+ const QString fontName = "qtds_propertyIconFont.ttf";
+ QIcon icon = Utils::StyleHelper::getIconFromIconFont(fontName, unicode, 10, 10, Qt::white);
+
+ return icon;
+ }
+
p.fillRect(2, 2, size - 4, size - 4, Qt::black);
if (color.alpha() == 0) {
@@ -70,13 +80,13 @@ QList<QColor> BackgroundAction::colors()
{
static QColor alphaZero(Qt::transparent);
static QList<QColor> colorList = {alphaZero,
+ QColor(BackgroundAction::ContextImage),
QColor(Qt::black),
QColor(0x4c4e50),
QColor(Qt::darkGray),
QColor(Qt::lightGray),
QColor(Qt::white)};
-
return colorList;
}
diff --git a/src/plugins/qmldesigner/components/formeditor/backgroundaction.h b/src/plugins/qmldesigner/components/formeditor/backgroundaction.h
index 34bd4cd322..c6eeb212fe 100644
--- a/src/plugins/qmldesigner/components/formeditor/backgroundaction.h
+++ b/src/plugins/qmldesigner/components/formeditor/backgroundaction.h
@@ -11,14 +11,12 @@ namespace QmlDesigner {
class BackgroundAction : public QWidgetAction
{
- enum BackgroundType {
- CheckboardBackground,
- WhiteBackground,
- BlackBackground
- };
+ enum BackgroundType { CheckboardBackground, WhiteBackground, BlackBackground };
Q_OBJECT
public:
+ enum SpecialColor { ContextImage = Qt::yellow };
+
explicit BackgroundAction(QObject *parent);
void setColor(const QColor &color);
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.cpp
index 1e67884ad8..9549ce9dd4 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.cpp
@@ -2,9 +2,13 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "formeditorgraphicsview.h"
+#include "backgroundaction.h"
#include "formeditoritem.h"
#include "formeditorwidget.h"
#include "navigation2d.h"
+
+#include <theme.h>
+
#include <utils/hostosinfo.h>
#include <QAction>
@@ -198,10 +202,28 @@ void FormEditorGraphicsView::drawBackground(QPainter *painter, const QRectF &rec
painter->save();
painter->setBrushOrigin(0, 0);
- painter->fillRect(rectangle.intersected(rootItemRect()), backgroundBrush());
// paint rect around editable area
- painter->setPen(Qt::black);
- painter->drawRect(rootItemRect());
+
+ if (backgroundBrush().color() == BackgroundAction::ContextImage) {
+ painter->fillRect(rectangle.intersected(rootItemRect()), Qt::gray);
+ painter->setOpacity(0.5);
+ if (!m_backgroundImage.isNull())
+ painter->drawImage(rootItemRect().topLeft() + m_backgroundImage.offset(),
+ m_backgroundImage);
+ painter->setOpacity(1.0);
+ } else {
+ painter->fillRect(rectangle.intersected(rootItemRect()), backgroundBrush());
+ }
+
+ QPen pen(Utils::creatorTheme()->color(Utils::Theme::QmlDesigner_FormEditorSelectionColor));
+
+ pen.setStyle(Qt::DotLine);
+ pen.setWidth(1);
+
+ painter->setPen(pen);
+
+ painter->drawRect(rootItemRect().adjusted(-1, -1, 0, 0));
+
painter->restore();
}
@@ -210,6 +232,17 @@ void FormEditorGraphicsView::frame(const QRectF &boundingRect)
fitInView(boundingRect, Qt::KeepAspectRatio);
}
+void FormEditorGraphicsView::setBackgoundImage(const QImage &image)
+{
+ m_backgroundImage = image;
+ update();
+}
+
+QImage FormEditorGraphicsView::backgroundImage() const
+{
+ return m_backgroundImage;
+}
+
void FormEditorGraphicsView::setZoomFactor(double zoom)
{
resetTransform();
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.h b/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.h
index 28a49b0046..60e02582cd 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.h
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.h
@@ -28,6 +28,9 @@ public:
void setZoomFactor(double zoom);
void frame(const QRectF &bbox);
+ void setBackgoundImage(const QImage &image);
+ QImage backgroundImage() const;
+
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
@@ -45,6 +48,7 @@ private:
Panning m_isPanning = Panning::NotStarted;
QPoint m_panningStartPosition;
QRectF m_rootItemRect;
+ QImage m_backgroundImage;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp
index 5661e4ff79..6b580a7d5f 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp
@@ -63,6 +63,8 @@ void FormEditorView::modelAttached(Model *model)
if (!isEnabled())
return;
+ m_formEditorWidget->setBackgoundImage({});
+
temporaryBlockView();
setupFormEditorWidget();
@@ -649,6 +651,10 @@ void FormEditorView::auxiliaryDataChanged(const ModelNode &node,
if (FormEditorItem *editorItem = scene()->itemForQmlItemNode(item))
editorItem->setFrameColor(data.value<QColor>());
}
+
+ if (key == contextImageProperty) {
+ m_formEditorWidget->setBackgoundImage(data.value<QImage>());
+ }
}
static void updateTransitions(FormEditorScene *scene, const QmlItemNode &qmlItemNode)
@@ -784,6 +790,11 @@ void FormEditorView::exportAsImage()
m_formEditorWidget->exportAsImage(m_scene->rootFormEditorItem()->boundingRect());
}
+QImage FormEditorView::takeFormEditorScreenshot()
+{
+ return m_formEditorWidget->takeFormEditorScreenshot();
+}
+
QPicture FormEditorView::renderToPicture() const
{
return m_formEditorWidget->renderToPicture();
@@ -954,6 +965,11 @@ void FormEditorView::setupRootItemSize()
formEditorWidget()->setRootItemRect(rootQmlNode.instanceBoundingRect());
formEditorWidget()->centerScene();
+
+ auto contextImage = rootModelNode().auxiliaryData(contextImageProperty);
+
+ if (contextImage)
+ m_formEditorWidget->setBackgoundImage(contextImage.value().value<QImage>());
}
}
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.h b/src/plugins/qmldesigner/components/formeditor/formeditorview.h
index f97959acb3..1a9f15d016 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorview.h
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.h
@@ -117,6 +117,7 @@ public:
void setGotoErrorCallback(std::function<void(int, int)> gotoErrorCallback);
void exportAsImage();
+ QImage takeFormEditorScreenshot();
QPicture renderToPicture() const;
void setupFormEditorWidget();
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
index bfc03d2b23..ef7ed1d52d 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "formeditorwidget.h"
+#include "backgroundaction.h"
#include "designeractionmanager.h"
#include "designericons.h"
#include "designersettings.h"
@@ -332,11 +333,13 @@ void FormEditorWidget::changeBackgound(const QColor &color)
if (color.alpha() == 0) {
m_graphicsView->activateCheckboardBackground();
if (m_formEditorView->rootModelNode().hasAuxiliaryData(formeditorColorProperty)) {
- m_formEditorView->rootModelNode().setAuxiliaryData(formeditorColorProperty, {});
+ m_formEditorView->rootModelNode().setAuxiliaryDataWithoutLock(formeditorColorProperty,
+ {});
}
} else {
m_graphicsView->activateColoredBackground(color);
- m_formEditorView->rootModelNode().setAuxiliaryData(formeditorColorProperty, color);
+ m_formEditorView->rootModelNode().setAuxiliaryDataWithoutLock(formeditorColorProperty,
+ color);
}
}
@@ -397,6 +400,10 @@ void FormEditorWidget::updateActions()
} else {
m_backgroundAction->setColor(Qt::transparent);
}
+
+ if (m_formEditorView->rootModelNode().hasAuxiliaryData(contextImageProperty))
+ m_backgroundAction->setColor(BackgroundAction::ContextImage);
+
} else {
m_rootWidthAction->clearLineEditText();
m_rootHeightAction->clearLineEditText();
@@ -540,6 +547,40 @@ void FormEditorWidget::exportAsImage(const QRectF &boundingRect)
}
}
+QImage FormEditorWidget::takeFormEditorScreenshot()
+{
+ const QRectF boundingRect = m_formEditorView->scene()->rootFormEditorItem()->boundingRect();
+
+ m_formEditorView->scene()->manipulatorLayerItem()->setVisible(false);
+ QImage image(boundingRect.size().toSize(), QImage::Format_ARGB32);
+
+ if (!m_graphicsView->backgroundImage().isNull()) {
+ image = m_graphicsView->backgroundImage();
+ const QPoint offset = m_graphicsView->backgroundImage().offset();
+
+ QPainter painter(&image);
+ QTransform viewportTransform = m_graphicsView->viewportTransform();
+
+ m_graphicsView->render(&painter,
+ QRectF(-offset, boundingRect.size()),
+ viewportTransform.mapRect(boundingRect).toRect());
+
+ image.setOffset(offset);
+
+ } else {
+ QPainter painter(&image);
+ QTransform viewportTransform = m_graphicsView->viewportTransform();
+
+ m_graphicsView->render(&painter,
+ QRectF(0, 0, image.width(), image.height()),
+ viewportTransform.mapRect(boundingRect).toRect());
+ }
+
+ m_formEditorView->scene()->manipulatorLayerItem()->setVisible(true);
+
+ return image;
+}
+
QPicture FormEditorWidget::renderToPicture() const
{
QPicture picture;
@@ -568,6 +609,17 @@ bool FormEditorWidget::errorMessageBoxIsVisible() const
return m_documentErrorWidget && m_documentErrorWidget->isVisible();
}
+void FormEditorWidget::setBackgoundImage(const QImage &image)
+{
+ m_graphicsView->setBackgoundImage(image);
+ updateActions();
+}
+
+QImage FormEditorWidget::backgroundImage() const
+{
+ return m_graphicsView->backgroundImage();
+}
+
DocumentWarningWidget *FormEditorWidget::errorWidget()
{
if (m_documentErrorWidget.isNull()) {
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h
index 5e4e29d155..8135ce8139 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h
@@ -63,12 +63,17 @@ public:
void showWarningMessageBox(const QList<DocumentMessage> &warnings);
void exportAsImage(const QRectF &boundingRect);
+
+ QImage takeFormEditorScreenshot();
QPicture renderToPicture() const;
FormEditorGraphicsView *graphicsView() const;
bool errorMessageBoxIsVisible() const;
+ void setBackgoundImage(const QImage &image);
+ QImage backgroundImage() const;
+
protected:
QActionGroup *toolActionGroup() const;
DocumentWarningWidget *errorWidget();
diff --git a/src/plugins/qmldesigner/designercore/include/auxiliarydataproperties.h b/src/plugins/qmldesigner/designercore/include/auxiliarydataproperties.h
index 4c12af14fe..b93626a331 100644
--- a/src/plugins/qmldesigner/designercore/include/auxiliarydataproperties.h
+++ b/src/plugins/qmldesigner/designercore/include/auxiliarydataproperties.h
@@ -108,6 +108,8 @@ inline constexpr AuxiliaryDataKeyView rotBlockProperty{AuxiliaryDataType::NodeIn
inline constexpr AuxiliaryDataKeyView languageProperty{AuxiliaryDataType::Temporary, "language"};
inline constexpr AuxiliaryDataKeyView bakeLightsManualProperty{AuxiliaryDataType::Document,
"bakeLightsManual"};
+inline constexpr AuxiliaryDataKeyView contextImageProperty{AuxiliaryDataType::Temporary,
+ "contextImage"};
// Most material preview aux properties are duplicated as document and instance types, as they
// are both required to be persistent and used at runtime to control material preview rendering
diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/designercore/include/modelnode.h
index 657093b0ac..5740449e45 100644
--- a/src/plugins/qmldesigner/designercore/include/modelnode.h
+++ b/src/plugins/qmldesigner/designercore/include/modelnode.h
@@ -182,6 +182,7 @@ public:
QVariant auxiliaryDataWithDefault(AuxiliaryDataKeyView key) const;
QVariant auxiliaryDataWithDefault(AuxiliaryDataKeyDefaultValue key) const;
void setAuxiliaryData(AuxiliaryDataKeyView key, const QVariant &data) const;
+ void setAuxiliaryDataWithoutLock(AuxiliaryDataKeyView key, const QVariant &data) const;
void setAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name, const QVariant &data) const;
void setAuxiliaryDataWithoutLock(AuxiliaryDataType type,
Utils::SmallStringView name,
diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp
index 12a8c09183..e05a895062 100644
--- a/src/plugins/qmldesigner/designercore/model/model.cpp
+++ b/src/plugins/qmldesigner/designercore/model/model.cpp
@@ -1473,6 +1473,7 @@ WriteLocker::WriteLocker(ModelPrivate *model)
if (m_model->m_writeLock)
qWarning() << "QmlDesigner: Misbehaving view calls back to model!!!";
// FIXME: Enable it again
+ QTC_CHECK(!m_model->m_writeLock);
Q_ASSERT(!m_model->m_writeLock);
model->m_writeLock = true;
}
@@ -1484,6 +1485,7 @@ WriteLocker::WriteLocker(Model *model)
if (m_model->m_writeLock)
qWarning() << "QmlDesigner: Misbehaving view calls back to model!!!";
// FIXME: Enable it again
+ QTC_CHECK(!m_model->m_writeLock);
Q_ASSERT(!m_model->m_writeLock);
m_model->m_writeLock = true;
}
@@ -1493,6 +1495,7 @@ WriteLocker::~WriteLocker()
if (!m_model->m_writeLock)
qWarning() << "QmlDesigner: WriterLocker out of sync!!!";
// FIXME: Enable it again
+ QTC_CHECK(m_model->m_writeLock);
Q_ASSERT(m_model->m_writeLock);
m_model->m_writeLock = false;
}
diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp
index 45c076022d..78f2b14e98 100644
--- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp
+++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp
@@ -1002,6 +1002,12 @@ void ModelNode::setAuxiliaryData(AuxiliaryDataKeyView key, const QVariant &data)
}
}
+void ModelNode::setAuxiliaryDataWithoutLock(AuxiliaryDataKeyView key, const QVariant &data) const
+{
+ if (isValid())
+ m_model->d->setAuxiliaryData(internalNode(), key, data);
+}
+
void ModelNode::setAuxiliaryDataWithoutLock(AuxiliaryDataType type,
Utils::SmallStringView name,
const QVariant &data) const
diff --git a/src/plugins/qmldesigner/documentmanager.cpp b/src/plugins/qmldesigner/documentmanager.cpp
index e3460622e7..5ec3c5b336 100644
--- a/src/plugins/qmldesigner/documentmanager.cpp
+++ b/src/plugins/qmldesigner/documentmanager.cpp
@@ -265,6 +265,9 @@ void DocumentManager::resetPossibleImports()
bool DocumentManager::goIntoComponent(const ModelNode &modelNode)
{
+ QImage image = QmlDesignerPlugin::instance()->viewManager().takeFormEditorScreenshot();
+ const QPoint offset = image.offset();
+ image.setOffset(offset - QmlItemNode(modelNode).instancePosition().toPoint());
if (modelNode.isValid() && modelNode.isComponent() && designDocument()) {
QmlDesignerPlugin::instance()->viewManager().setComponentNode(modelNode);
QHash<PropertyName, QVariant> oldProperties = getProperties(modelNode);
@@ -282,6 +285,8 @@ bool DocumentManager::goIntoComponent(const ModelNode &modelNode)
ModelNode rootModelNode = designDocument()->rewriterView()->rootModelNode();
applyProperties(rootModelNode, oldProperties);
+ rootModelNode.setAuxiliaryData(AuxiliaryDataType::Temporary, "contextImage", image);
+
return true;
}