Add support for show layout bounds.
Summary: Supports show layout bounds either by override within FlatViewGroup, or if show layout bounds is set in settings. Currently requires app restart to disable. Reviewed By: ahmedre Differential Revision: D3553669
This commit is contained in:
parent
76c2904d31
commit
7df627f9be
|
@ -10,6 +10,7 @@
|
|||
package com.facebook.react.flat;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
|
||||
/**
|
||||
* Base class for all DrawCommands. Becomes immutable once it has its bounds set. Until then, a
|
||||
|
@ -40,6 +41,26 @@ import android.graphics.Canvas;
|
|||
}
|
||||
}
|
||||
|
||||
protected static int getDebugBorderColor() {
|
||||
return Color.CYAN;
|
||||
}
|
||||
|
||||
protected String getDebugName() {
|
||||
return getClass().getSimpleName().substring(4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debugDraw(FlatViewGroup parent, Canvas canvas) {
|
||||
parent.debugDrawNamedRect(
|
||||
canvas,
|
||||
getDebugBorderColor(),
|
||||
getDebugName(),
|
||||
mLeft,
|
||||
mTop,
|
||||
mRight,
|
||||
mBottom);
|
||||
}
|
||||
|
||||
protected void onPreDraw(FlatViewGroup parent, Canvas canvas) {
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,16 @@ public interface DrawCommand {
|
|||
/**
|
||||
* Performs drawing into the given canvas.
|
||||
*
|
||||
* @param parent The parent to get child information from, if needed
|
||||
* @param canvas The canvas to draw into
|
||||
*/
|
||||
public void draw(FlatViewGroup parent, Canvas canvas);
|
||||
|
||||
/**
|
||||
* Performs debug bounds drawing into the given canvas.
|
||||
*
|
||||
* @param parent The parent to get child information from, if needed
|
||||
* @param canvas The canvas to draw into
|
||||
*/
|
||||
public void debugDraw(FlatViewGroup parent, Canvas canvas);
|
||||
}
|
||||
|
|
|
@ -32,4 +32,9 @@ import android.graphics.Canvas;
|
|||
parent.drawNextChild(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debugDraw(FlatViewGroup parent, Canvas canvas) {
|
||||
parent.debugDrawNextChild(canvas);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ import java.util.Map;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -81,6 +83,15 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
|
|||
}
|
||||
}
|
||||
|
||||
private static final boolean DEBUG_DRAW = false;
|
||||
private static final boolean DEBUG_DRAW_TEXT = false;
|
||||
private boolean mAndroidDebugDraw;
|
||||
private static Paint sDebugTextPaint;
|
||||
private static Paint sDebugTextBackgroundPaint;
|
||||
private static Paint sDebugRectPaint;
|
||||
private static Paint sDebugCornerPaint;
|
||||
private static Rect sDebugRect;
|
||||
|
||||
private static final ArrayList<FlatViewGroup> LAYOUT_REQUESTS = new ArrayList<>();
|
||||
private static final Rect VIEW_BOUNDS = new Rect();
|
||||
private static final Rect EMPTY_RECT = new Rect();
|
||||
|
@ -162,8 +173,15 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
|
|||
return nodeRegion != null && nodeRegion.mIsVirtual;
|
||||
}
|
||||
|
||||
// This is hidden in the Android ViewGroup, but still gets called in super.dispatchDraw.
|
||||
protected void onDebugDraw(Canvas canvas) {
|
||||
// Android is drawing layout bounds, so we should as well.
|
||||
mAndroidDebugDraw = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchDraw(Canvas canvas) {
|
||||
mAndroidDebugDraw = false;
|
||||
super.dispatchDraw(canvas);
|
||||
|
||||
if (mRemoveClippedSubviews) {
|
||||
|
@ -189,11 +207,30 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
|
|||
}
|
||||
mDrawChildIndex = 0;
|
||||
|
||||
if (DEBUG_DRAW || mAndroidDebugDraw) {
|
||||
initDebugDrawResources();
|
||||
debugDraw(canvas);
|
||||
}
|
||||
|
||||
if (mHotspot != null) {
|
||||
mHotspot.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
private void debugDraw(Canvas canvas) {
|
||||
for (DrawCommand drawCommand : mDrawCommands) {
|
||||
if (drawCommand instanceof DrawView) {
|
||||
if (!((DrawView) drawCommand).isViewGroupClipped) {
|
||||
drawCommand.debugDraw(this, canvas);
|
||||
}
|
||||
// else, don't draw, and don't increment index
|
||||
} else {
|
||||
drawCommand.debugDraw(this, canvas);
|
||||
}
|
||||
}
|
||||
mDrawChildIndex = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||
// suppress
|
||||
|
@ -201,6 +238,153 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
|
|||
return false;
|
||||
}
|
||||
|
||||
/* package */ void debugDrawNextChild(Canvas canvas) {
|
||||
View child = getChildAt(mDrawChildIndex);
|
||||
// Draw FlatViewGroups a different color than regular child views.
|
||||
int color = child instanceof FlatViewGroup ? Color.DKGRAY : Color.RED;
|
||||
debugDrawRect(
|
||||
canvas,
|
||||
color,
|
||||
child.getLeft(),
|
||||
child.getTop(),
|
||||
child.getRight(),
|
||||
child.getBottom());
|
||||
++mDrawChildIndex;
|
||||
}
|
||||
|
||||
// Used in debug drawing.
|
||||
private int dipsToPixels(int dips) {
|
||||
float scale = getResources().getDisplayMetrics().density;
|
||||
return (int) (dips * scale + 0.5f);
|
||||
}
|
||||
|
||||
// Used in debug drawing.
|
||||
private static void fillRect(Canvas canvas, Paint paint, float x1, float y1, float x2, float y2) {
|
||||
if (x1 != x2 && y1 != y2) {
|
||||
if (x1 > x2) {
|
||||
float tmp = x1; x1 = x2; x2 = tmp;
|
||||
}
|
||||
if (y1 > y2) {
|
||||
float tmp = y1; y1 = y2; y2 = tmp;
|
||||
}
|
||||
canvas.drawRect(x1, y1, x2, y2, paint);
|
||||
}
|
||||
}
|
||||
|
||||
// Used in debug drawing.
|
||||
private static int sign(float x) {
|
||||
return (x >= 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
// Used in debug drawing.
|
||||
private static void drawCorner(
|
||||
Canvas c,
|
||||
Paint paint,
|
||||
float x1,
|
||||
float y1,
|
||||
float dx,
|
||||
float dy,
|
||||
float lw) {
|
||||
fillRect(c, paint, x1, y1, x1 + dx, y1 + lw * sign(dy));
|
||||
fillRect(c, paint, x1, y1, x1 + lw * sign(dx), y1 + dy);
|
||||
}
|
||||
|
||||
// Used in debug drawing.
|
||||
private static void drawRectCorners(
|
||||
Canvas canvas,
|
||||
float x1,
|
||||
float y1,
|
||||
float x2,
|
||||
float y2,
|
||||
Paint paint,
|
||||
int lineLength,
|
||||
int lineWidth) {
|
||||
drawCorner(canvas, paint, x1, y1, lineLength, lineLength, lineWidth);
|
||||
drawCorner(canvas, paint, x1, y2, lineLength, -lineLength, lineWidth);
|
||||
drawCorner(canvas, paint, x2, y1, -lineLength, lineLength, lineWidth);
|
||||
drawCorner(canvas, paint, x2, y2, -lineLength, -lineLength, lineWidth);
|
||||
}
|
||||
|
||||
private void initDebugDrawResources() {
|
||||
if (sDebugTextPaint == null) {
|
||||
sDebugTextPaint = new Paint();
|
||||
sDebugTextPaint.setTextAlign(Paint.Align.RIGHT);
|
||||
sDebugTextPaint.setTextSize(dipsToPixels(9));
|
||||
sDebugTextPaint.setColor(Color.RED);
|
||||
}
|
||||
if (sDebugTextBackgroundPaint == null) {
|
||||
sDebugTextBackgroundPaint = new Paint();
|
||||
sDebugTextBackgroundPaint.setColor(Color.WHITE);
|
||||
sDebugTextBackgroundPaint.setAlpha(200);
|
||||
sDebugTextBackgroundPaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
if (sDebugRectPaint == null) {
|
||||
sDebugRectPaint = new Paint();
|
||||
sDebugRectPaint.setAlpha(100);
|
||||
sDebugRectPaint.setStyle(Paint.Style.STROKE);
|
||||
}
|
||||
if (sDebugCornerPaint == null) {
|
||||
sDebugCornerPaint = new Paint();
|
||||
sDebugCornerPaint.setAlpha(200);
|
||||
sDebugCornerPaint.setColor(Color.rgb(63, 127, 255));
|
||||
sDebugCornerPaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
if (sDebugRect == null) {
|
||||
sDebugRect = new Rect();
|
||||
}
|
||||
}
|
||||
|
||||
private void debugDrawRect(
|
||||
Canvas canvas,
|
||||
int color,
|
||||
float left,
|
||||
float top,
|
||||
float right,
|
||||
float bottom) {
|
||||
debugDrawNamedRect(canvas, color, "", left, top, right, bottom);
|
||||
}
|
||||
|
||||
/* package */ void debugDrawNamedRect(
|
||||
Canvas canvas,
|
||||
int color,
|
||||
String name,
|
||||
float left,
|
||||
float top,
|
||||
float right,
|
||||
float bottom) {
|
||||
if (DEBUG_DRAW_TEXT && !name.isEmpty()) {
|
||||
sDebugTextPaint.getTextBounds(name, 0, name.length(), sDebugRect);
|
||||
int inset = dipsToPixels(2);
|
||||
float textRight = right - inset - 1;
|
||||
float textBottom = bottom - inset - 1;
|
||||
canvas.drawRect(
|
||||
textRight - sDebugRect.right - inset,
|
||||
textBottom + sDebugRect.top - inset,
|
||||
textRight + inset,
|
||||
textBottom + inset,
|
||||
sDebugTextBackgroundPaint);
|
||||
canvas.drawText(name, textRight, textBottom, sDebugTextPaint);
|
||||
}
|
||||
// Retain the alpha component.
|
||||
sDebugRectPaint.setColor((sDebugRectPaint.getColor() & 0xFF000000) | (color & 0x00FFFFFF));
|
||||
sDebugRectPaint.setAlpha(100);
|
||||
canvas.drawRect(
|
||||
left,
|
||||
top,
|
||||
right - 1,
|
||||
bottom - 1,
|
||||
sDebugRectPaint);
|
||||
drawRectCorners(
|
||||
canvas,
|
||||
left,
|
||||
top,
|
||||
right,
|
||||
bottom,
|
||||
sDebugCornerPaint,
|
||||
dipsToPixels(8),
|
||||
dipsToPixels(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
// nothing to do here
|
||||
|
|
Loading…
Reference in New Issue