Correctly handle touches together with zPosition

Renames hitTest to isPointInside

Refactor sorting of children in nodes

Fixes zPosition in sprites and hides internal methods

Adds scaleX / scaleY properties

R=abarth@chromium.org

Review URL: https://codereview.chromium.org/1190393004.
This commit is contained in:
Viktor Lidholt 2015-06-19 11:15:58 -07:00
parent 0dd98719dc
commit 43d97f6903
3 changed files with 87 additions and 31 deletions

View File

@ -93,7 +93,26 @@ class Node {
_invalidateTransformMatrix(); _invalidateTransformMatrix();
} }
List<Node> get children => _children; double get scaleX => _scaleX;
void set scaleX(double scaleX) {
assert(scaleX != null);
_scaleX = scaleX;
_invalidateTransformMatrix();
}
double get scaleY => _scaleY;
void set scaleY(double scaleY) {
assert(scaleY != null);
_scaleY = scaleY;
_invalidateTransformMatrix();
}
List<Node> get children {
_sortChildren();
return _children;
}
// Adding and removing children // Adding and removing children
@ -134,6 +153,24 @@ class Node {
if (_spriteBox != null) _spriteBox._eventTargets = null; if (_spriteBox != null) _spriteBox._eventTargets = null;
} }
void _sortChildren() {
// Sort children primarily by zPosition, secondarily by added order
if (_childrenNeedSorting) {
_children.sort((Node a, Node b) {
if (a._zPosition == b._zPosition) {
return a._addedOrder - b._addedOrder;
}
else if (a._zPosition > b._zPosition) {
return 1;
}
else {
return -1;
}
});
_childrenNeedSorting = false;
}
}
// Calculating the transformation matrix // Calculating the transformation matrix
Matrix4 get transformMatrix { Matrix4 get transformMatrix {
@ -244,7 +281,7 @@ class Node {
// Hit test // Hit test
bool hitTest(Point nodePoint) { bool isPointInside(Point nodePoint) {
assert(nodePoint != null); assert(nodePoint != null);
return false; return false;
@ -252,17 +289,16 @@ class Node {
// Rendering // Rendering
void visit(PictureRecorder canvas) { void _visit(PictureRecorder canvas) {
assert(canvas != null); assert(canvas != null);
if (!visible) return; if (!visible) return;
prePaint(canvas); _prePaint(canvas);
paint(canvas); _visitChildren(canvas);
visitChildren(canvas); _postPaint(canvas);
postPaint(canvas);
} }
void prePaint(PictureRecorder canvas) { void _prePaint(PictureRecorder canvas) {
canvas.save(); canvas.save();
// Get the transformation matrix and apply transform // Get the transformation matrix and apply transform
@ -272,28 +308,32 @@ class Node {
void paint(PictureRecorder canvas) { void paint(PictureRecorder canvas) {
} }
void visitChildren(PictureRecorder canvas) { void _visitChildren(PictureRecorder canvas) {
// Sort children primarily by zPosition, secondarily by added order // Sort children if needed
if (_childrenNeedSorting) { _sortChildren();
_children.sort((Node a, Node b) {
if (a._zPosition == b._zPosition) { int i = 0;
return a._addedOrder - b._addedOrder;
} // Visit children behind this node
else if (a._zPosition > b._zPosition) { while (i < _children.length) {
return 1; Node child = _children[i];
} if (child.zPosition >= 0.0) break;
else { child._visit(canvas);
return -1; i++;
}
});
_childrenNeedSorting = false;
} }
// Visit each child // Paint this node
_children.forEach((child) => child.visit(canvas)); paint(canvas);
// Visit children in front of this node
while (i < _children.length) {
Node child = _children[i];
child._visit(canvas);
i++;
}
} }
void postPaint(PictureRecorder canvas) { void _postPaint(PictureRecorder canvas) {
canvas.restore(); canvas.restore();
} }

View File

@ -21,7 +21,7 @@ abstract class NodeWithSize extends Node {
} }
} }
bool hitTest (Point nodePoint) { bool isPointInside (Point nodePoint) {
double minX = -size.width * pivot.x; double minX = -size.width * pivot.x;
double minY = -size.height * pivot.y; double minY = -size.height * pivot.y;

View File

@ -74,11 +74,27 @@ class SpriteBox extends RenderBox {
// Event handling // Event handling
void _addEventTargets(Node node, List<Node> eventTargets) { void _addEventTargets(Node node, List<Node> eventTargets) {
List children = node.children;
int i = 0;
// Add childrens that are behind this node
while (i < children.length) {
Node child = children[i];
if (child.zPosition >= 0.0) break;
_addEventTargets(child, eventTargets);
i++;
}
// Add this node
if (node.userInteractionEnabled) { if (node.userInteractionEnabled) {
eventTargets.add(node); eventTargets.add(node);
} }
for (Node child in node.children) {
// Add children in front of this node
while (i < children.length) {
Node child = children[i];
_addEventTargets(child, eventTargets); _addEventTargets(child, eventTargets);
i++;
} }
} }
@ -101,7 +117,7 @@ class SpriteBox extends RenderBox {
if (node.handleMultiplePointers || node._handlingPointer == null) { if (node.handleMultiplePointers || node._handlingPointer == null) {
// Do the hit test // Do the hit test
Point posInNodeSpace = node.convertPointToNodeSpace(entry.localPosition); Point posInNodeSpace = node.convertPointToNodeSpace(entry.localPosition);
if (node.hitTest(posInNodeSpace)) { if (node.isPointInside(posInNodeSpace)) {
nodeTargets.add(node); nodeTargets.add(node);
node._handlingPointer = event.pointer; node._handlingPointer = event.pointer;
} }
@ -221,7 +237,7 @@ class SpriteBox extends RenderBox {
canvas.concat(transformMatrix.storage); canvas.concat(transformMatrix.storage);
// Draw the sprite tree // Draw the sprite tree
_rootNode.visit(canvas); _rootNode._visit(canvas);
canvas.restore(); canvas.restore();
} }
@ -289,7 +305,7 @@ class SpriteBox extends RenderBox {
} }
// Do the hit test // Do the hit test
Point posInNodeSpace = node.convertPointToNodeSpace(position); Point posInNodeSpace = node.convertPointToNodeSpace(position);
if (node.hitTest(posInNodeSpace)) { if (node.isPointInside(posInNodeSpace)) {
list.add(node); list.add(node);
} }
} }