1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.widget; 18 19 import static com.android.settings.DataUsageSummary.formatDateRange; 20 21 import android.content.Context; 22 import android.content.res.ColorStateList; 23 import android.content.res.Resources; 24 import android.content.res.TypedArray; 25 import android.graphics.Canvas; 26 import android.graphics.Paint; 27 import android.graphics.drawable.Drawable; 28 import android.text.Layout; 29 import android.text.StaticLayout; 30 import android.text.TextPaint; 31 import android.util.AttributeSet; 32 import android.util.Log; 33 import android.util.TypedValue; 34 import android.view.View; 35 36 import com.android.internal.util.Preconditions; 37 import com.android.settings.R; 38 39 import java.util.Locale; 40 41 /** 42 * Background of {@link ChartView} that renders grid lines as requested by 43 * {@link ChartAxis#getTickPoints()}. 44 */ 45 public class ChartGridView extends View { 46 47 private ChartAxis mHoriz; 48 private ChartAxis mVert; 49 50 private Drawable mPrimary; 51 private Drawable mSecondary; 52 private Drawable mBorder; 53 54 private int mLabelSize; 55 private int mLabelColor; 56 57 private Layout mLabelStart; 58 private Layout mLabelMid; 59 private Layout mLabelEnd; 60 ChartGridView(Context context)61 public ChartGridView(Context context) { 62 this(context, null, 0); 63 } 64 ChartGridView(Context context, AttributeSet attrs)65 public ChartGridView(Context context, AttributeSet attrs) { 66 this(context, attrs, 0); 67 } 68 ChartGridView(Context context, AttributeSet attrs, int defStyle)69 public ChartGridView(Context context, AttributeSet attrs, int defStyle) { 70 super(context, attrs, defStyle); 71 72 setWillNotDraw(false); 73 74 final TypedArray a = context.obtainStyledAttributes( 75 attrs, R.styleable.ChartGridView, defStyle, 0); 76 77 mPrimary = a.getDrawable(R.styleable.ChartGridView_primaryDrawable); 78 mSecondary = a.getDrawable(R.styleable.ChartGridView_secondaryDrawable); 79 mBorder = a.getDrawable(R.styleable.ChartGridView_borderDrawable); 80 81 final int taId = a.getResourceId(R.styleable.ChartGridView_android_textAppearance, -1); 82 final TypedArray ta = context.obtainStyledAttributes(taId, 83 com.android.internal.R.styleable.TextAppearance); 84 mLabelSize = ta.getDimensionPixelSize( 85 com.android.internal.R.styleable.TextAppearance_textSize, 0); 86 ta.recycle(); 87 88 final ColorStateList labelColor = a.getColorStateList( 89 R.styleable.ChartGridView_android_textColor); 90 mLabelColor = labelColor.getDefaultColor(); 91 92 a.recycle(); 93 } 94 init(ChartAxis horiz, ChartAxis vert)95 void init(ChartAxis horiz, ChartAxis vert) { 96 mHoriz = Preconditions.checkNotNull(horiz, "missing horiz"); 97 mVert = Preconditions.checkNotNull(vert, "missing vert"); 98 } 99 setBounds(long start, long end)100 void setBounds(long start, long end) { 101 final Context context = getContext(); 102 final long mid = (start + end) / 2; 103 mLabelStart = makeLabel(formatDateRange(context, start, start)); 104 mLabelMid = makeLabel(formatDateRange(context, mid, mid)); 105 mLabelEnd = makeLabel(formatDateRange(context, end, end)); 106 invalidate(); 107 } 108 109 @Override onDraw(Canvas canvas)110 protected void onDraw(Canvas canvas) { 111 final int width = getWidth(); 112 final int height = getHeight() - getPaddingBottom(); 113 114 final Drawable secondary = mSecondary; 115 if (secondary != null) { 116 final int secondaryHeight = secondary.getIntrinsicHeight(); 117 118 final float[] vertTicks = mVert.getTickPoints(); 119 for (float y : vertTicks) { 120 final int bottom = (int) Math.min(y + secondaryHeight, height); 121 secondary.setBounds(0, (int) y, width, bottom); 122 secondary.draw(canvas); 123 } 124 } 125 126 final Drawable primary = mPrimary; 127 if (primary != null) { 128 final int primaryWidth = primary.getIntrinsicWidth(); 129 final int primaryHeight = primary.getIntrinsicHeight(); 130 131 final float[] horizTicks = mHoriz.getTickPoints(); 132 for (float x : horizTicks) { 133 final int right = (int) Math.min(x + primaryWidth, width); 134 primary.setBounds((int) x, 0, right, height); 135 primary.draw(canvas); 136 } 137 } 138 139 mBorder.setBounds(0, 0, width, height); 140 mBorder.draw(canvas); 141 142 final int padding = mLabelStart != null ? mLabelStart.getHeight() / 8 : 0; 143 144 final Layout start = mLabelStart; 145 if (start != null) { 146 final int saveCount = canvas.save(); 147 canvas.translate(0, height + padding); 148 start.draw(canvas); 149 canvas.restoreToCount(saveCount); 150 } 151 152 final Layout mid = mLabelMid; 153 if (mid != null) { 154 final int saveCount = canvas.save(); 155 canvas.translate((width - mid.getWidth()) / 2, height + padding); 156 mid.draw(canvas); 157 canvas.restoreToCount(saveCount); 158 } 159 160 final Layout end = mLabelEnd; 161 if (end != null) { 162 final int saveCount = canvas.save(); 163 canvas.translate(width - end.getWidth(), height + padding); 164 end.draw(canvas); 165 canvas.restoreToCount(saveCount); 166 } 167 } 168 makeLabel(CharSequence text)169 private Layout makeLabel(CharSequence text) { 170 final Resources res = getResources(); 171 final TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG); 172 paint.density = res.getDisplayMetrics().density; 173 paint.setCompatibilityScaling(res.getCompatibilityInfo().applicationScale); 174 paint.setColor(mLabelColor); 175 paint.setTextSize(mLabelSize); 176 177 return new StaticLayout(text, paint, 178 (int) Math.ceil(Layout.getDesiredWidth(text, paint)), 179 Layout.Alignment.ALIGN_NORMAL, 1.f, 0, true); 180 } 181 } 182