Add traverseChildren for virtualNode

This commit is contained in:
Horcrux
2016-11-09 13:10:53 +08:00
parent 374d716f0b
commit e48e5916ce
7 changed files with 106 additions and 78 deletions
@@ -22,9 +22,7 @@ import com.facebook.react.uimanager.annotations.ReactProp;
public class RNSVGCircleShadowNode extends RNSVGPathShadowNode {
private String mCx;
private String mCy;
private String mR;
@ReactProp(name = "cx")
@@ -9,13 +9,46 @@
package com.horcrux.svg;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
/**
* Shadow node for virtual RNSVGClipPath view
*/
public class RNSVGClipPathShadowNode extends RNSVGGroupShadowNode {
@Override
public void draw(Canvas canvas, Paint paint, float opacity) {
FLog.w(ReactConstants.TAG, "RNSVG: ClipPath can't be drawn, it should be defined as a child component for `Defs` ");
}
@Override
protected void saveDefinition() {
getSvgShadowNode().defineClipPath(this, mName);
}
@Override
public boolean isResponsible() {
return false;
}
@Override
public int hitTest(Point point, Matrix matrix) {
return -1;
}
@Override
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList, boolean inherited) {}
@Override
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList) {}
@Override
public void resetProperties() {}
}
@@ -19,18 +19,12 @@ public class RNSVGDefsShadowNode extends RNSVGDefinitionShadowNode {
@Override
public void draw(Canvas canvas, Paint paint, float opacity) {
int count = saveAndSetupCanvas(canvas);
clip(canvas, paint);
for (int i = 0; i < getChildCount(); i++) {
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) {
continue;
traverseChildren(new NodeRunnable() {
@Override
public boolean run(RNSVGVirtualNode node) {
node.saveDefinition();
return true;
}
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
child.saveDefinition();
}
restoreCanvas(canvas, count);
});
}
}
@@ -26,52 +26,52 @@ import javax.annotation.Nullable;
*/
public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
public void draw(Canvas canvas, Paint paint, float opacity) {
RNSVGSvgViewShadowNode svg = getSvgShadowNode();
public void draw(final Canvas canvas, final Paint paint, final float opacity) {
final RNSVGSvgViewShadowNode svg = getSvgShadowNode();
final RNSVGVirtualNode self = this;
if (opacity > MIN_OPACITY_FOR_DRAW) {
int count = saveAndSetupCanvas(canvas);
clip(canvas, paint);
for (int i = 0; i < getChildCount(); i++) {
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) {
continue;
traverseChildren(new NodeRunnable() {
@Override
public boolean run(RNSVGVirtualNode node) {
node.setupDimensions(canvas);
node.mergeProperties(self, mOwnedPropList, true);
node.draw(canvas, paint, opacity * mOpacity);
node.markUpdateSeen();
if (node.isResponsible()) {
svg.enableTouchEvents();
}
return true;
}
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
child.setupDimensions(canvas);
child.mergeProperties(this, mOwnedPropList, true);
child.draw(canvas, paint, opacity * mOpacity);
child.markUpdateSeen();
if (child.isResponsible()) {
svg.enableTouchEvents();
}
}
});
restoreCanvas(canvas, count);
}
}
@Override
protected Path getPath(Canvas canvas, Paint paint) {
Path path = new Path();
protected Path getPath(final Canvas canvas, final Paint paint) {
final Path path = new Path();
for (int i = 0; i < getChildCount(); i++) {
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) {
continue;
traverseChildren(new NodeRunnable() {
@Override
public boolean run(RNSVGVirtualNode node) {
node.setupDimensions(canvas);
path.addPath(node.getPath(canvas, paint));
return true;
}
});
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
child.setupDimensions(canvas);
path.addPath(child.getPath(canvas, paint));
}
return path;
}
@Override
public int hitTest(Point point, @Nullable Matrix matrix) {
int viewTag = -1;
public int hitTest(final Point point, final @Nullable Matrix matrix) {
Matrix combinedMatrix = new Matrix();
if (matrix != null) {
@@ -88,13 +88,13 @@ public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
RNSVGVirtualNode node = (RNSVGVirtualNode) child;
viewTag = node.hitTest(point, combinedMatrix);
int viewTag = node.hitTest(point, combinedMatrix);
if (viewTag != -1) {
return (node.isResponsible() || viewTag != child.getReactTag()) ? viewTag : getReactTag();
}
}
return viewTag;
return -1;
}
protected void saveDefinition() {
@@ -102,36 +102,34 @@ public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
getSvgShadowNode().defineTemplate(this, mName);
}
for (int i = getChildCount() - 1; i >= 0; i--) {
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) {
continue;
traverseChildren(new NodeRunnable() {
@Override
public boolean run(RNSVGVirtualNode node) {
node.saveDefinition();
return true;
}
((RNSVGVirtualNode) getChildAt(i)).saveDefinition();
}
});
}
@Override
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList) {
if (mergeList.size() != 0) {
for (int i = getChildCount() - 1; i >= 0; i--) {
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) {
continue;
}
((RNSVGVirtualNode) getChildAt(i)).mergeProperties(target, mergeList);
public void mergeProperties(final RNSVGVirtualNode target, final ReadableArray mergeList) {
traverseChildren(new NodeRunnable() {
@Override
public boolean run(RNSVGVirtualNode node) {
node.mergeProperties(target, mergeList);
return true;
}
}
});
}
@Override
public void resetProperties() {
for (int i = getChildCount() - 1; i >= 0; i--) {
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) {
continue;
traverseChildren(new NodeRunnable() {
@Override
public boolean run(RNSVGVirtualNode node) {
node.resetProperties();
return true;
}
((RNSVGVirtualNode) getChildAt(i)).resetProperties();
}
});
}
}
@@ -20,11 +20,8 @@ import com.facebook.react.uimanager.annotations.ReactProp;
public class RNSVGLineShadowNode extends RNSVGPathShadowNode {
private String mX1;
private String mY1;
private String mX2;
private String mY2;
@ReactProp(name = "x1")
@@ -21,15 +21,10 @@ import com.facebook.react.uimanager.annotations.ReactProp;
public class RNSVGRectShadowNode extends RNSVGPathShadowNode {
private String mX;
private String mY;
private String mW;
private String mH;
private String mRx;
private String mRy;
@@ -274,11 +274,7 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
}
protected void setupDimensions(Canvas canvas) {
Rect mCanvasClipBounds = canvas.getClipBounds();
mCanvasX = mCanvasClipBounds.left;
mCanvasY = mCanvasClipBounds.top;
mCanvasWidth = canvas.getWidth();
mCanvasHeight = canvas.getHeight();
setupDimensions(canvas.getClipBounds());
}
protected void setupDimensions(Rect rect) {
@@ -299,4 +295,21 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
abstract public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList);
abstract public void resetProperties();
protected interface NodeRunnable {
boolean run(RNSVGVirtualNode node);
}
protected void traverseChildren(NodeRunnable runner) {
for (int i = 0; i < getChildCount(); i++) {
ReactShadowNode child = getChildAt(i);
if (!(child instanceof RNSVGVirtualNode)) {
continue;
}
if (!runner.run((RNSVGVirtualNode) child)) {
break;
}
}
}
}