fbshipit-source-id: b6fc29740c6875d2e78953b8a7123890a67930f2 Co-authored-by: Sebastian McKenzie <sebmck@fb.com> Co-authored-by: John Knox <jknox@fb.com> Co-authored-by: Emil Sjölander <emilsj@fb.com> Co-authored-by: Pritesh Nandgaonkar <prit91@fb.com>
176 lines
5.4 KiB
Java
176 lines
5.4 KiB
Java
/*
|
|
* 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.PixelFormat;
|
|
import android.graphics.Rect;
|
|
import android.graphics.Region;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.text.TextPaint;
|
|
import javax.annotation.Nullable;
|
|
|
|
public class BoundsDrawable extends Drawable {
|
|
public static final int COLOR_HIGHLIGHT_CONTENT = 0x888875c5;
|
|
public static final int COLOR_HIGHLIGHT_PADDING = 0x889dd185;
|
|
public static final int COLOR_HIGHLIGHT_MARGIN = 0x88f7b77b;
|
|
private static @Nullable BoundsDrawable sInstance;
|
|
|
|
private final TextPaint mTextPaint;
|
|
private final Paint mMarginPaint;
|
|
private final Paint mPaddingPaint;
|
|
private final Paint mContentPaint;
|
|
private final Rect mWorkRect;
|
|
private final Rect mMarginBounds;
|
|
private final Rect mPaddingBounds;
|
|
private final Rect mContentBounds;
|
|
|
|
private final int mStrokeWidth;
|
|
private final float mAscentOffset;
|
|
private final float mDensity;
|
|
|
|
public static BoundsDrawable getInstance(
|
|
float density, Rect marginBounds, Rect paddingBounds, Rect contentBounds) {
|
|
final BoundsDrawable drawable = getInstance(density);
|
|
drawable.setBounds(marginBounds, paddingBounds, contentBounds);
|
|
return drawable;
|
|
}
|
|
|
|
public static BoundsDrawable getInstance(float density) {
|
|
if (sInstance == null) {
|
|
sInstance = new BoundsDrawable(density);
|
|
}
|
|
return sInstance;
|
|
}
|
|
|
|
private BoundsDrawable(float density) {
|
|
mWorkRect = new Rect();
|
|
mMarginBounds = new Rect();
|
|
mPaddingBounds = new Rect();
|
|
mContentBounds = new Rect();
|
|
|
|
mDensity = density;
|
|
|
|
mTextPaint = new TextPaint();
|
|
mTextPaint.setAntiAlias(true);
|
|
mTextPaint.setTextAlign(Paint.Align.CENTER);
|
|
mTextPaint.setTextSize(dpToPx(8f));
|
|
mAscentOffset = -mTextPaint.ascent() / 2f;
|
|
mStrokeWidth = dpToPx(2f);
|
|
|
|
mPaddingPaint = new Paint();
|
|
mPaddingPaint.setStyle(Paint.Style.FILL);
|
|
mPaddingPaint.setColor(COLOR_HIGHLIGHT_PADDING);
|
|
|
|
mContentPaint = new Paint();
|
|
mContentPaint.setStyle(Paint.Style.FILL);
|
|
mContentPaint.setColor(COLOR_HIGHLIGHT_CONTENT);
|
|
|
|
mMarginPaint = new Paint();
|
|
mMarginPaint.setStyle(Paint.Style.FILL);
|
|
mMarginPaint.setColor(COLOR_HIGHLIGHT_MARGIN);
|
|
}
|
|
|
|
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) {
|
|
canvas.drawRect(mContentBounds, mContentPaint);
|
|
|
|
int saveCount = canvas.save();
|
|
canvas.clipRect(mContentBounds, Region.Op.DIFFERENCE);
|
|
canvas.drawRect(mPaddingBounds, mPaddingPaint);
|
|
canvas.restoreToCount(saveCount);
|
|
|
|
saveCount = canvas.save();
|
|
canvas.clipRect(mPaddingBounds, Region.Op.DIFFERENCE);
|
|
canvas.drawRect(mMarginBounds, mMarginPaint);
|
|
canvas.restoreToCount(saveCount);
|
|
|
|
drawBoundsDimensions(canvas, mContentBounds);
|
|
|
|
// Disabled for now since Sonar doesn't support options too well at this point in time.
|
|
// Once options are supported, we should re-enable the calls below
|
|
// drawCardinalDimensionsBetween(canvas, mContentBounds, mPaddingBounds);
|
|
// drawCardinalDimensionsBetween(canvas, mPaddingBounds, mMarginBounds);
|
|
}
|
|
|
|
@Override
|
|
public void setAlpha(int alpha) {
|
|
// No-op
|
|
}
|
|
|
|
@Override
|
|
public void setColorFilter(ColorFilter colorFilter) {
|
|
// No-op
|
|
}
|
|
|
|
@Override
|
|
public int getOpacity() {
|
|
return PixelFormat.TRANSLUCENT;
|
|
}
|
|
|
|
private void drawCardinalDimensionsBetween(Canvas canvas, Rect inner, Rect outer) {
|
|
mWorkRect.set(inner);
|
|
mWorkRect.left = outer.left;
|
|
mWorkRect.right = inner.left;
|
|
drawBoundsDimension(canvas, mWorkRect, mWorkRect.width());
|
|
mWorkRect.left = inner.right;
|
|
mWorkRect.right = outer.right;
|
|
drawBoundsDimension(canvas, mWorkRect, mWorkRect.width());
|
|
mWorkRect.set(outer);
|
|
mWorkRect.bottom = inner.top;
|
|
drawBoundsDimension(canvas, mWorkRect, mWorkRect.height());
|
|
mWorkRect.bottom = outer.bottom;
|
|
mWorkRect.top = inner.bottom;
|
|
drawBoundsDimension(canvas, mWorkRect, mWorkRect.height());
|
|
}
|
|
|
|
private void drawBoundsDimension(Canvas canvas, Rect bounds, int value) {
|
|
if (value <= 0) {
|
|
return;
|
|
}
|
|
int saveCount = canvas.save();
|
|
canvas.translate(bounds.centerX(), bounds.centerY());
|
|
drawOutlinedText(canvas, value + "px");
|
|
canvas.restoreToCount(saveCount);
|
|
}
|
|
|
|
private void drawBoundsDimensions(Canvas canvas, Rect bounds) {
|
|
int saveCount = canvas.save();
|
|
canvas.translate(bounds.centerX(), bounds.centerY());
|
|
drawOutlinedText(canvas, bounds.width() + "px \u00D7 " + bounds.height() + "px");
|
|
canvas.restoreToCount(saveCount);
|
|
}
|
|
|
|
private void drawOutlinedText(Canvas canvas, String text) {
|
|
mTextPaint.setColor(Color.BLACK);
|
|
mTextPaint.setStrokeWidth(mStrokeWidth);
|
|
mTextPaint.setStyle(Paint.Style.STROKE);
|
|
canvas.drawText(text, 0f, mAscentOffset, mTextPaint);
|
|
|
|
mTextPaint.setColor(Color.WHITE);
|
|
mTextPaint.setStrokeWidth(0f);
|
|
mTextPaint.setStyle(Paint.Style.FILL);
|
|
canvas.drawText(text, 0f, mAscentOffset, mTextPaint);
|
|
}
|
|
|
|
private int dpToPx(float dp) {
|
|
return (int) (dp * mDensity);
|
|
}
|
|
}
|