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

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 *,
return;
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
if (isContentVisible())
qmlItemNode().paintInstance(painter);
painter->setRenderHint(QPainter::Antialiasing, false);
if (!qmlItemNode().isRootModelNode())
paintBoundingRect(painter);
......
......@@ -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;
......
......@@ -80,7 +80,7 @@ public:
int instancePenWidth() const;
void paintInstance(QPainter *painter) const;
void paintInstance(QPainter *painter);
void selectNode();
void deselectNode();
......
......@@ -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
......@@ -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
......
......@@ -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();
......
......@@ -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++) {
......
......@@ -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
......
......@@ -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));
}
......
......@@ -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()
{
}
}
}
......@@ -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);
......
......@@ -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);
......
......@@ -327,7 +327,8 @@ static bool isTransformProperty(const QString &name)
<< "scale"
<< "transformOrigin"
<< "paintedWidth"
<< "paintedHeight");
<< "paintedHeight"
<< "border.width");
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