BatteryMeterDrawableBase.java revision d866b8aa0341e960399c425b021b4a6aedfa5b9e
1597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei/* 2597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * Copyright (C) 2017 The Android Open Source Project 3597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * 4597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * Licensed under the Apache License, Version 2.0 (the "License"); 5597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * you may not use this file except in compliance with the License. 6597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * You may obtain a copy of the License at 7597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * 8597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * http://www.apache.org/licenses/LICENSE-2.0 9597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * 10597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * Unless required by applicable law or agreed to in writing, software 11597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * distributed under the License is distributed on an "AS IS" BASIS, 12597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * See the License for the specific language governing permissions and 14597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei * limitations under the License. 15597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei */ 16597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 17597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleipackage com.android.settingslib.graph; 18597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 19597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.animation.ArgbEvaluator; 20597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.annotation.Nullable; 21597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.content.Context; 22597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.content.res.Resources; 23597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.content.res.TypedArray; 24597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.graphics.Canvas; 25597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.graphics.Color; 26597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.graphics.ColorFilter; 27597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.graphics.Paint; 28597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.graphics.Path; 29597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.graphics.RectF; 30597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.graphics.Typeface; 31597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport android.graphics.drawable.Drawable; 3258be7a675b7aa505255f0c91fee755f8290e8363Jason Monkimport android.util.TypedValue; 3358be7a675b7aa505255f0c91fee755f8290e8363Jason Monk 34597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport com.android.settingslib.R; 35597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleiimport com.android.settingslib.Utils; 36597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 37597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyuleipublic class BatteryMeterDrawableBase extends Drawable { 38597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 39597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private static final float ASPECT_RATIO = 9.5f / 14.5f; 40597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei public static final String TAG = BatteryMeterDrawableBase.class.getSimpleName(); 41597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 42597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei protected final Context mContext; 43597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 446aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler private int mLevel = -1; 456aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler private boolean mPluggedIn; 466aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler private boolean mPowerSaveEnabled; 476aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler private boolean mShowPercent; 48597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 49597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private static final boolean SINGLE_DIGIT_PERCENT = false; 50597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 51597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private static final int FULL = 96; 52597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 53597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private static final float BOLT_LEVEL_THRESHOLD = 0.3f; // opaque bolt below this fraction 54597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 55597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final int[] mColors; 56597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final int mIntrinsicWidth; 57597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final int mIntrinsicHeight; 58597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 59597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private float mButtonHeightFraction; 60597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private float mSubpixelSmoothingLeft; 61597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private float mSubpixelSmoothingRight; 62597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final Paint mFramePaint, mBatteryPaint, mWarningTextPaint, mTextPaint, mBoltPaint, 63597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusPaint; 64597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private float mTextHeight, mWarningTextHeight; 65597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int mIconTint = Color.WHITE; 66d866b8aa0341e960399c425b021b4a6aedfa5b9eJason Monk private float mOldDarkIntensity = -1f; 67597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 68597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int mHeight; 69597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int mWidth; 70597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private String mWarningString; 71597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final int mCriticalLevel; 72597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int mChargeColor; 73597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final float[] mBoltPoints; 74597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final Path mBoltPath = new Path(); 75597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final float[] mPlusPoints; 76597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final Path mPlusPath = new Path(); 77597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 78597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final RectF mFrame = new RectF(); 79597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final RectF mButtonFrame = new RectF(); 80597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final RectF mBoltFrame = new RectF(); 81597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final RectF mPlusFrame = new RectF(); 82597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 83597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final Path mShapePath = new Path(); 84597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final Path mClipPath = new Path(); 85597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private final Path mTextPath = new Path(); 86597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 87597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int mDarkModeBackgroundColor; 88597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int mDarkModeFillColor; 89597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 90597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int mLightModeBackgroundColor; 91597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int mLightModeFillColor; 92597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 93597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei public BatteryMeterDrawableBase(Context context, int frameColor) { 94597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mContext = context; 95597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final Resources res = context.getResources(); 96597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei TypedArray levels = res.obtainTypedArray(R.array.batterymeter_color_levels); 97597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei TypedArray colors = res.obtainTypedArray(R.array.batterymeter_color_values); 98597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 99597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final int N = levels.length(); 100597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mColors = new int[2 * N]; 10158be7a675b7aa505255f0c91fee755f8290e8363Jason Monk for (int i=0; i < N; i++) { 102597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mColors[2 * i] = levels.getInt(i, 0); 10358be7a675b7aa505255f0c91fee755f8290e8363Jason Monk if (colors.getType(i) == TypedValue.TYPE_ATTRIBUTE) { 1047c8564e6adb259ddf8c5626c8f59079e2e32cb79Jason Monk mColors[2 * i + 1] = Utils.getColorAttr(context, colors.getThemeAttributeId(i, 0)); 10558be7a675b7aa505255f0c91fee755f8290e8363Jason Monk } else { 10658be7a675b7aa505255f0c91fee755f8290e8363Jason Monk mColors[2 * i + 1] = colors.getColor(i, 0); 10758be7a675b7aa505255f0c91fee755f8290e8363Jason Monk } 108597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 109597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei levels.recycle(); 110597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei colors.recycle(); 1116aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler 112597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mWarningString = context.getString(R.string.battery_meter_very_low_overlay_symbol); 113597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mCriticalLevel = mContext.getResources().getInteger( 114597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei com.android.internal.R.integer.config_criticalBatteryWarningLevel); 115597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mButtonHeightFraction = context.getResources().getFraction( 116597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei R.fraction.battery_button_height_fraction, 1, 1); 117597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mSubpixelSmoothingLeft = context.getResources().getFraction( 118597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei R.fraction.battery_subpixel_smoothing_left, 1, 1); 119597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mSubpixelSmoothingRight = context.getResources().getFraction( 120597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei R.fraction.battery_subpixel_smoothing_right, 1, 1); 121597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 122597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 123597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFramePaint.setColor(frameColor); 124597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFramePaint.setDither(true); 125597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFramePaint.setStrokeWidth(0); 126597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFramePaint.setStyle(Paint.Style.FILL_AND_STROKE); 127597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 128597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 129597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBatteryPaint.setDither(true); 130597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBatteryPaint.setStrokeWidth(0); 131597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBatteryPaint.setStyle(Paint.Style.FILL_AND_STROKE); 132597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 133597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 134597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei Typeface font = Typeface.create("sans-serif-condensed", Typeface.BOLD); 135597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mTextPaint.setTypeface(font); 136597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mTextPaint.setTextAlign(Paint.Align.CENTER); 137597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 138597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mWarningTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 139597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei font = Typeface.create("sans-serif", Typeface.BOLD); 140597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mWarningTextPaint.setTypeface(font); 141597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mWarningTextPaint.setTextAlign(Paint.Align.CENTER); 142597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (mColors.length > 1) { 143597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mWarningTextPaint.setColor(mColors[1]); 144597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 145597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 146597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mChargeColor = Utils.getDefaultColor(mContext, R.color.batterymeter_charge_color); 147597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 148597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 149597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltPaint.setColor(Utils.getDefaultColor(mContext, R.color.batterymeter_bolt_color)); 1506aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler mBoltPoints = loadPoints(res, R.array.batterymeter_bolt_points); 151597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 152597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusPaint = new Paint(mBoltPaint); 1536aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler mPlusPoints = loadPoints(res, R.array.batterymeter_plus_points); 154597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 155597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mDarkModeBackgroundColor = 156597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei Utils.getDefaultColor(mContext, R.color.dark_mode_icon_color_dual_tone_background); 157597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mDarkModeFillColor = 158597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei Utils.getDefaultColor(mContext, R.color.dark_mode_icon_color_dual_tone_fill); 159597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mLightModeBackgroundColor = 160597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei Utils.getDefaultColor(mContext, R.color.light_mode_icon_color_dual_tone_background); 161597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mLightModeFillColor = 162597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei Utils.getDefaultColor(mContext, R.color.light_mode_icon_color_dual_tone_fill); 163597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 164597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mIntrinsicWidth = context.getResources().getDimensionPixelSize(R.dimen.battery_width); 165597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mIntrinsicHeight = context.getResources().getDimensionPixelSize(R.dimen.battery_height); 166597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 167597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 168597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei @Override 169597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei public int getIntrinsicHeight() { 170597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return mIntrinsicHeight; 171597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 172597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 173597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei @Override 174597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei public int getIntrinsicWidth() { 175597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return mIntrinsicWidth; 176597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 177597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 1786aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler public void setShowPercent(boolean show) { 1796aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler mShowPercent = show; 180597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei postInvalidate(); 181597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 182597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 1836aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler public void setPluggedIn(boolean val) { 1846aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler mPluggedIn = val; 1856aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler postInvalidate(); 186597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 187597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 1886aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler public void setBatteryLevel(int val) { 1896aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler mLevel = val; 1906aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler postInvalidate(); 1916aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler } 1926aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler 1936aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler public void setPowerSave(boolean val) { 1946aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler mPowerSaveEnabled = val; 1956aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler postInvalidate(); 196597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 197597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 1986aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler // an approximation of View.postInvalidate() 1996aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler protected void postInvalidate() { 2006aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler unscheduleSelf(this::invalidateSelf); 2016aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler scheduleSelf(this::invalidateSelf, 0); 2026aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler } 2036aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler 2046aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler private static float[] loadPoints(Resources res, int pointArrayRes) { 2056aa6e6e640ddaea3272144aee68762dd17674773Dan Sandler final int[] pts = res.getIntArray(pointArrayRes); 206597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei int maxX = 0, maxY = 0; 207597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei for (int i = 0; i < pts.length; i += 2) { 208597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei maxX = Math.max(maxX, pts[i]); 209597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei maxY = Math.max(maxY, pts[i + 1]); 210597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 211597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float[] ptsF = new float[pts.length]; 212597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei for (int i = 0; i < pts.length; i += 2) { 213597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei ptsF[i] = (float) pts[i] / maxX; 214597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei ptsF[i + 1] = (float) pts[i + 1] / maxY; 215597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 216597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return ptsF; 217597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 218597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 219597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei @Override 220597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei public void setBounds(int left, int top, int right, int bottom) { 221597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei super.setBounds(left, top, right, bottom); 222597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mHeight = bottom - top; 223597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mWidth = right - left; 224597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mWarningTextPaint.setTextSize(mHeight * 0.75f); 225597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent; 226597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 227597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 228597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int getColorForLevel(int percent) { 229597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // If we are in power save mode, always use the normal color. 230597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (mPowerSaveEnabled) { 231597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return mColors[mColors.length - 1]; 232597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 233597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei int thresh, color = 0; 234597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei for (int i = 0; i < mColors.length; i += 2) { 235597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei thresh = mColors[i]; 236597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei color = mColors[i + 1]; 237597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (percent <= thresh) { 238597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 239597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // Respect tinting for "normal" level 240597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (i == mColors.length - 2) { 241597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return mIconTint; 242597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } else { 243597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return color; 244597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 245597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 246597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 247597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return color; 248597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 249597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 250597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei public void setDarkIntensity(float darkIntensity) { 251597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (darkIntensity == mOldDarkIntensity) { 252597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return; 253597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 254597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei int backgroundColor = getBackgroundColor(darkIntensity); 255597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei int fillColor = getFillColor(darkIntensity); 256597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei setColors(fillColor, backgroundColor); 257597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mOldDarkIntensity = darkIntensity; 258597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 259597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 260597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei public void setColors(int fillColor, int backgroundColor) { 261597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mIconTint = fillColor; 262597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFramePaint.setColor(backgroundColor); 263597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltPaint.setColor(fillColor); 264597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mChargeColor = fillColor; 265597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei invalidateSelf(); 266597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 267597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 268597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int getBackgroundColor(float darkIntensity) { 269597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return getColorForDarkIntensity( 270597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei darkIntensity, mLightModeBackgroundColor, mDarkModeBackgroundColor); 271597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 272597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 273597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int getFillColor(float darkIntensity) { 274597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return getColorForDarkIntensity( 275597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei darkIntensity, mLightModeFillColor, mDarkModeFillColor); 276597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 277597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 278597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei private int getColorForDarkIntensity(float darkIntensity, int lightColor, int darkColor) { 279597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return (int) ArgbEvaluator.getInstance().evaluate(darkIntensity, lightColor, darkColor); 280597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 281597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 282597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei @Override 283597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei public void draw(Canvas c) { 284597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final int level = mLevel; 285597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 286597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (level == -1) return; 287597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 288597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei float drawFrac = (float) level / 100f; 289597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final int height = mHeight; 290597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final int width = (int) (ASPECT_RATIO * mHeight); 291597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei int px = (mWidth - width) / 2; 292597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 293597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final int buttonHeight = (int) (height * mButtonHeightFraction); 294597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 295597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.set(0, 0, width, height); 296597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.offset(px, 0); 297597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 298597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // button-frame: area above the battery body 299597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mButtonFrame.set( 300597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.left + Math.round(width * 0.25f), 301597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.top, 302597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.right - Math.round(width * 0.25f), 303597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.top + buttonHeight); 304597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 305597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mButtonFrame.top += mSubpixelSmoothingLeft; 306597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mButtonFrame.left += mSubpixelSmoothingLeft; 307597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mButtonFrame.right -= mSubpixelSmoothingRight; 308597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 309597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // frame: battery body area 310597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.top += buttonHeight; 311597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.left += mSubpixelSmoothingLeft; 312597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.top += mSubpixelSmoothingLeft; 313597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.right -= mSubpixelSmoothingRight; 314597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.bottom -= mSubpixelSmoothingRight; 315597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 316597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // set the battery charging color 317597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBatteryPaint.setColor(mPluggedIn ? mChargeColor : getColorForLevel(level)); 318597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 319597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (level >= FULL) { 320597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei drawFrac = 1f; 321597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } else if (level <= mCriticalLevel) { 322597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei drawFrac = 0f; 323597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 324597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 325597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float levelTop = drawFrac == 1f ? mButtonFrame.top 326597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei : (mFrame.top + (mFrame.height() * (1f - drawFrac))); 327597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 328597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // define the battery shape 329597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.reset(); 330597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.moveTo(mButtonFrame.left, mButtonFrame.top); 331597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.lineTo(mButtonFrame.right, mButtonFrame.top); 332597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.lineTo(mButtonFrame.right, mFrame.top); 333597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.lineTo(mFrame.right, mFrame.top); 334597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.lineTo(mFrame.right, mFrame.bottom); 335597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.lineTo(mFrame.left, mFrame.bottom); 336597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.lineTo(mFrame.left, mFrame.top); 337597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.lineTo(mButtonFrame.left, mFrame.top); 338597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.lineTo(mButtonFrame.left, mButtonFrame.top); 339597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 340597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (mPluggedIn) { 341597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // define the bolt shape 342597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float bl = mFrame.left + mFrame.width() / 4f; 343597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float bt = mFrame.top + mFrame.height() / 6f; 344597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float br = mFrame.right - mFrame.width() / 4f; 345597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float bb = mFrame.bottom - mFrame.height() / 10f; 346597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (mBoltFrame.left != bl || mBoltFrame.top != bt 347597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei || mBoltFrame.right != br || mBoltFrame.bottom != bb) { 348597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltFrame.set(bl, bt, br, bb); 349597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltPath.reset(); 350597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltPath.moveTo( 351597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(), 352597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height()); 353597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei for (int i = 2; i < mBoltPoints.length; i += 2) { 354597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltPath.lineTo( 355597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltFrame.left + mBoltPoints[i] * mBoltFrame.width(), 356597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltFrame.top + mBoltPoints[i + 1] * mBoltFrame.height()); 357597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 358597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltPath.lineTo( 359597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(), 360597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height()); 361597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 362597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 363597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei float boltPct = (mBoltFrame.bottom - levelTop) / (mBoltFrame.bottom - mBoltFrame.top); 364597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei boltPct = Math.min(Math.max(boltPct, 0), 1); 365597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (boltPct <= BOLT_LEVEL_THRESHOLD) { 366597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // draw the bolt if opaque 367597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei c.drawPath(mBoltPath, mBoltPaint); 368597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } else { 369597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // otherwise cut the bolt out of the overall shape 370597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.op(mBoltPath, Path.Op.DIFFERENCE); 371597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 372597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } else if (mPowerSaveEnabled) { 373597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // define the plus shape 374597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float pw = mFrame.width() * 2 / 3; 375597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float pl = mFrame.left + (mFrame.width() - pw) / 2; 376597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float pt = mFrame.top + (mFrame.height() - pw) / 2; 377597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float pr = mFrame.right - (mFrame.width() - pw) / 2; 378597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float pb = mFrame.bottom - (mFrame.height() - pw) / 2; 379597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (mPlusFrame.left != pl || mPlusFrame.top != pt 380597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei || mPlusFrame.right != pr || mPlusFrame.bottom != pb) { 381597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusFrame.set(pl, pt, pr, pb); 382597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusPath.reset(); 383597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusPath.moveTo( 384597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusFrame.left + mPlusPoints[0] * mPlusFrame.width(), 385597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusFrame.top + mPlusPoints[1] * mPlusFrame.height()); 386597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei for (int i = 2; i < mPlusPoints.length; i += 2) { 387597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusPath.lineTo( 388597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusFrame.left + mPlusPoints[i] * mPlusFrame.width(), 389597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusFrame.top + mPlusPoints[i + 1] * mPlusFrame.height()); 390597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 391597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusPath.lineTo( 392597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusFrame.left + mPlusPoints[0] * mPlusFrame.width(), 393597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusFrame.top + mPlusPoints[1] * mPlusFrame.height()); 394597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 395597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 396597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei float boltPct = (mPlusFrame.bottom - levelTop) / (mPlusFrame.bottom - mPlusFrame.top); 397597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei boltPct = Math.min(Math.max(boltPct, 0), 1); 398597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (boltPct <= BOLT_LEVEL_THRESHOLD) { 399597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // draw the bolt if opaque 400597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei c.drawPath(mPlusPath, mPlusPaint); 401597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } else { 402597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // otherwise cut the bolt out of the overall shape 403597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.op(mPlusPath, Path.Op.DIFFERENCE); 404597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 405597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 406597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 407597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // compute percentage text 408597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei boolean pctOpaque = false; 409597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei float pctX = 0, pctY = 0; 410597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei String pctText = null; 411597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (!mPluggedIn && !mPowerSaveEnabled && level > mCriticalLevel && mShowPercent) { 412597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mTextPaint.setColor(getColorForLevel(level)); 413597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mTextPaint.setTextSize(height * 414597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei (SINGLE_DIGIT_PERCENT ? 0.75f 415597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei : (mLevel == 100 ? 0.38f : 0.5f))); 416597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mTextHeight = -mTextPaint.getFontMetrics().ascent; 417597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei pctText = String.valueOf(SINGLE_DIGIT_PERCENT ? (level / 10) : level); 418597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei pctX = mWidth * 0.5f; 419597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei pctY = (mHeight + mTextHeight) * 0.47f; 420597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei pctOpaque = levelTop > pctY; 421597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (!pctOpaque) { 422597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mTextPath.reset(); 423597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mTextPaint.getTextPath(pctText, 0, pctText.length(), pctX, pctY, mTextPath); 424597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // cut the percentage text out of the overall shape 425597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.op(mTextPath, Path.Op.DIFFERENCE); 426597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 427597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 428597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 429597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // draw the battery shape background 430597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei c.drawPath(mShapePath, mFramePaint); 431597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 432597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // draw the battery shape, clipped to charging level 433597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFrame.top = levelTop; 434597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mClipPath.reset(); 435597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mClipPath.addRect(mFrame, Path.Direction.CCW); 436597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mShapePath.op(mClipPath, Path.Op.INTERSECT); 437597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei c.drawPath(mShapePath, mBatteryPaint); 438597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 439597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (!mPluggedIn && !mPowerSaveEnabled) { 440597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei if (level <= mCriticalLevel) { 441597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // draw the warning text 442597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float x = mWidth * 0.5f; 443597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei final float y = (mHeight + mWarningTextHeight) * 0.48f; 444597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei c.drawText(mWarningString, x, y, mWarningTextPaint); 445597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } else if (pctOpaque) { 446597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // draw the percentage text 447597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei c.drawText(pctText, pctX, pctY, mTextPaint); 448597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 449597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 450597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 451597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 452597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei // Some stuff required by Drawable. 453597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei @Override 454597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei public void setAlpha(int alpha) { 455597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 456597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 457597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei @Override 458597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei public void setColorFilter(@Nullable ColorFilter colorFilter) { 459597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mFramePaint.setColorFilter(colorFilter); 460597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBatteryPaint.setColorFilter(colorFilter); 461597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mWarningTextPaint.setColorFilter(colorFilter); 462597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mBoltPaint.setColorFilter(colorFilter); 463597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei mPlusPaint.setColorFilter(colorFilter); 464597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 465597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei 466597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei @Override 467597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei public int getOpacity() { 468597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei return 0; 469597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei } 470597b10f6db2401f7685191f96e3aaedcbccc56b0jackqdyulei} 471