Maintain z order of shapepaths during update in CurveRenderer
The new nodes for any updated shapepath would be appended to the end of the child list, and hence pop to the front of the z order stack. Instead, maintain the order by inserting the new nodes in the old ones' place in the child list. Fixes: QTBUG-119192 Change-Id: I0fa477158648a901b488b08b9fdef6465c312dd0 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
parent
717a1dd908
commit
70495410a8
|
@ -352,26 +352,49 @@ void QQuickShapeCurveRenderer::updateNode()
|
|||
strokeNode->setColor(pathData.pen.color());
|
||||
};
|
||||
|
||||
for (PathData &pathData : m_paths) {
|
||||
NodeList toBeDeleted;
|
||||
|
||||
for (int i = 0; i < m_paths.size(); i++) {
|
||||
PathData &pathData = m_paths[i];
|
||||
if (pathData.currentRunner) {
|
||||
if (!pathData.currentRunner->isDone)
|
||||
continue;
|
||||
// Find insertion point for new nodes
|
||||
QSGNode *nextNode = nullptr;
|
||||
int j = i;
|
||||
do {
|
||||
const PathData &pd = m_paths[j];
|
||||
if (!pd.fillNodes.isEmpty())
|
||||
nextNode = pd.fillNodes.first();
|
||||
else if (!pathData.strokeNodes.isEmpty())
|
||||
nextNode = pd.strokeNodes.first();
|
||||
} while (!nextNode && ++j < m_paths.size());
|
||||
|
||||
const PathData &newData = pathData.currentRunner->pathData;
|
||||
if (newData.m_dirty & PathDirty)
|
||||
pathData.path = newData.path;
|
||||
if (newData.m_dirty & FillDirty) {
|
||||
pathData.fillPath = newData.fillPath;
|
||||
qDeleteAll(pathData.fillNodes);
|
||||
for (auto *node : std::as_const(newData.fillNodes)) {
|
||||
if (nextNode)
|
||||
m_rootNode->insertChildNodeBefore(node, nextNode);
|
||||
else
|
||||
m_rootNode->appendChildNode(node);
|
||||
}
|
||||
toBeDeleted += pathData.fillNodes;
|
||||
pathData.fillNodes = newData.fillNodes;
|
||||
for (auto *node : std::as_const(pathData.fillNodes))
|
||||
m_rootNode->appendChildNode(node);
|
||||
}
|
||||
if (newData.m_dirty & StrokeDirty) {
|
||||
qDeleteAll(pathData.strokeNodes);
|
||||
for (auto *node : std::as_const(newData.strokeNodes)) {
|
||||
if (nextNode)
|
||||
m_rootNode->insertChildNodeBefore(node, nextNode);
|
||||
else
|
||||
m_rootNode->appendChildNode(node);
|
||||
}
|
||||
toBeDeleted += pathData.strokeNodes;
|
||||
pathData.strokeNodes = newData.strokeNodes;
|
||||
for (auto *node : std::as_const(pathData.strokeNodes))
|
||||
m_rootNode->appendChildNode(node);
|
||||
}
|
||||
|
||||
if (newData.m_dirty & UniformsDirty)
|
||||
updateUniforms(pathData);
|
||||
|
||||
|
@ -388,6 +411,7 @@ void QQuickShapeCurveRenderer::updateNode()
|
|||
pathData.m_dirty = 0;
|
||||
}
|
||||
}
|
||||
qDeleteAll(toBeDeleted); // also removes them from m_rootNode's child list
|
||||
}
|
||||
|
||||
void QQuickShapeCurveRenderer::processPath(PathData *pathData)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# These are items to be used in other scenes; lack size
|
||||
borderimages/SimpleBorderImage.qml
|
||||
borderimages/SimpleNoBorder.qml
|
||||
shape/OrderedPaths.qml
|
||||
|
||||
# This will not stabilize before the timeout
|
||||
text/text_2500_chinese_characters.qml
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
import QtQuick
|
||||
import QtQuick.Shapes
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property bool async: false
|
||||
|
||||
property int counter: 0
|
||||
NumberAnimation {
|
||||
target: root
|
||||
property: "counter"
|
||||
duration: 2000
|
||||
from: 0
|
||||
to: 15
|
||||
running: true
|
||||
}
|
||||
|
||||
component RectStack : Shape {
|
||||
asynchronous: root.async
|
||||
|
||||
property alias p1FillColor: p1.fillColor
|
||||
property alias p2FillColor: p2.fillColor
|
||||
property alias p3FillColor: p3.fillColor
|
||||
property alias p4FillColor: p4.fillColor
|
||||
property alias p1StrokeColor: p1.strokeColor
|
||||
property alias p2StrokeColor: p2.strokeColor
|
||||
property alias p3StrokeColor: p3.strokeColor
|
||||
property alias p4StrokeColor: p4.strokeColor
|
||||
|
||||
ShapePath {
|
||||
id: p1
|
||||
fillColor: "black"
|
||||
strokeColor: "transparent"
|
||||
strokeWidth: 5
|
||||
startX: 10
|
||||
startY: 10
|
||||
PathLine { relativeX: 100; relativeY: 0 }
|
||||
PathLine { relativeX: 0; relativeY: 60 }
|
||||
PathLine { relativeX: -100; relativeY: 0 }
|
||||
PathLine { relativeX: 0; relativeY: -60 }
|
||||
}
|
||||
ShapePath {
|
||||
id: p2
|
||||
fillColor: "red"
|
||||
strokeColor: "transparent"
|
||||
strokeWidth: 5
|
||||
startX: 20
|
||||
startY: 15
|
||||
PathLine { relativeX: 100; relativeY: 0 }
|
||||
PathLine { relativeX: 0; relativeY: 60 }
|
||||
PathLine { relativeX: -100; relativeY: 0 }
|
||||
PathLine { relativeX: 0; relativeY: -60 }
|
||||
}
|
||||
ShapePath {
|
||||
id: p3
|
||||
fillColor: "green"
|
||||
strokeColor: "transparent"
|
||||
strokeWidth: 5
|
||||
startX: 30
|
||||
startY: 20
|
||||
PathLine { relativeX: 100; relativeY: 0 }
|
||||
PathLine { relativeX: 0; relativeY: 60 }
|
||||
PathLine { relativeX: -100; relativeY: 0 }
|
||||
PathLine { relativeX: 0; relativeY: -60 }
|
||||
}
|
||||
ShapePath {
|
||||
id: p4
|
||||
fillColor: "blue"
|
||||
strokeColor: "transparent"
|
||||
strokeWidth: 5
|
||||
startX: 40
|
||||
startY: 25
|
||||
PathLine { relativeX: 100; relativeY: 0 }
|
||||
PathLine { relativeX: 0; relativeY: 60 }
|
||||
PathLine { relativeX: -100; relativeY: 0 }
|
||||
PathLine { relativeX: 0; relativeY: -60 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ListModel {
|
||||
id: renderers
|
||||
ListElement { renderer: Shape.GeometryRenderer }
|
||||
ListElement { renderer: Shape.CurveRenderer }
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: 5
|
||||
Repeater {
|
||||
model: renderers
|
||||
Column {
|
||||
spacing: 5
|
||||
|
||||
RectStack {
|
||||
preferredRendererType: renderer
|
||||
}
|
||||
|
||||
RectStack {
|
||||
preferredRendererType: renderer
|
||||
p1FillColor: counter % 16 >= 8 ? "black" : "transparent"
|
||||
p2FillColor: counter % 8 >= 4 ? "red" : "transparent"
|
||||
p3FillColor: counter % 4 >= 2 ? "green" : "transparent"
|
||||
p4FillColor: counter % 2 >= 1 ? "blue" : "transparent"
|
||||
}
|
||||
|
||||
RectStack {
|
||||
preferredRendererType: renderer
|
||||
property int shifter: counter < 4 ? counter : counter + 1
|
||||
p1FillColor: shifter % 2 == 0 ? "black" : "transparent"
|
||||
p2FillColor: counter % 2 == 0 ? "red" : "transparent"
|
||||
p3FillColor: shifter % 2 == 1 ? "green" : "transparent"
|
||||
p4FillColor: counter % 2 == 1 ? "blue" : "transparent"
|
||||
}
|
||||
|
||||
RectStack {
|
||||
preferredRendererType: renderer
|
||||
p1FillColor: counter % 16 >= 8 ? "black" : "transparent"
|
||||
p2FillColor: counter % 8 >= 4 ? "red" : "transparent"
|
||||
p3FillColor: counter % 4 >= 2 ? "green" : "transparent"
|
||||
p4FillColor: counter % 2 >= 1 ? "blue" : "transparent"
|
||||
p1StrokeColor: counter % 2 >= 1 ? "transparent" : "lightblue"
|
||||
p2StrokeColor: counter % 4 >= 2 ? "transparent" : "lightgreen"
|
||||
p3StrokeColor: counter % 8 >= 4 ? "transparent" : "pink"
|
||||
p4StrokeColor: counter % 16 >= 8 ? "transparent" : "gray"
|
||||
}
|
||||
|
||||
RectStack {
|
||||
preferredRendererType: renderer
|
||||
p1FillColor: "transparent"
|
||||
p2FillColor: "transparent"
|
||||
p3FillColor: "transparent"
|
||||
p4FillColor: "transparent"
|
||||
p1StrokeColor: counter % 16 >= 8 ? "lightblue": "transparent"
|
||||
p2StrokeColor: counter % 8 >= 4 ? "lightgreen": "transparent"
|
||||
p3StrokeColor: counter % 4 >= 2 ? "pink": "transparent"
|
||||
p4StrokeColor: counter % 2 >= 1 ? "gray" : "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import QtQuick
|
||||
|
||||
Item {
|
||||
width: 320
|
||||
height: 480
|
||||
|
||||
OrderedPaths {
|
||||
anchors.fill: parent
|
||||
async: false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import QtQuick
|
||||
|
||||
Item {
|
||||
width: 320
|
||||
height: 480
|
||||
|
||||
OrderedPaths {
|
||||
anchors.fill: parent
|
||||
async: true
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue