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 { public class RNSVGCircleShadowNode extends RNSVGPathShadowNode {
private String mCx; private String mCx;
private String mCy; private String mCy;
private String mR; private String mR;
@ReactProp(name = "cx") @ReactProp(name = "cx")
@@ -9,13 +9,46 @@
package com.horcrux.svg; 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 * Shadow node for virtual RNSVGClipPath view
*/ */
public class RNSVGClipPathShadowNode extends RNSVGGroupShadowNode { 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 @Override
protected void saveDefinition() { protected void saveDefinition() {
getSvgShadowNode().defineClipPath(this, mName); 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 @Override
public void draw(Canvas canvas, Paint paint, float opacity) { public void draw(Canvas canvas, Paint paint, float opacity) {
int count = saveAndSetupCanvas(canvas); traverseChildren(new NodeRunnable() {
clip(canvas, paint); @Override
public boolean run(RNSVGVirtualNode node) {
for (int i = 0; i < getChildCount(); i++) { node.saveDefinition();
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) { return true;
continue;
} }
});
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
child.saveDefinition();
}
restoreCanvas(canvas, count);
} }
} }
@@ -26,52 +26,52 @@ import javax.annotation.Nullable;
*/ */
public class RNSVGGroupShadowNode extends RNSVGPathShadowNode { public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
public void draw(Canvas canvas, Paint paint, float opacity) { public void draw(final Canvas canvas, final Paint paint, final float opacity) {
RNSVGSvgViewShadowNode svg = getSvgShadowNode(); final RNSVGSvgViewShadowNode svg = getSvgShadowNode();
final RNSVGVirtualNode self = this;
if (opacity > MIN_OPACITY_FOR_DRAW) { if (opacity > MIN_OPACITY_FOR_DRAW) {
int count = saveAndSetupCanvas(canvas); int count = saveAndSetupCanvas(canvas);
clip(canvas, paint); clip(canvas, paint);
for (int i = 0; i < getChildCount(); i++) {
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) { traverseChildren(new NodeRunnable() {
continue; @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); restoreCanvas(canvas, count);
} }
} }
@Override @Override
protected Path getPath(Canvas canvas, Paint paint) { protected Path getPath(final Canvas canvas, final Paint paint) {
Path path = new Path(); final Path path = new Path();
for (int i = 0; i < getChildCount(); i++) { traverseChildren(new NodeRunnable() {
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) { @Override
continue; 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; return path;
} }
@Override @Override
public int hitTest(Point point, @Nullable Matrix matrix) { public int hitTest(final Point point, final @Nullable Matrix matrix) {
int viewTag = -1;
Matrix combinedMatrix = new Matrix(); Matrix combinedMatrix = new Matrix();
if (matrix != null) { if (matrix != null) {
@@ -88,13 +88,13 @@ public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
RNSVGVirtualNode node = (RNSVGVirtualNode) child; RNSVGVirtualNode node = (RNSVGVirtualNode) child;
viewTag = node.hitTest(point, combinedMatrix); int viewTag = node.hitTest(point, combinedMatrix);
if (viewTag != -1) { if (viewTag != -1) {
return (node.isResponsible() || viewTag != child.getReactTag()) ? viewTag : getReactTag(); return (node.isResponsible() || viewTag != child.getReactTag()) ? viewTag : getReactTag();
} }
} }
return viewTag; return -1;
} }
protected void saveDefinition() { protected void saveDefinition() {
@@ -102,36 +102,34 @@ public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
getSvgShadowNode().defineTemplate(this, mName); getSvgShadowNode().defineTemplate(this, mName);
} }
for (int i = getChildCount() - 1; i >= 0; i--) { traverseChildren(new NodeRunnable() {
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) { @Override
continue; public boolean run(RNSVGVirtualNode node) {
node.saveDefinition();
return true;
} }
});
((RNSVGVirtualNode) getChildAt(i)).saveDefinition();
}
} }
@Override @Override
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList) { public void mergeProperties(final RNSVGVirtualNode target, final ReadableArray mergeList) {
if (mergeList.size() != 0) { traverseChildren(new NodeRunnable() {
for (int i = getChildCount() - 1; i >= 0; i--) { @Override
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) { public boolean run(RNSVGVirtualNode node) {
continue; node.mergeProperties(target, mergeList);
} return true;
((RNSVGVirtualNode) getChildAt(i)).mergeProperties(target, mergeList);
} }
} });
} }
@Override @Override
public void resetProperties() { public void resetProperties() {
for (int i = getChildCount() - 1; i >= 0; i--) { traverseChildren(new NodeRunnable() {
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) { @Override
continue; 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 { public class RNSVGLineShadowNode extends RNSVGPathShadowNode {
private String mX1; private String mX1;
private String mY1; private String mY1;
private String mX2; private String mX2;
private String mY2; private String mY2;
@ReactProp(name = "x1") @ReactProp(name = "x1")
@@ -21,15 +21,10 @@ import com.facebook.react.uimanager.annotations.ReactProp;
public class RNSVGRectShadowNode extends RNSVGPathShadowNode { public class RNSVGRectShadowNode extends RNSVGPathShadowNode {
private String mX; private String mX;
private String mY; private String mY;
private String mW; private String mW;
private String mH; private String mH;
private String mRx; private String mRx;
private String mRy; private String mRy;
@@ -274,11 +274,7 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
} }
protected void setupDimensions(Canvas canvas) { protected void setupDimensions(Canvas canvas) {
Rect mCanvasClipBounds = canvas.getClipBounds(); setupDimensions(canvas.getClipBounds());
mCanvasX = mCanvasClipBounds.left;
mCanvasY = mCanvasClipBounds.top;
mCanvasWidth = canvas.getWidth();
mCanvasHeight = canvas.getHeight();
} }
protected void setupDimensions(Rect rect) { 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 mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList);
abstract public void resetProperties(); 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;
}
}
}
} }