QQuickTextEdit: move QSG* members from dptr to root node.
authorPierre Rossi <pierre.rossi@digia.com>
Mon, 1 Jul 2013 16:33:19 +0000 (18:33 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Wed, 3 Jul 2013 13:55:03 +0000 (15:55 +0200)
Subclass QSGTransform node for our use case and add the frame decorations
and cursor nodes in there.

Task-number: QTBUG-31580
Change-Id: Id2b468b53092f21134ae45e5694bc54c43660f8b
Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
src/quick/items/qquicktextedit.cpp
src/quick/items/qquicktextedit_p_p.h

index 327b086..05da7ab 100644 (file)
@@ -135,6 +135,37 @@ namespace {
             return format(pos);
         }
     };
+
+    class RootNode : public QSGTransformNode
+    {
+    public:
+        RootNode() : cursorNode(0), frameDecorationsNode(0)
+        { }
+
+        void resetFrameDecorations(QQuickTextNode* newNode)
+        {
+            if (frameDecorationsNode) {
+                removeChildNode(frameDecorationsNode);
+                delete frameDecorationsNode;
+            }
+            frameDecorationsNode = newNode;
+            newNode->setFlag(QSGNode::OwnedByParent);
+        }
+
+        void resetCursorNode(QSGSimpleRectNode* newNode)
+        {
+            if (cursorNode)
+                removeChildNode(cursorNode);
+            delete cursorNode;
+            cursorNode = newNode;
+            appendChildNode(cursorNode);
+            cursorNode->setFlag(QSGNode::OwnedByParent);
+        }
+
+        QSGSimpleRectNode *cursorNode;
+        QQuickTextNode* frameDecorationsNode;
+
+    };
 }
 
 QQuickTextEdit::QQuickTextEdit(QQuickItem *parent)
@@ -1731,7 +1762,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
 
     d->updateType = QQuickTextEditPrivate::UpdateNone;
 
-    QSGTransformNode *rootNode = static_cast<QSGTransformNode *>(oldNode);
+    RootNode *rootNode = static_cast<RootNode *>(oldNode);
     TextNodeIterator nodeIterator = d->textNodeMap.begin();
     while (nodeIterator != d->textNodeMap.end() && !(*nodeIterator)->dirty())
         ++nodeIterator;
@@ -1740,7 +1771,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
     if (!oldNode || nodeIterator < d->textNodeMap.end()) {
 
         if (!oldNode)
-            rootNode = new QSGTransformNode;
+            rootNode = new RootNode;
 
         int firstDirtyPos = 0;
         if (nodeIterator != d->textNodeMap.end()) {
@@ -1754,11 +1785,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
         }
 
         // FIXME: the text decorations could probably be handled separately (only updated for affected textFrames)
-        if (d->frameDecorationsNode) {
-            rootNode->removeChildNode(d->frameDecorationsNode);
-            delete d->frameDecorationsNode;
-        }
-        d->frameDecorationsNode = d->createTextNode();
+        rootNode->resetFrameDecorations(d->createTextNode());
 
         QQuickTextNode *node = 0;
 
@@ -1774,7 +1801,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
         while (!frames.isEmpty()) {
             QTextFrame *textFrame = frames.takeFirst();
             frames.append(textFrame->childFrames());
-            d->frameDecorationsNode->m_engine->addFrameDecorations(d->document, textFrame);
+            rootNode->frameDecorationsNode->m_engine->addFrameDecorations(d->document, textFrame);
 
 
             if (textFrame->lastPosition() < firstDirtyPos || (firstCleanNode && textFrame->firstPosition() >= firstCleanNode->startPos()))
@@ -1837,9 +1864,9 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
             }
             d->addCurrentTextNodeToRoot(rootNode, node, nodeIterator, nodeStart);
         }
-        d->frameDecorationsNode->m_engine->addToSceneGraph(d->frameDecorationsNode, QQuickText::Normal, QColor());
+        rootNode->frameDecorationsNode->m_engine->addToSceneGraph(rootNode->frameDecorationsNode, QQuickText::Normal, QColor());
         // Now prepend the frame decorations since we want them rendered first, with the text nodes and cursor in front.
-        rootNode->prependChildNode(d->frameDecorationsNode);
+        rootNode->prependChildNode(rootNode->frameDecorationsNode);
 
         Q_ASSERT(nodeIterator == d->textNodeMap.end() || (*nodeIterator) == firstCleanNode);
         // Update the position of the subsequent text blocks.
@@ -1865,11 +1892,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
         QColor color = (!d->cursorVisible || !d->control->cursorOn())
                 ? QColor(0, 0, 0, 0)
                 : d->color;
-        if (d->cursorNode)
-            rootNode->removeChildNode(d->cursorNode);
-        delete d->cursorNode;
-        d->cursorNode = new QSGSimpleRectNode(cursorRectangle(), color);
-        rootNode->appendChildNode(d->cursorNode);
+        rootNode->resetCursorNode(new QSGSimpleRectNode(cursorRectangle(), color));
     }
 
     return rootNode;
index 4f0ab93..11a0364 100644 (file)
@@ -93,8 +93,7 @@ public:
     QQuickTextEditPrivate()
         : color(QRgb(0xFF000000)), selectionColor(QRgb(0xFF000080)), selectedTextColor(QRgb(0xFFFFFFFF))
         , textMargin(0.0), xoff(0), yoff(0), font(sourceFont), cursorComponent(0), cursorItem(0), document(0), control(0)
-        , quickDocument(0), frameDecorationsNode(0), cursorNode(0)
-        , lastSelectionStart(0), lastSelectionEnd(0), lineCount(0)
+        , quickDocument(0), lastSelectionStart(0), lastSelectionEnd(0), lineCount(0)
         , hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop)
         , format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap)
         , renderType(QQuickTextEdit::QtRendering)
@@ -155,8 +154,6 @@ public:
     QQuickTextControl *control;
     QQuickTextDocument *quickDocument;
     QList<Node*> textNodeMap;
-    QQuickTextNode *frameDecorationsNode;
-    QSGSimpleRectNode *cursorNode;
 
     int lastSelectionStart;
     int lastSelectionEnd;