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
17package com.android.settings.widget;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.content.res.TypedArray;
22import android.graphics.Canvas;
23import android.graphics.Color;
24import android.graphics.Paint;
25import android.graphics.drawable.Drawable;
26import android.text.Layout;
27import android.text.StaticLayout;
28import android.text.TextPaint;
29import android.util.AttributeSet;
30import android.util.TypedValue;
31import android.view.View;
32
33import com.android.settings.DataUsageSummary;
34import com.android.settings.R;
35import com.google.common.base.Preconditions;
36
37/**
38 * Background of {@link ChartView} that renders grid lines as requested by
39 * {@link ChartAxis#getTickPoints()}.
40 */
41public class ChartGridView extends View {
42
43    private ChartAxis mHoriz;
44    private ChartAxis mVert;
45
46    private Drawable mPrimary;
47    private Drawable mSecondary;
48    private Drawable mBorder;
49    private int mLabelColor;
50
51    private Layout mLayoutStart;
52    private Layout mLayoutEnd;
53
54    public ChartGridView(Context context) {
55        this(context, null, 0);
56    }
57
58    public ChartGridView(Context context, AttributeSet attrs) {
59        this(context, attrs, 0);
60    }
61
62    public ChartGridView(Context context, AttributeSet attrs, int defStyle) {
63        super(context, attrs, defStyle);
64
65        setWillNotDraw(false);
66
67        final TypedArray a = context.obtainStyledAttributes(
68                attrs, R.styleable.ChartGridView, defStyle, 0);
69
70        mPrimary = a.getDrawable(R.styleable.ChartGridView_primaryDrawable);
71        mSecondary = a.getDrawable(R.styleable.ChartGridView_secondaryDrawable);
72        mBorder = a.getDrawable(R.styleable.ChartGridView_borderDrawable);
73        mLabelColor = a.getColor(R.styleable.ChartGridView_labelColor, Color.RED);
74
75        a.recycle();
76    }
77
78    void init(ChartAxis horiz, ChartAxis vert) {
79        mHoriz = Preconditions.checkNotNull(horiz, "missing horiz");
80        mVert = Preconditions.checkNotNull(vert, "missing vert");
81    }
82
83    void setBounds(long start, long end) {
84        final Context context = getContext();
85        mLayoutStart = makeLayout(DataUsageSummary.formatDateRange(context, start, start, true));
86        mLayoutEnd = makeLayout(DataUsageSummary.formatDateRange(context, end, end, true));
87        invalidate();
88    }
89
90    @Override
91    protected void onDraw(Canvas canvas) {
92        final int width = getWidth();
93        final int height = getHeight();
94
95        final Drawable secondary = mSecondary;
96        final int secondaryHeight = mSecondary.getIntrinsicHeight();
97
98        final float[] vertTicks = mVert.getTickPoints();
99        for (float y : vertTicks) {
100            final int bottom = (int) Math.min(y + secondaryHeight, height);
101            secondary.setBounds(0, (int) y, width, bottom);
102            secondary.draw(canvas);
103        }
104
105        final Drawable primary = mPrimary;
106        final int primaryWidth = mPrimary.getIntrinsicWidth();
107        final int primaryHeight = mPrimary.getIntrinsicHeight();
108
109        final float[] horizTicks = mHoriz.getTickPoints();
110        for (float x : horizTicks) {
111            final int right = (int) Math.min(x + primaryWidth, width);
112            primary.setBounds((int) x, 0, right, height);
113            primary.draw(canvas);
114        }
115
116        mBorder.setBounds(0, 0, width, height);
117        mBorder.draw(canvas);
118
119        final int padding = mLayoutStart != null ? mLayoutStart.getHeight() / 8 : 0;
120
121        final Layout start = mLayoutStart;
122        if (start != null) {
123            canvas.save();
124            canvas.translate(0, height + padding);
125            start.draw(canvas);
126            canvas.restore();
127        }
128
129        final Layout end = mLayoutEnd;
130        if (end != null) {
131            canvas.save();
132            canvas.translate(width - end.getWidth(), height + padding);
133            end.draw(canvas);
134            canvas.restore();
135        }
136    }
137
138    private Layout makeLayout(CharSequence text) {
139        final Resources res = getResources();
140        final TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
141        paint.density = res.getDisplayMetrics().density;
142        paint.setCompatibilityScaling(res.getCompatibilityInfo().applicationScale);
143        paint.setColor(mLabelColor);
144        paint.setTextSize(
145                TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10, res.getDisplayMetrics()));
146
147        return new StaticLayout(text, paint,
148                (int) Math.ceil(Layout.getDesiredWidth(text, paint)),
149                Layout.Alignment.ALIGN_NORMAL, 1.f, 0, true);
150    }
151
152}
153