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();
}
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
@ -134,6 +153,24 @@ class Node {
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
Matrix4 get transformMatrix {
@ -244,7 +281,7 @@ class Node {
// Hit test
bool hitTest(Point nodePoint) {
bool isPointInside(Point nodePoint) {
assert(nodePoint != null);
return false;
@ -252,17 +289,16 @@ class Node {
// Rendering
void visit(PictureRecorder canvas) {
void _visit(PictureRecorder canvas) {
assert(canvas != null);
if (!visible) return;
prePaint(canvas);
paint(canvas);
visitChildren(canvas);
postPaint(canvas);
_prePaint(canvas);
_visitChildren(canvas);
_postPaint(canvas);
}
void prePaint(PictureRecorder canvas) {
void _prePaint(PictureRecorder canvas) {
canvas.save();
// Get the transformation matrix and apply transform
@ -272,28 +308,32 @@ class Node {
void paint(PictureRecorder canvas) {
}
void visitChildren(PictureRecorder canvas) {
// 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;
void _visitChildren(PictureRecorder canvas) {
// Sort children if needed
_sortChildren();
int i = 0;
// Visit children behind this node
while (i < _children.length) {
Node child = _children[i];
if (child.zPosition >= 0.0) break;
child._visit(canvas);
i++;
}
// Visit each child
_children.forEach((child) => child.visit(canvas));
// Paint this node
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();
}

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 minY = -size.height * pivot.y;

View File

@ -74,11 +74,27 @@ class SpriteBox extends RenderBox {
// Event handling
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) {
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);
i++;
}
}
@ -101,7 +117,7 @@ class SpriteBox extends RenderBox {
if (node.handleMultiplePointers || node._handlingPointer == null) {
// Do the hit test
Point posInNodeSpace = node.convertPointToNodeSpace(entry.localPosition);
if (node.hitTest(posInNodeSpace)) {
if (node.isPointInside(posInNodeSpace)) {
nodeTargets.add(node);
node._handlingPointer = event.pointer;
}
@ -221,7 +237,7 @@ class SpriteBox extends RenderBox {
canvas.concat(transformMatrix.storage);
// Draw the sprite tree
_rootNode.visit(canvas);
_rootNode._visit(canvas);
canvas.restore();
}
@ -289,7 +305,7 @@ class SpriteBox extends RenderBox {
}
// Do the hit test
Point posInNodeSpace = node.convertPointToNodeSpace(position);
if (node.hitTest(posInNodeSpace)) {
if (node.isPointInside(posInNodeSpace)) {
list.add(node);
}
}