Data usage strings, sweep touches, fixes.

Change strings around limiting background data.  Move limit/warning
sweeps above inspection sweeps, and teach about additional neighbors
on different axis.

Guard against DialogFragment.show(), fix pie chart to draw edges, and
remove data usage from battery UI.

Bug: 5341374, 5337650, 5337385, 5319465, 5236335
Change-Id: Iea8c2a2ab405b645d85abe34a0178d4b8874cdd5
This commit is contained in:
Jeff Sharkey
2011-09-25 18:22:48 -07:00
parent 2407efcf42
commit 461842a8c0
7 changed files with 174 additions and 98 deletions

View File

@@ -120,6 +120,12 @@ public class ChartDataUsageView extends ChartView {
mSweepWarning.setValidRangeDynamic(null, mSweepLimit);
mSweepLimit.setValidRangeDynamic(mSweepWarning, null);
// mark neighbors for checking touch events against
mSweepLeft.setNeighbors(mSweepRight);
mSweepRight.setNeighbors(mSweepLeft);
mSweepLimit.setNeighbors(mSweepWarning, mSweepLeft, mSweepRight);
mSweepWarning.setNeighbors(mSweepLimit, mSweepLeft, mSweepRight);
mSweepLeft.addOnSweepListener(mHorizListener);
mSweepRight.addOnSweepListener(mHorizListener);
mSweepWarning.addOnSweepListener(mVertListener);
@@ -375,12 +381,12 @@ public class ChartDataUsageView extends ChartView {
return mSweepLimit.getLabelValue();
}
private long getStatsStart() {
return mHistory != null ? mHistory.getStart() : Long.MIN_VALUE;
private long getHistoryStart() {
return mHistory != null ? mHistory.getStart() : Long.MAX_VALUE;
}
private long getStatsEnd() {
return mHistory != null ? mHistory.getEnd() : Long.MAX_VALUE;
private long getHistoryEnd() {
return mHistory != null ? mHistory.getEnd() : Long.MIN_VALUE;
}
/**
@@ -394,8 +400,13 @@ public class ChartDataUsageView extends ChartView {
mSeries.setBounds(visibleStart, visibleEnd);
mDetailSeries.setBounds(visibleStart, visibleEnd);
final long validStart = Math.max(visibleStart, getStatsStart());
final long validEnd = Math.min(visibleEnd, getStatsEnd());
final long historyStart = getHistoryStart();
final long historyEnd = getHistoryEnd();
final long validStart = historyStart == Long.MAX_VALUE ? visibleStart
: Math.max(visibleStart, historyStart);
final long validEnd = historyEnd == Long.MIN_VALUE ? visibleEnd
: Math.min(visibleEnd, historyEnd);
if (LIMIT_SWEEPS_TO_VALID_DATA) {
// prevent time sweeps from leaving valid data

View File

@@ -101,6 +101,8 @@ public class ChartSweepView extends View {
private float mTrackingStart;
private MotionEvent mTracking;
private ChartSweepView[] mNeighbors = new ChartSweepView[0];
public ChartSweepView(Context context) {
this(context, null);
}
@@ -149,6 +151,10 @@ public class ChartSweepView extends View {
mAxis = Preconditions.checkNotNull(axis, "missing axis");
}
public void setNeighbors(ChartSweepView... neighbors) {
mNeighbors = neighbors;
}
public int getFollowAxis() {
return mFollowAxis;
}
@@ -381,18 +387,16 @@ public class ChartSweepView extends View {
* {@link ChartSweepView} compared to ourselves.
*/
public boolean isTouchCloserTo(MotionEvent eventInParent, ChartSweepView another) {
if (another == null) return false;
final float selfDist = getTouchDistanceFromTarget(eventInParent);
final float anotherDist = another.getTouchDistanceFromTarget(eventInParent);
return anotherDist < selfDist;
}
private float getTouchDistanceFromTarget(MotionEvent eventInParent) {
if (mFollowAxis == HORIZONTAL) {
final float selfDist = Math.abs(eventInParent.getX() - (getX() + getTargetInset()));
final float anotherDist = Math.abs(
eventInParent.getX() - (another.getX() + another.getTargetInset()));
return anotherDist < selfDist;
return Math.abs(eventInParent.getX() - (getX() + getTargetInset()));
} else {
final float selfDist = Math.abs(eventInParent.getY() - (getY() + getTargetInset()));
final float anotherDist = Math.abs(
eventInParent.getY() - (another.getY() + another.getTargetInset()));
return anotherDist < selfDist;
return Math.abs(eventInParent.getY() - (getY() + getTargetInset()));
}
}
@@ -421,9 +425,10 @@ public class ChartSweepView extends View {
eventInParent.offsetLocation(getLeft(), getTop());
// ignore event when closer to a neighbor
if (isTouchCloserTo(eventInParent, mValidAfterDynamic)
|| isTouchCloserTo(eventInParent, mValidBeforeDynamic)) {
return false;
for (ChartSweepView neighbor : mNeighbors) {
if (isTouchCloserTo(eventInParent, neighbor)) {
return false;
}
}
if (acceptDrag) {

View File

@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
@@ -42,31 +43,34 @@ public class PieChartView extends View {
public static final String TAG = "PieChartView";
public static final boolean LOGD = false;
private static final boolean FILL_GRADIENT = false;
private ArrayList<Slice> mSlices = Lists.newArrayList();
private int mOriginAngle;
private Matrix mMatrix = new Matrix();
private Paint mPaintPrimary = new Paint();
private Paint mPaintShadow = new Paint();
private Paint mPaintOutline = new Paint();
private Path mPathSide = new Path();
private Path mPathSideShadow = new Path();
private Path mPathSideOutline = new Path();
private Path mPathShadow = new Path();
private Path mPathOutline = new Path();
private int mSideWidth;
public class Slice {
public long value;
public Path pathPrimary = new Path();
public Path pathShadow = new Path();
public Path path = new Path();
public Path pathSide = new Path();
public Path pathOutline = new Path();
public Paint paintPrimary;
public Paint paint;
public Slice(long value, int color) {
this.value = value;
this.paintPrimary = buildFillPaint(color, getResources());
this.paint = buildFillPaint(color, getResources());
}
}
@@ -81,12 +85,10 @@ public class PieChartView extends View {
public PieChartView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mPaintPrimary = buildFillPaint(Color.parseColor("#666666"), getResources());
mPaintShadow.setColor(Color.BLACK);
mPaintShadow.setStyle(Style.STROKE);
mPaintShadow.setStrokeWidth(3f * getResources().getDisplayMetrics().density);
mPaintShadow.setAntiAlias(true);
mPaintOutline.setColor(Color.BLACK);
mPaintOutline.setStyle(Style.STROKE);
mPaintOutline.setStrokeWidth(3f * getResources().getDisplayMetrics().density);
mPaintOutline.setAntiAlias(true);
mSideWidth = (int) (20 * getResources().getDisplayMetrics().density);
@@ -100,8 +102,10 @@ public class PieChartView extends View {
paint.setStyle(Style.FILL_AND_STROKE);
paint.setAntiAlias(true);
final int width = (int) (280 * res.getDisplayMetrics().density);
paint.setShader(new RadialGradient(0, 0, width, color, darken(color), TileMode.MIRROR));
if (FILL_GRADIENT) {
final int width = (int) (280 * res.getDisplayMetrics().density);
paint.setShader(new RadialGradient(0, 0, width, color, darken(color), TileMode.MIRROR));
}
return paint;
}
@@ -120,6 +124,13 @@ public class PieChartView extends View {
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
final float centerX = getWidth() / 2;
final float centerY = getHeight() / 2;
mMatrix.reset();
mMatrix.postScale(0.665f, 0.95f, centerX, centerY);
mMatrix.postRotate(-40, centerX, centerY);
generatePath();
}
@@ -128,14 +139,15 @@ public class PieChartView extends View {
long total = 0;
for (Slice slice : mSlices) {
slice.pathPrimary.reset();
slice.pathShadow.reset();
slice.path.reset();
slice.pathSide.reset();
slice.pathOutline.reset();
total += slice.value;
}
mPathSide.reset();
mPathSideShadow.reset();
mPathShadow.reset();
mPathSideOutline.reset();
mPathOutline.reset();
// bail when not enough stats to render
if (total == 0) {
@@ -147,23 +159,56 @@ public class PieChartView extends View {
final int height = getHeight();
final RectF rect = new RectF(0, 0, width, height);
final RectF rectSide = new RectF();
rectSide.set(rect);
rectSide.offset(-mSideWidth, 0);
mPathSide.addOval(rect, Direction.CW);
mPathSideShadow.addOval(rect, Direction.CW);
mPathShadow.addOval(rect, Direction.CW);
mPathSide.addOval(rectSide, Direction.CW);
mPathSideOutline.addOval(rectSide, Direction.CW);
mPathOutline.addOval(rect, Direction.CW);
int startAngle = mOriginAngle;
for (Slice slice : mSlices) {
final int sweepAngle = (int) (slice.value * 360 / total);
final int endAngle = startAngle + sweepAngle;
slice.pathPrimary.moveTo(rect.centerX(), rect.centerY());
slice.pathPrimary.arcTo(rect, startAngle, sweepAngle);
slice.pathPrimary.lineTo(rect.centerX(), rect.centerY());
final float startAngleMod = startAngle % 360;
final float endAngleMod = endAngle % 360;
final boolean startSideVisible = startAngleMod > 90 && startAngleMod < 270;
final boolean endSideVisible = endAngleMod > 90 && endAngleMod < 270;
slice.pathShadow.moveTo(rect.centerX(), rect.centerY());
slice.pathShadow.arcTo(rect, startAngle, 0);
slice.pathShadow.moveTo(rect.centerX(), rect.centerY());
slice.pathShadow.arcTo(rect, startAngle + sweepAngle, 0);
// draw slice
slice.path.moveTo(rect.centerX(), rect.centerY());
slice.path.arcTo(rect, startAngle, sweepAngle);
slice.path.lineTo(rect.centerX(), rect.centerY());
if (startSideVisible || endSideVisible) {
// when start is beyond horizon, push until visible
final float startAngleSide = startSideVisible ? startAngle : 450;
final float endAngleSide = endSideVisible ? endAngle : 270;
final float sweepAngleSide = endAngleSide - startAngleSide;
// draw slice side
slice.pathSide.moveTo(rect.centerX(), rect.centerY());
slice.pathSide.arcTo(rect, startAngleSide, 0);
slice.pathSide.rLineTo(-mSideWidth, 0);
slice.pathSide.arcTo(rectSide, startAngleSide, sweepAngleSide);
slice.pathSide.rLineTo(mSideWidth, 0);
slice.pathSide.arcTo(rect, endAngleSide, -sweepAngleSide);
}
// draw slice outline
slice.pathOutline.moveTo(rect.centerX(), rect.centerY());
slice.pathOutline.arcTo(rect, startAngle, 0);
if (startSideVisible) {
slice.pathOutline.rLineTo(-mSideWidth, 0);
}
slice.pathOutline.moveTo(rect.centerX(), rect.centerY());
slice.pathOutline.arcTo(rect, startAngle + sweepAngle, 0);
if (endSideVisible) {
slice.pathOutline.rLineTo(-mSideWidth, 0);
}
startAngle += sweepAngle;
}
@@ -174,21 +219,18 @@ public class PieChartView extends View {
@Override
protected void onDraw(Canvas canvas) {
canvas.translate(getWidth() * 0.25f, getHeight() * -0.05f);
canvas.rotate(-40, getWidth() * 0.5f, getHeight());
canvas.scale(0.7f, 1.0f, getWidth(), getHeight());
canvas.save();
canvas.translate(-mSideWidth, 0);
canvas.drawPath(mPathSide, mPaintPrimary);
canvas.drawPath(mPathSideShadow, mPaintShadow);
canvas.restore();
canvas.concat(mMatrix);
for (Slice slice : mSlices) {
canvas.drawPath(slice.pathPrimary, slice.paintPrimary);
canvas.drawPath(slice.pathShadow, mPaintShadow);
canvas.drawPath(slice.pathSide, slice.paint);
}
canvas.drawPath(mPathShadow, mPaintShadow);
canvas.drawPath(mPathSideOutline, mPaintOutline);
for (Slice slice : mSlices) {
canvas.drawPath(slice.path, slice.paint);
canvas.drawPath(slice.pathOutline, mPaintOutline);
}
canvas.drawPath(mPathOutline, mPaintOutline);
}
public static int darken(int color) {