Data usage axis grow/shrink, other fixes.
When dragging vertical sweeps near edges, grow or shrink axis scale
to give users access to larger limits. Triggers 10% for each 250ms
that user continues holding. Change axis math to support arbitrary
ranges beyond [0,5GB].
Show "empty" message when no application details found. Added strings
that didn't appear in default language. Better sweep margins using
dip instead of scale units. Format time ranges in local time instead
of UTC. Only show dashed estimate when it would reach near warning
or limit. Extend app usage series until "now" when buckets missing.
Bug: 5096685, 5092538, 5058158, 5058114, 5058024, 4643457
Change-Id: I45cf33f7f3baeba1bfa5b21f31cb0a12006f62fa
diff --git a/src/com/android/settings/widget/ChartSweepView.java b/src/com/android/settings/widget/ChartSweepView.java
index 99c35bd..b5e044f 100644
--- a/src/com/android/settings/widget/ChartSweepView.java
+++ b/src/com/android/settings/widget/ChartSweepView.java
@@ -29,6 +29,7 @@
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.MathUtils;
import android.view.MotionEvent;
import android.view.View;
@@ -48,6 +49,7 @@
private Point mSweepOffset = new Point();
private Rect mMargins = new Rect();
+ private float mNeighborMargin;
private int mFollowAxis;
@@ -65,7 +67,6 @@
private long mValidBefore;
private ChartSweepView mValidAfterDynamic;
private ChartSweepView mValidBeforeDynamic;
- private long mValidBufferArea;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
@@ -93,6 +94,7 @@
setSweepDrawable(a.getDrawable(R.styleable.ChartSweepView_sweepDrawable));
setFollowAxis(a.getInt(R.styleable.ChartSweepView_followAxis, -1));
+ setNeighborMargin(a.getDimensionPixelSize(R.styleable.ChartSweepView_neighborMargin, 0));
setLabelSize(a.getDimensionPixelSize(R.styleable.ChartSweepView_labelSize, 0));
setLabelTemplate(a.getResourceId(R.styleable.ChartSweepView_labelTemplate, 0));
@@ -271,16 +273,18 @@
mValidBefore = validBefore;
}
+ public void setNeighborMargin(float neighborMargin) {
+ mNeighborMargin = neighborMargin;
+ }
+
/**
* Set valid range this sweep can move within, defined by the given
* {@link ChartSweepView}. The most restrictive combination of all valid
* ranges is used.
*/
- public void setValidRangeDynamic(
- ChartSweepView validAfter, ChartSweepView validBefore, long bufferArea) {
+ public void setValidRangeDynamic(ChartSweepView validAfter, ChartSweepView validBefore) {
mValidAfterDynamic = validAfter;
mValidBeforeDynamic = validBefore;
- mValidBufferArea = bufferArea;
}
@Override
@@ -316,9 +320,7 @@
getParent().requestDisallowInterceptTouchEvent(true);
// content area of parent
- final Rect parentContent = new Rect(parent.getPaddingLeft(), parent.getPaddingTop(),
- parent.getWidth() - parent.getPaddingRight(),
- parent.getHeight() - parent.getPaddingBottom());
+ final Rect parentContent = getParentContentRect();
final Rect clampRect = computeClampRect(parentContent);
if (mFollowAxis == VERTICAL) {
@@ -358,6 +360,33 @@
}
}
+ /**
+ * Update {@link #mValue} based on current position, including any
+ * {@link #onTouchEvent(MotionEvent)} in progress. Typically used when
+ * {@link ChartAxis} changes during sweep adjustment.
+ */
+ public void updateValueFromPosition() {
+ final Rect parentContent = getParentContentRect();
+ if (mFollowAxis == VERTICAL) {
+ final float effectiveY = getY() - mMargins.top - parentContent.top;
+ setValue(mAxis.convertToValue(effectiveY));
+ } else {
+ final float effectiveX = getX() - mMargins.left - parentContent.left;
+ setValue(mAxis.convertToValue(effectiveX));
+ }
+ }
+
+ public int shouldAdjustAxis() {
+ return mAxis.shouldAdjustAxis(getValue());
+ }
+
+ private Rect getParentContentRect() {
+ final View parent = (View) getParent();
+ return new Rect(parent.getPaddingLeft(), parent.getPaddingTop(),
+ parent.getWidth() - parent.getPaddingRight(),
+ parent.getHeight() - parent.getPaddingBottom());
+ }
+
@Override
public void addOnLayoutChangeListener(OnLayoutChangeListener listener) {
// ignored to keep LayoutTransition from animating us
@@ -368,18 +397,14 @@
// ignored to keep LayoutTransition from animating us
}
- private long getValidAfterValue() {
+ private long getValidAfterDynamic() {
final ChartSweepView dynamic = mValidAfterDynamic;
- final boolean dynamicEnabled = dynamic != null && dynamic.isEnabled();
- return Math.max(mValidAfter,
- dynamicEnabled ? dynamic.getValue() + mValidBufferArea : Long.MIN_VALUE);
+ return dynamic != null && dynamic.isEnabled() ? dynamic.getValue() : Long.MIN_VALUE;
}
- private long getValidBeforeValue() {
+ private long getValidBeforeDynamic() {
final ChartSweepView dynamic = mValidBeforeDynamic;
- final boolean dynamicEnabled = dynamic != null && dynamic.isEnabled();
- return Math.min(mValidBefore,
- dynamicEnabled ? dynamic.getValue() - mValidBufferArea : Long.MAX_VALUE);
+ return dynamic != null && dynamic.isEnabled() ? dynamic.getValue() : Long.MAX_VALUE;
}
/**
@@ -388,22 +413,36 @@
* style rules.
*/
private Rect computeClampRect(Rect parentContent) {
- final Rect clampRect = new Rect(parentContent);
+ // create two rectangles, and pick most restrictive combination
+ final Rect rect = buildClampRect(parentContent, mValidAfter, mValidBefore, 0f);
+ final Rect dynamicRect = buildClampRect(
+ parentContent, getValidAfterDynamic(), getValidBeforeDynamic(), mNeighborMargin);
- float validAfterPoint = mAxis.convertToPoint(getValidAfterValue());
- float validBeforePoint = mAxis.convertToPoint(getValidBeforeValue());
- if (validAfterPoint > validBeforePoint) {
- float swap = validBeforePoint;
- validBeforePoint = validAfterPoint;
- validAfterPoint = swap;
+ rect.intersect(dynamicRect);
+ return rect;
+ }
+
+ private Rect buildClampRect(
+ Rect parentContent, long afterValue, long beforeValue, float margin) {
+ if (mAxis instanceof InvertedChartAxis) {
+ long temp = beforeValue;
+ beforeValue = afterValue;
+ afterValue = temp;
}
+ final boolean afterValid = afterValue != Long.MIN_VALUE && afterValue != Long.MAX_VALUE;
+ final boolean beforeValid = beforeValue != Long.MIN_VALUE && beforeValue != Long.MAX_VALUE;
+
+ final float afterPoint = mAxis.convertToPoint(afterValue) + margin;
+ final float beforePoint = mAxis.convertToPoint(beforeValue) - margin;
+
+ final Rect clampRect = new Rect(parentContent);
if (mFollowAxis == VERTICAL) {
- clampRect.bottom = clampRect.top + (int) validBeforePoint;
- clampRect.top += validAfterPoint;
+ if (beforeValid) clampRect.bottom = clampRect.top + (int) beforePoint;
+ if (afterValid) clampRect.top += afterPoint;
} else {
- clampRect.right = clampRect.left + (int) validBeforePoint;
- clampRect.left += validAfterPoint;
+ if (beforeValid) clampRect.right = clampRect.left + (int) beforePoint;
+ if (afterValid) clampRect.left += afterPoint;
}
return clampRect;
}