From 8ea28097424651ec95de2d70e43ac9ef067c3f8c Mon Sep 17 00:00:00 2001 From: Phoomraphee Luenam Date: Mon, 6 Aug 2018 04:09:27 -0700 Subject: [PATCH] Add Alignment Functionality for Sonar Summary: Part of a hackathon project. (https://fb.facebook.com/groups/230455004101832/permalink/454928784987785/) We're adding an alignment mode for Sonar that shows the pixel level alignment. Reviewed By: danielbuechele Differential Revision: D9121197 fbshipit-source-id: 21af36fd7eeea631d580ccebff8e648fa276bf35 --- .../plugins/inspector/HighlightedOverlay.java | 61 ++++++++---- .../plugins/inspector/LinesDrawable.java | 92 +++++++++++++++++++ 2 files changed, 137 insertions(+), 16 deletions(-) create mode 100644 android/src/main/java/com/facebook/sonar/plugins/inspector/LinesDrawable.java diff --git a/android/src/main/java/com/facebook/sonar/plugins/inspector/HighlightedOverlay.java b/android/src/main/java/com/facebook/sonar/plugins/inspector/HighlightedOverlay.java index b887feee9..217b20664 100644 --- a/android/src/main/java/com/facebook/sonar/plugins/inspector/HighlightedOverlay.java +++ b/android/src/main/java/com/facebook/sonar/plugins/inspector/HighlightedOverlay.java @@ -12,6 +12,7 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; import android.view.View; +import android.util.Log; /** * A singleton instance of a overlay drawable used for highlighting node bounds. See {@link @@ -31,24 +32,49 @@ public class HighlightedOverlay { */ public static void setHighlighted( View targetView, Rect margin, Rect padding, Rect contentBounds) { - if (!VIEW_OVERLAY_SUPPORT) { - return; - } - - contentBounds.set( - contentBounds.left + padding.left, - contentBounds.top + padding.top, - contentBounds.right - padding.right, - contentBounds.bottom - padding.bottom); - - padding = enclose(padding, contentBounds); - margin = enclose(margin, padding); - - final float density = targetView.getContext().getResources().getDisplayMetrics().density; - final Drawable overlay = BoundsDrawable.getInstance(density, margin, padding, contentBounds); - targetView.getOverlay().add(overlay); + setHighlightedAndAlignment(targetView, margin, padding, contentBounds, false); } + public static void setHighlightedAndAlignment( + View targetView, Rect margin, Rect padding, Rect contentBounds, boolean isAlignmentMode) { + if (!VIEW_OVERLAY_SUPPORT) { + return; + } + + contentBounds.set( + contentBounds.left + padding.left, + contentBounds.top + padding.top, + contentBounds.right - padding.right, + contentBounds.bottom - padding.bottom); + + padding = enclose(padding, contentBounds); + margin = enclose(margin, padding); + + final float density = targetView.getContext().getResources().getDisplayMetrics().density; + final Drawable overlay = BoundsDrawable.getInstance(density, margin, padding, contentBounds); + + targetView.getOverlay().add(overlay); + + if(isAlignmentMode) { + int[] coords = new int[2]; + targetView.getLocationOnScreen(coords); + Rect lineContentBounds = + new Rect( + coords[0] + contentBounds.left, + coords[1] + contentBounds.top, + coords[0] + contentBounds.right, + coords[1] + contentBounds.bottom); + + final Drawable lineOverlay = LinesDrawable.getInstance(density, margin, padding, lineContentBounds); + + targetView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); + + + + targetView.getRootView().getOverlay().add(lineOverlay); + } + } + public static void removeHighlight(View targetView) { if (!VIEW_OVERLAY_SUPPORT) { return; @@ -56,6 +82,9 @@ public class HighlightedOverlay { final float density = targetView.getContext().getResources().getDisplayMetrics().density; final Drawable overlay = BoundsDrawable.getInstance(density); + final Drawable overlay2 = LinesDrawable.getInstance(density); + targetView.getRootView().getOverlay().remove(overlay2); + targetView.getOverlay().remove(overlay); } diff --git a/android/src/main/java/com/facebook/sonar/plugins/inspector/LinesDrawable.java b/android/src/main/java/com/facebook/sonar/plugins/inspector/LinesDrawable.java new file mode 100644 index 000000000..3b3b5f205 --- /dev/null +++ b/android/src/main/java/com/facebook/sonar/plugins/inspector/LinesDrawable.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.DashPathEffect; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.Region; +import android.graphics.drawable.Drawable; +import android.text.TextPaint; +import javax.annotation.Nullable; + +public class LinesDrawable extends Drawable { + private static @Nullable LinesDrawable sInstance; + + private final Rect mWorkRect; + private final Rect mMarginBounds; + private final Rect mPaddingBounds; + private final Rect mContentBounds; + + private final float mDensity; + + public static LinesDrawable getInstance( + float density, Rect marginBounds, Rect paddingBounds, Rect contentBounds) { + final LinesDrawable drawable = getInstance(density); + drawable.setBounds(marginBounds, paddingBounds, contentBounds); + return drawable; + } + + public static LinesDrawable getInstance(float density) { + if (sInstance == null) { + sInstance = new LinesDrawable(density); + } + return sInstance; + } + + private LinesDrawable(float density) { + mWorkRect = new Rect(); + mMarginBounds = new Rect(); + mPaddingBounds = new Rect(); + mContentBounds = new Rect(); + + mDensity = density; + } + + public void setBounds(Rect marginBounds, Rect paddingBounds, Rect contentBounds) { + mMarginBounds.set(marginBounds); + mPaddingBounds.set(paddingBounds); + mContentBounds.set(contentBounds); + setBounds(marginBounds); + } + + @Override + public void draw(Canvas canvas) { + + Paint dashPaint = new Paint(); + dashPaint.setColor(0xFF800000); + dashPaint.setStyle(Paint.Style.STROKE); + dashPaint.setStrokeWidth(3); + dashPaint.setPathEffect(new DashPathEffect(new float[]{10, 10}, 0)); + + canvas.drawLine(mContentBounds.right, 0, mContentBounds.right, 100000, dashPaint); + canvas.drawLine(mContentBounds.left, 0, mContentBounds.left, 100000, dashPaint); + canvas.drawLine(0, mContentBounds.top, 100000, mContentBounds.top, dashPaint); + canvas.drawLine(0, mContentBounds.bottom, 100000, mContentBounds.bottom, dashPaint); + } + + @Override + public void setAlpha(int alpha) { + // No-op + } + + @Override + public void setColorFilter(ColorFilter colorFilter) { + // No-op + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } +}