From 8fdcaa5cdf2e290b16b4bfa40c27d8efd9332168 Mon Sep 17 00:00:00 2001 From: Marco Bubke <marco.bubke@nokia.com> Date: Tue, 5 Oct 2010 20:55:31 +0200 Subject: [PATCH] QmlDesigner.NodeInstances: Render in QPixmap Fixes many graphics glitches, improve render speed. Reviewed-By: Thomas Hartmann --- .../components/formeditor/formeditoritem.cpp | 3 - .../designercore/include/nodeinstance.h | 3 +- .../designercore/include/qmlitemnode.h | 2 +- .../instances/graphicsobjectnodeinstance.cpp | 57 ++++++++++++++----- .../instances/graphicsobjectnodeinstance.h | 7 ++- .../designercore/instances/nodeinstance.cpp | 7 ++- .../instances/nodeinstancesignalspy.cpp | 4 +- .../instances/nodeinstancesignalspy.h | 3 +- .../instances/nodeinstanceview.cpp | 5 ++ .../instances/objectnodeinstance.cpp | 6 +- .../instances/objectnodeinstance.h | 4 +- .../designercore/model/qmlitemnode.cpp | 2 +- .../designercore/model/qmlmodelview.cpp | 3 +- 13 files changed, 78 insertions(+), 28 deletions(-) diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp index be4a479ef88..c6717ab5346 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp @@ -270,13 +270,10 @@ void FormEditorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, return; painter->save(); - painter->setRenderHint(QPainter::Antialiasing, true); if (isContentVisible()) qmlItemNode().paintInstance(painter); - painter->setRenderHint(QPainter::Antialiasing, false); - if (!qmlItemNode().isRootModelNode()) paintBoundingRect(painter); diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstance.h b/src/plugins/qmldesigner/designercore/include/nodeinstance.h index 0b5a223d38d..bdf7ec5410d 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstance.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstance.h @@ -84,7 +84,7 @@ public: NodeInstance(const NodeInstance &other); NodeInstance& operator=(const NodeInstance &other); - void paint(QPainter *painter) const; + void paint(QPainter *painter); NodeInstance parent() const; bool hasParent() const; @@ -127,6 +127,7 @@ public: bool isValid() const; void makeInvalid(); + void renderPixmapNextPaint(); bool hasContent() const; bool isResizable() const; bool isMovable() const; diff --git a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h index 5500f5eeb05..91fdc853b88 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h @@ -80,7 +80,7 @@ public: int instancePenWidth() const; - void paintInstance(QPainter *painter) const; + void paintInstance(QPainter *painter); void selectNode(); void deselectNode(); diff --git a/src/plugins/qmldesigner/designercore/instances/graphicsobjectnodeinstance.cpp b/src/plugins/qmldesigner/designercore/instances/graphicsobjectnodeinstance.cpp index 83232f53f28..5f1f61e7534 100644 --- a/src/plugins/qmldesigner/designercore/instances/graphicsobjectnodeinstance.cpp +++ b/src/plugins/qmldesigner/designercore/instances/graphicsobjectnodeinstance.cpp @@ -34,6 +34,8 @@ #include "private/qgraphicsitem_p.h" #include <QStyleOptionGraphicsItem> #include "nodemetainfo.h" +#include <QPixmap> +#include <QSizeF> namespace QmlDesigner { namespace Internal { @@ -41,7 +43,8 @@ namespace Internal { GraphicsObjectNodeInstance::GraphicsObjectNodeInstance(QGraphicsObject *graphicsObject, bool hasContent) : ObjectNodeInstance(graphicsObject), m_hasContent(hasContent), - m_isMovable(true) + m_isMovable(true), + m_renderPixmapIsDirty(true) { } @@ -171,6 +174,34 @@ void initOption(QGraphicsItem *item, QStyleOptionGraphicsItem *option, const QTr privateItem->initStyleOption(option, transform, QRegion()); } +void GraphicsObjectNodeInstance::renderPixmap() +{ + QRectF boundingRect = graphicsObject()->boundingRect(); + QSize boundingSize = boundingRect.size().toSize(); + + if (m_renderPixmap.size() != boundingSize) { + m_renderPixmap = QPixmap(boundingSize); + } + + if (m_renderPixmap.isNull()) + return; + + m_renderPixmap.fill(Qt::transparent); + + QPainter painter(&m_renderPixmap); + painter.translate(-boundingRect.topLeft()); + + if (hasContent()) { + QStyleOptionGraphicsItem option; + initOption(graphicsObject(), &option, painter.transform()); + graphicsObject()->paint(&painter, &option); + + } + + foreach(QGraphicsItem *graphicsItem, graphicsObject()->childItems()) + paintRecursively(graphicsItem, &painter); +} + void GraphicsObjectNodeInstance::paintRecursively(QGraphicsItem *graphicsItem, QPainter *painter) const { QGraphicsObject *graphicsObject = graphicsItem->toGraphicsObject(); @@ -193,21 +224,13 @@ void GraphicsObjectNodeInstance::paintRecursively(QGraphicsItem *graphicsItem, Q } } -void GraphicsObjectNodeInstance::paint(QPainter *painter) const +void GraphicsObjectNodeInstance::paint(QPainter *painter) { if (graphicsObject()) { - painter->save(); - if (hasContent()) { - QStyleOptionGraphicsItem option; - initOption(graphicsObject(), &option, painter->transform()); - graphicsObject()->paint(painter, &option); - - } - - foreach(QGraphicsItem *graphicsItem, graphicsObject()->childItems()) - paintRecursively(graphicsItem, painter); - - painter->restore(); + if (m_renderPixmapIsDirty) + renderPixmap(); + if (!m_renderPixmap.isNull()) + painter->drawPixmap(graphicsObject()->boundingRect().topLeft(), m_renderPixmap); } } @@ -241,5 +264,11 @@ void GraphicsObjectNodeInstance::setMovable(bool movable) m_isMovable = movable; } +void GraphicsObjectNodeInstance::renderPixmapNextPaint() +{ + if (graphicsObject() && QGraphicsItemPrivate::get(graphicsObject())->dirty /*|| QGraphicsItemPrivate::get(graphicsObject())->dirtyChildren*/) + m_renderPixmapIsDirty = true; +} + } // namespace Internal } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/instances/graphicsobjectnodeinstance.h b/src/plugins/qmldesigner/designercore/instances/graphicsobjectnodeinstance.h index 45200acd273..3aec7833d78 100644 --- a/src/plugins/qmldesigner/designercore/instances/graphicsobjectnodeinstance.h +++ b/src/plugins/qmldesigner/designercore/instances/graphicsobjectnodeinstance.h @@ -44,7 +44,7 @@ class GraphicsObjectNodeInstance : public ObjectNodeInstance public: GraphicsObjectNodeInstance(QGraphicsObject *graphicsObject, bool hasContent); - void paint(QPainter *painter) const; + void paint(QPainter *painter); bool isTopLevel() const; bool isGraphicsObject() const; @@ -77,13 +77,18 @@ public: bool isMovable() const; void setMovable(bool movable); + void renderPixmapNextPaint(); + protected: + void renderPixmap(); QGraphicsObject *graphicsObject() const; void paintRecursively(QGraphicsItem *graphicsItem, QPainter *painter) const; static QPair<QGraphicsObject*, bool> createGraphicsObject(const NodeMetaInfo &metaInfo, QDeclarativeContext *context); private: // variables bool m_hasContent; bool m_isMovable; + QPixmap m_renderPixmap; + bool m_renderPixmapIsDirty; }; } // namespace Internal diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp index acf2c0fb151..af94af11d6d 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp @@ -115,7 +115,7 @@ NodeInstance &NodeInstance::operator=(const NodeInstance &other) \brief Paints the NodeInstance with this painter. \param painter used QPainter */ -void NodeInstance::paint(QPainter *painter) const +void NodeInstance::paint(QPainter *painter) { m_nodeInstance->paint(painter); } @@ -461,6 +461,11 @@ void NodeInstance::makeInvalid() m_nodeInstance.clear(); } +void NodeInstance::renderPixmapNextPaint() +{ + m_nodeInstance->renderPixmapNextPaint(); +} + bool NodeInstance::hasContent() const { return m_nodeInstance->hasContent(); diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.cpp index 70a10a7544a..376ce9d1aa5 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.cpp @@ -26,10 +26,10 @@ void NodeInstanceSignalSpy::setObjectNodeInstance(const ObjectNodeInstance::Poin void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const QString &prefix) { - if (registeredObjectList.contains(spiedObject)) // prevent cycles + if (m_registeredObjectList.contains(spiedObject)) // prevent cycles return; - registeredObjectList.append(spiedObject); + m_registeredObjectList.append(spiedObject); for (int index = QObject::staticMetaObject.propertyOffset(); index < spiedObject->metaObject()->propertyCount(); index++) { diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.h b/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.h index 94cef6d2321..85cc4d79812 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.h +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.h @@ -27,8 +27,9 @@ protected: private: int methodeOffset; QHash<int, QString> m_indexPropertyHash; - QObjectList registeredObjectList; + QObjectList m_registeredObjectList; ObjectNodeInstanceWeakPointer m_objectNodeInstance; + QMetaObject m_metaObject; }; } // namespace Internal diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 30b5d43acd5..dd0a94983c8 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -578,9 +578,14 @@ void NodeInstanceView::notifyPropertyChange(const ModelNode &node, const QString { if (m_blockStatePropertyChanges) return; + if (!node.isValid()) return; + if (hasInstanceForNode(node)) + instanceForNode(node).renderPixmapNextPaint(); + + emitInstancePropertyChange(QList<QPair<ModelNode, QString> >() << qMakePair(node, propertyName)); } diff --git a/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.cpp b/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.cpp index f543f9de3ea..64230d32336 100644 --- a/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.cpp +++ b/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.cpp @@ -911,7 +911,7 @@ QVariant ObjectNodeInstance::resetValue(const QString &propertyName) const return m_resetValueHash.value(propertyName); } -void ObjectNodeInstance::paint(QPainter * /*painter*/) const +void ObjectNodeInstance::paint(QPainter * /*painter*/) { } @@ -1025,6 +1025,10 @@ void ObjectNodeInstance::doComponentComplete() } +void ObjectNodeInstance::renderPixmapNextPaint() +{ + +} } } diff --git a/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.h b/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.h index 2f7715d1032..aed1bd38a30 100644 --- a/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.h +++ b/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.h @@ -97,7 +97,7 @@ public: NodeInstanceView *nodeInstanceView() const; void setNodeInstanceView(NodeInstanceView *view); virtual void initializePropertyWatcher(const Pointer &objectNodeInstance); - virtual void paint(QPainter *painter) const; + virtual void paint(QPainter *painter); virtual bool isTopLevel() const; @@ -188,6 +188,8 @@ public: virtual void doComponentComplete(); + virtual void renderPixmapNextPaint(); + protected: static QObject *createInstance(const NodeMetaInfo &metaInfo, QDeclarativeContext *parentContext); diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp index 8a6369475ac..bf067bb9389 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp @@ -246,7 +246,7 @@ int QmlItemNode::instancePenWidth() const return nodeInstance().penWidth(); } -void QmlItemNode::paintInstance(QPainter *painter) const +void QmlItemNode::paintInstance(QPainter *painter) { if (nodeInstance().isValid()) nodeInstance().paint(painter); diff --git a/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp b/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp index 646c9455984..4d1246ac459 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp @@ -327,7 +327,8 @@ static bool isTransformProperty(const QString &name) << "scale" << "transformOrigin" << "paintedWidth" - << "paintedHeight"); + << "paintedHeight" + << "border.width"); return transformProperties.contains(name); } -- GitLab