Commit 8fdcaa5c authored by Marco Bubke's avatar Marco Bubke
Browse files

QmlDesigner.NodeInstances: Render in QPixmap

Fixes many graphics glitches, improve render speed.

Reviewed-By: Thomas Hartmann
parent faad3fce
...@@ -270,13 +270,10 @@ void FormEditorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, ...@@ -270,13 +270,10 @@ void FormEditorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
return; return;
painter->save(); painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
if (isContentVisible()) if (isContentVisible())
qmlItemNode().paintInstance(painter); qmlItemNode().paintInstance(painter);
painter->setRenderHint(QPainter::Antialiasing, false);
if (!qmlItemNode().isRootModelNode()) if (!qmlItemNode().isRootModelNode())
paintBoundingRect(painter); paintBoundingRect(painter);
......
...@@ -84,7 +84,7 @@ public: ...@@ -84,7 +84,7 @@ public:
NodeInstance(const NodeInstance &other); NodeInstance(const NodeInstance &other);
NodeInstance& operator=(const NodeInstance &other); NodeInstance& operator=(const NodeInstance &other);
void paint(QPainter *painter) const; void paint(QPainter *painter);
NodeInstance parent() const; NodeInstance parent() const;
bool hasParent() const; bool hasParent() const;
...@@ -127,6 +127,7 @@ public: ...@@ -127,6 +127,7 @@ public:
bool isValid() const; bool isValid() const;
void makeInvalid(); void makeInvalid();
void renderPixmapNextPaint();
bool hasContent() const; bool hasContent() const;
bool isResizable() const; bool isResizable() const;
bool isMovable() const; bool isMovable() const;
......
...@@ -80,7 +80,7 @@ public: ...@@ -80,7 +80,7 @@ public:
int instancePenWidth() const; int instancePenWidth() const;
void paintInstance(QPainter *painter) const; void paintInstance(QPainter *painter);
void selectNode(); void selectNode();
void deselectNode(); void deselectNode();
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include "private/qgraphicsitem_p.h" #include "private/qgraphicsitem_p.h"
#include <QStyleOptionGraphicsItem> #include <QStyleOptionGraphicsItem>
#include "nodemetainfo.h" #include "nodemetainfo.h"
#include <QPixmap>
#include <QSizeF>
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal { namespace Internal {
...@@ -41,7 +43,8 @@ namespace Internal { ...@@ -41,7 +43,8 @@ namespace Internal {
GraphicsObjectNodeInstance::GraphicsObjectNodeInstance(QGraphicsObject *graphicsObject, bool hasContent) GraphicsObjectNodeInstance::GraphicsObjectNodeInstance(QGraphicsObject *graphicsObject, bool hasContent)
: ObjectNodeInstance(graphicsObject), : ObjectNodeInstance(graphicsObject),
m_hasContent(hasContent), m_hasContent(hasContent),
m_isMovable(true) m_isMovable(true),
m_renderPixmapIsDirty(true)
{ {
} }
...@@ -171,6 +174,34 @@ void initOption(QGraphicsItem *item, QStyleOptionGraphicsItem *option, const QTr ...@@ -171,6 +174,34 @@ void initOption(QGraphicsItem *item, QStyleOptionGraphicsItem *option, const QTr
privateItem->initStyleOption(option, transform, QRegion()); 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 void GraphicsObjectNodeInstance::paintRecursively(QGraphicsItem *graphicsItem, QPainter *painter) const
{ {
QGraphicsObject *graphicsObject = graphicsItem->toGraphicsObject(); QGraphicsObject *graphicsObject = graphicsItem->toGraphicsObject();
...@@ -193,21 +224,13 @@ void GraphicsObjectNodeInstance::paintRecursively(QGraphicsItem *graphicsItem, Q ...@@ -193,21 +224,13 @@ void GraphicsObjectNodeInstance::paintRecursively(QGraphicsItem *graphicsItem, Q
} }
} }
void GraphicsObjectNodeInstance::paint(QPainter *painter) const void GraphicsObjectNodeInstance::paint(QPainter *painter)
{ {
if (graphicsObject()) { if (graphicsObject()) {
painter->save(); if (m_renderPixmapIsDirty)
if (hasContent()) { renderPixmap();
QStyleOptionGraphicsItem option; if (!m_renderPixmap.isNull())
initOption(graphicsObject(), &option, painter->transform()); painter->drawPixmap(graphicsObject()->boundingRect().topLeft(), m_renderPixmap);
graphicsObject()->paint(painter, &option);
}
foreach(QGraphicsItem *graphicsItem, graphicsObject()->childItems())
paintRecursively(graphicsItem, painter);
painter->restore();
} }
} }
...@@ -241,5 +264,11 @@ void GraphicsObjectNodeInstance::setMovable(bool movable) ...@@ -241,5 +264,11 @@ void GraphicsObjectNodeInstance::setMovable(bool movable)
m_isMovable = movable; m_isMovable = movable;
} }
void GraphicsObjectNodeInstance::renderPixmapNextPaint()
{
if (graphicsObject() && QGraphicsItemPrivate::get(graphicsObject())->dirty /*|| QGraphicsItemPrivate::get(graphicsObject())->dirtyChildren*/)
m_renderPixmapIsDirty = true;
}
} // namespace Internal } // namespace Internal
} // namespace QmlDesigner } // namespace QmlDesigner
...@@ -44,7 +44,7 @@ class GraphicsObjectNodeInstance : public ObjectNodeInstance ...@@ -44,7 +44,7 @@ class GraphicsObjectNodeInstance : public ObjectNodeInstance
public: public:
GraphicsObjectNodeInstance(QGraphicsObject *graphicsObject, bool hasContent); GraphicsObjectNodeInstance(QGraphicsObject *graphicsObject, bool hasContent);
void paint(QPainter *painter) const; void paint(QPainter *painter);
bool isTopLevel() const; bool isTopLevel() const;
bool isGraphicsObject() const; bool isGraphicsObject() const;
...@@ -77,13 +77,18 @@ public: ...@@ -77,13 +77,18 @@ public:
bool isMovable() const; bool isMovable() const;
void setMovable(bool movable); void setMovable(bool movable);
void renderPixmapNextPaint();
protected: protected:
void renderPixmap();
QGraphicsObject *graphicsObject() const; QGraphicsObject *graphicsObject() const;
void paintRecursively(QGraphicsItem *graphicsItem, QPainter *painter) const; void paintRecursively(QGraphicsItem *graphicsItem, QPainter *painter) const;
static QPair<QGraphicsObject*, bool> createGraphicsObject(const NodeMetaInfo &metaInfo, QDeclarativeContext *context); static QPair<QGraphicsObject*, bool> createGraphicsObject(const NodeMetaInfo &metaInfo, QDeclarativeContext *context);
private: // variables private: // variables
bool m_hasContent; bool m_hasContent;
bool m_isMovable; bool m_isMovable;
QPixmap m_renderPixmap;
bool m_renderPixmapIsDirty;
}; };
} // namespace Internal } // namespace Internal
......
...@@ -115,7 +115,7 @@ NodeInstance &NodeInstance::operator=(const NodeInstance &other) ...@@ -115,7 +115,7 @@ NodeInstance &NodeInstance::operator=(const NodeInstance &other)
\brief Paints the NodeInstance with this painter. \brief Paints the NodeInstance with this painter.
\param painter used QPainter \param painter used QPainter
*/ */
void NodeInstance::paint(QPainter *painter) const void NodeInstance::paint(QPainter *painter)
{ {
m_nodeInstance->paint(painter); m_nodeInstance->paint(painter);
} }
...@@ -461,6 +461,11 @@ void NodeInstance::makeInvalid() ...@@ -461,6 +461,11 @@ void NodeInstance::makeInvalid()
m_nodeInstance.clear(); m_nodeInstance.clear();
} }
void NodeInstance::renderPixmapNextPaint()
{
m_nodeInstance->renderPixmapNextPaint();
}
bool NodeInstance::hasContent() const bool NodeInstance::hasContent() const
{ {
return m_nodeInstance->hasContent(); return m_nodeInstance->hasContent();
......
...@@ -26,10 +26,10 @@ void NodeInstanceSignalSpy::setObjectNodeInstance(const ObjectNodeInstance::Poin ...@@ -26,10 +26,10 @@ void NodeInstanceSignalSpy::setObjectNodeInstance(const ObjectNodeInstance::Poin
void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const QString &prefix) void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const QString &prefix)
{ {
if (registeredObjectList.contains(spiedObject)) // prevent cycles if (m_registeredObjectList.contains(spiedObject)) // prevent cycles
return; return;
registeredObjectList.append(spiedObject); m_registeredObjectList.append(spiedObject);
for (int index = QObject::staticMetaObject.propertyOffset(); for (int index = QObject::staticMetaObject.propertyOffset();
index < spiedObject->metaObject()->propertyCount(); index < spiedObject->metaObject()->propertyCount();
index++) { index++) {
......
...@@ -27,8 +27,9 @@ protected: ...@@ -27,8 +27,9 @@ protected:
private: private:
int methodeOffset; int methodeOffset;
QHash<int, QString> m_indexPropertyHash; QHash<int, QString> m_indexPropertyHash;
QObjectList registeredObjectList; QObjectList m_registeredObjectList;
ObjectNodeInstanceWeakPointer m_objectNodeInstance; ObjectNodeInstanceWeakPointer m_objectNodeInstance;
QMetaObject m_metaObject;
}; };
} // namespace Internal } // namespace Internal
......
...@@ -578,9 +578,14 @@ void NodeInstanceView::notifyPropertyChange(const ModelNode &node, const QString ...@@ -578,9 +578,14 @@ void NodeInstanceView::notifyPropertyChange(const ModelNode &node, const QString
{ {
if (m_blockStatePropertyChanges) if (m_blockStatePropertyChanges)
return; return;
if (!node.isValid()) if (!node.isValid())
return; return;
if (hasInstanceForNode(node))
instanceForNode(node).renderPixmapNextPaint();
emitInstancePropertyChange(QList<QPair<ModelNode, QString> >() << qMakePair(node, propertyName)); emitInstancePropertyChange(QList<QPair<ModelNode, QString> >() << qMakePair(node, propertyName));
} }
......
...@@ -911,7 +911,7 @@ QVariant ObjectNodeInstance::resetValue(const QString &propertyName) const ...@@ -911,7 +911,7 @@ QVariant ObjectNodeInstance::resetValue(const QString &propertyName) const
return m_resetValueHash.value(propertyName); return m_resetValueHash.value(propertyName);
} }
void ObjectNodeInstance::paint(QPainter * /*painter*/) const void ObjectNodeInstance::paint(QPainter * /*painter*/)
{ {
} }
...@@ -1025,6 +1025,10 @@ void ObjectNodeInstance::doComponentComplete() ...@@ -1025,6 +1025,10 @@ void ObjectNodeInstance::doComponentComplete()
} }
void ObjectNodeInstance::renderPixmapNextPaint()
{
}
} }
} }
...@@ -97,7 +97,7 @@ public: ...@@ -97,7 +97,7 @@ public:
NodeInstanceView *nodeInstanceView() const; NodeInstanceView *nodeInstanceView() const;
void setNodeInstanceView(NodeInstanceView *view); void setNodeInstanceView(NodeInstanceView *view);
virtual void initializePropertyWatcher(const Pointer &objectNodeInstance); virtual void initializePropertyWatcher(const Pointer &objectNodeInstance);
virtual void paint(QPainter *painter) const; virtual void paint(QPainter *painter);
virtual bool isTopLevel() const; virtual bool isTopLevel() const;
...@@ -188,6 +188,8 @@ public: ...@@ -188,6 +188,8 @@ public:
virtual void doComponentComplete(); virtual void doComponentComplete();
virtual void renderPixmapNextPaint();
protected: protected:
static QObject *createInstance(const NodeMetaInfo &metaInfo, QDeclarativeContext *parentContext); static QObject *createInstance(const NodeMetaInfo &metaInfo, QDeclarativeContext *parentContext);
......
...@@ -246,7 +246,7 @@ int QmlItemNode::instancePenWidth() const ...@@ -246,7 +246,7 @@ int QmlItemNode::instancePenWidth() const
return nodeInstance().penWidth(); return nodeInstance().penWidth();
} }
void QmlItemNode::paintInstance(QPainter *painter) const void QmlItemNode::paintInstance(QPainter *painter)
{ {
if (nodeInstance().isValid()) if (nodeInstance().isValid())
nodeInstance().paint(painter); nodeInstance().paint(painter);
......
...@@ -327,7 +327,8 @@ static bool isTransformProperty(const QString &name) ...@@ -327,7 +327,8 @@ static bool isTransformProperty(const QString &name)
<< "scale" << "scale"
<< "transformOrigin" << "transformOrigin"
<< "paintedWidth" << "paintedWidth"
<< "paintedHeight"); << "paintedHeight"
<< "border.width");
return transformProperties.contains(name); return transformProperties.contains(name);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment