From fb339b21b8a24b835cea7a057c47b7c5ad80dd72 Mon Sep 17 00:00:00 2001
From: Lars Knoll <lars.knoll@digia.com>
Date: Fri, 8 Aug 2014 20:29:19 +0200
Subject: [PATCH] Create rectangle nodes in the text editing through the
 context

Unfortunately we can't re-use the QSGSimpleRectNode, as it doesn't provide us
with virtual methods to move it's creation into the context. But's since it's
only 20 lines of code anyway, this is still a nice cleanup. And it also allows
the re-use of any optimizations in the renderer for QSGRectangleNode.

Change-Id: I957777fbbeb0a994a9c257baf3bfe87fce8cc9e8
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
---
 src/quick/items/qquicktextedit.cpp       |  6 +++---
 src/quick/items/qquicktextedit_p_p.h     |  2 +-
 src/quick/items/qquicktextinput.cpp      | 16 +++++++++++-----
 src/quick/items/qquicktextnode.cpp       | 11 +++++++++--
 src/quick/items/qquicktextnode_p.h       |  7 ++++---
 src/quick/items/qquicktextnodeengine.cpp |  9 ++++-----
 src/quick/scenegraph/qsgcontext.cpp      | 13 +++++++++++++
 src/quick/scenegraph/qsgcontext_p.h      |  1 +
 8 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index fdaef6df8e..6bec2ce646 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -155,7 +155,7 @@ namespace {
             newNode->setFlag(QSGNode::OwnedByParent);
         }
 
-        void resetCursorNode(QSGSimpleRectNode* newNode)
+        void resetCursorNode(QSGRectangleNode* newNode)
         {
             if (cursorNode)
                 removeChildNode(cursorNode);
@@ -165,7 +165,7 @@ namespace {
             cursorNode->setFlag(QSGNode::OwnedByParent);
         }
 
-        QSGSimpleRectNode *cursorNode;
+        QSGRectangleNode *cursorNode;
         QQuickTextNode* frameDecorationsNode;
 
     };
@@ -1914,7 +1914,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
         QColor color = (!d->cursorVisible || !d->control->cursorOn())
                 ? QColor(0, 0, 0, 0)
                 : d->color;
-        rootNode->resetCursorNode(new QSGSimpleRectNode(cursorRectangle(), color));
+        rootNode->resetCursorNode(d->sceneGraphContext()->createRectangleNode(cursorRectangle(), color));
     }
 
     return rootNode;
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index 0cf7ee2850..8623e55a1d 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -65,7 +65,7 @@ class QTextLayout;
 class QQuickTextDocumentWithImageResources;
 class QQuickTextControl;
 class QQuickTextNode;
-class QSGSimpleRectNode;
+
 class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate
 {
 public:
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index f2cf89c1b9..c63e1c87e6 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -1861,7 +1861,7 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
     d->textNode = node;
 
     if (!d->textLayoutDirty && oldNode != 0) {
-        QSGSimpleRectNode *cursorNode = node->cursorNode();
+        QSGRectangleNode *cursorNode = node->cursorNode();
         if (cursorNode != 0 && !isReadOnly()) {
             cursorNode->setRect(cursorRectangle());
 
@@ -2706,14 +2706,20 @@ void QQuickTextInput::selectionChanged()
 
 void QQuickTextInputPrivate::showCursor()
 {
-    if (textNode != 0 && textNode->cursorNode() != 0)
-        textNode->cursorNode()->setColor(color);
+    if (textNode != 0 && textNode->cursorNode() != 0) {
+        QSGRectangleNode *cursor = textNode->cursorNode();
+        cursor->setColor(color);
+        cursor->update();
+    }
 }
 
 void QQuickTextInputPrivate::hideCursor()
 {
-    if (textNode != 0 && textNode->cursorNode() != 0)
-        textNode->cursorNode()->setColor(QColor(0, 0, 0, 0));
+    if (textNode != 0 && textNode->cursorNode() != 0) {
+        QSGRectangleNode *cursor = textNode->cursorNode();
+        cursor->setColor(QColor(0, 0, 0, 0));
+        cursor->update();
+    }
 }
 
 QRectF QQuickTextInput::boundingRect() const
diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp
index 02e321dfba..480e141e30 100644
--- a/src/quick/items/qquicktextnode.cpp
+++ b/src/quick/items/qquicktextnode.cpp
@@ -43,7 +43,6 @@
 
 #include "qquicktextnodeengine_p.h"
 
-#include <QtQuick/qsgsimplerectnode.h>
 #include <private/qsgadaptationlayer_p.h>
 #include <private/qsgdistancefieldglyphnode_p.h>
 #include <private/qquickclipnode_p.h>
@@ -183,7 +182,8 @@ void QQuickTextNode::setCursor(const QRectF &rect, const QColor &color)
     if (m_cursorNode != 0)
         delete m_cursorNode;
 
-    m_cursorNode = new QSGSimpleRectNode(rect, color);
+    QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext();
+    m_cursorNode =  sg->sceneGraphContext()->createRectangleNode(rect, color);
     appendChildNode(m_cursorNode);
 }
 
@@ -198,6 +198,13 @@ void QQuickTextNode::initEngine(const QColor& textColor, const QColor& selectedT
     m_engine->setPosition(position);
 }
 
+void QQuickTextNode::addRectangleNode(const QRectF &rect, const QColor &color)
+{
+    QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext();
+    appendChildNode(sg->sceneGraphContext()->createRectangleNode(rect, color));
+}
+
+
 void QQuickTextNode::addImage(const QRectF &rect, const QImage &image)
 {
     QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext();
diff --git a/src/quick/items/qquicktextnode_p.h b/src/quick/items/qquicktextnode_p.h
index 0bff0d5cff..7099b19c46 100644
--- a/src/quick/items/qquicktextnode_p.h
+++ b/src/quick/items/qquicktextnode_p.h
@@ -59,7 +59,7 @@ class QColor;
 class QTextDocument;
 class QSGContext;
 class QRawFont;
-class QSGSimpleRectNode;
+class QSGRectangleNode;
 class QSGClipNode;
 class QSGTexture;
 
@@ -96,12 +96,13 @@ public:
                          int selectionStart = -1, int selectionEnd = -1);
 
     void setCursor(const QRectF &rect, const QColor &color);
-    QSGSimpleRectNode *cursorNode() const { return m_cursorNode; }
+    QSGRectangleNode *cursorNode() const { return m_cursorNode; }
 
     QSGGlyphNode *addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color,
                             QQuickText::TextStyle style = QQuickText::Normal, const QColor &styleColor = QColor(),
                             QSGNode *parentNode = 0);
     void addImage(const QRectF &rect, const QImage &image);
+    void addRectangleNode(const QRectF &rect, const QColor &color);
 
     bool useNativeRenderer() const { return m_useNativeRenderer; }
     void setUseNativeRenderer(bool on) { m_useNativeRenderer = on; }
@@ -110,7 +111,7 @@ private:
     void initEngine(const QColor &textColor, const QColor &selectedTextColor, const QColor &selectionColor, const QColor& anchorColor = QColor()
             , const QPointF &position = QPointF());
 
-    QSGSimpleRectNode *m_cursorNode;
+    QSGRectangleNode *m_cursorNode;
     QList<QSGTexture *> m_textures;
     QQuickItem *m_ownerElement;
     bool m_useNativeRenderer;
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index e9ff70e00b..d0754d511c 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -49,7 +49,6 @@
 #include <QtGui/qtextobject.h>
 #include <QtGui/qtexttable.h>
 #include <QtGui/qtextlist.h>
-#include <QtQuick/qsgsimplerectnode.h>
 
 #include <private/qquicktext_p_p.h>
 #include <private/qtextdocumentlayout_p.h>
@@ -647,14 +646,14 @@ void  QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode,
         const QRectF &rect = m_backgrounds.at(i).first;
         const QColor &color = m_backgrounds.at(i).second;
 
-        parentNode->appendChildNode(new QSGSimpleRectNode(rect, color));
+        parentNode->addRectangleNode(rect, color);
     }
 
     // First, prepend all selection rectangles to the tree
     for (int i=0; i<m_selectionRects.size(); ++i) {
         const QRectF &rect = m_selectionRects.at(i);
 
-        parentNode->appendChildNode(new QSGSimpleRectNode(rect, m_selectionColor));
+        parentNode->addRectangleNode(rect, m_selectionColor);
     }
 
     // Finally, add decorations for each node to the tree.
@@ -665,7 +664,7 @@ void  QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode,
                 ? m_selectedTextColor
                 : textDecoration.color;
 
-        parentNode->appendChildNode(new QSGSimpleRectNode(textDecoration.rect, color));
+        parentNode->addRectangleNode(textDecoration.rect, color);
     }
 
     // Then, go through all the nodes for all lines and combine all QGlyphRuns with a common
@@ -714,7 +713,7 @@ void  QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode,
             if (node->selectionState == Selected) {
                 QColor color = m_selectionColor;
                 color.setAlpha(128);
-                parentNode->appendChildNode(new QSGSimpleRectNode(node->boundingRect, color));
+                parentNode->addRectangleNode(node->boundingRect, color);
             }
         }
     }
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 4ea0cca553..f69dd7adde 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -261,6 +261,19 @@ void QSGContext::renderContextInvalidated(QSGRenderContext *)
 {
 }
 
+
+/*!
+    Convenience factory function for creating a colored rectangle with the given geometry.
+ */
+QSGRectangleNode *QSGContext::createRectangleNode(const QRectF &rect, const QColor &c)
+{
+    QSGRectangleNode *node = createRectangleNode();
+    node->setRect(rect);
+    node->setColor(c);
+    node->update();
+    return node;
+}
+
 /*!
     Factory function for scene graph backends of the Rectangle element.
  */
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index cd69180c56..abf1abd4c0 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -172,6 +172,7 @@ public:
     virtual void renderContextInvalidated(QSGRenderContext *renderContext);
     virtual QSGRenderContext *createRenderContext();
 
+    QSGRectangleNode *createRectangleNode(const QRectF &rect, const QColor &c);
     virtual QSGRectangleNode *createRectangleNode();
     virtual QSGImageNode *createImageNode();
     virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode);
-- 
GitLab