Home | History | Annotate | Download | only in storage
      1 /*
      2  * Copyright (C) 2014 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.tv.settings.device.storage;
     18 
     19 import android.graphics.Canvas;
     20 import android.graphics.ColorFilter;
     21 import android.graphics.Paint;
     22 import android.graphics.PixelFormat;
     23 import android.graphics.drawable.Drawable;
     24 import android.os.Parcel;
     25 import android.os.Parcelable;
     26 
     27 import java.util.ArrayList;
     28 
     29 /**
     30  * Draws a horizontal bar chart with colored slices, each represented by
     31  * {@link Entry}. Pulled from Android Settings App.
     32  */
     33 public class PercentageBarChart extends Drawable {
     34 
     35     public static class Entry implements Comparable<Entry>, Parcelable {
     36 
     37         final int order;
     38         final float percentage;
     39         final Paint paint;
     40 
     41         public Entry(int order, float percentage, int color) {
     42             this.order = order;
     43             this.percentage = percentage;
     44             this.paint = new Paint();
     45             this.paint.setColor(color);
     46             this.paint.setStyle(Paint.Style.FILL);
     47         }
     48 
     49         @Override
     50         public int compareTo(Entry another) {
     51             return order - another.order;
     52         }
     53 
     54         @Override
     55         public int describeContents() {
     56             return 0;
     57         }
     58 
     59         @Override
     60         public void writeToParcel(Parcel dest, int flags) {
     61             dest.writeInt(order);
     62             dest.writeFloat(percentage);
     63             dest.writeInt(paint.getColor());
     64         }
     65 
     66         public static final Parcelable.Creator<Entry> CREATOR = new Parcelable.Creator<Entry>() {
     67             @Override
     68             public Entry createFromParcel(Parcel in) {
     69                 return new Entry(in.readInt(), in.readFloat(), in.readInt());
     70             }
     71 
     72             @Override
     73             public Entry[] newArray(int size) {
     74                 return new Entry[size];
     75             }
     76         };
     77     }
     78 
     79     private final ArrayList<Entry> mEntries;
     80     private final int mBackgroundColor;
     81     private final int mMinTickWidth;
     82     private final int mWidth;
     83     private final int mHeight;
     84     private final boolean mIsLayoutRtl;
     85     private final Paint mEmptyPaint;
     86 
     87     public PercentageBarChart(ArrayList<Entry> entries, int backgroundColor, int minTickWidth,
     88             int width, int height, boolean isLayoutRtl) {
     89         super();
     90         mEntries = entries;
     91         mBackgroundColor = backgroundColor;
     92         mMinTickWidth = minTickWidth;
     93         mWidth = width;
     94         mHeight = height;
     95         mIsLayoutRtl = isLayoutRtl;
     96         mEmptyPaint = new Paint();
     97         mEmptyPaint.setColor(backgroundColor);
     98         mEmptyPaint.setStyle(Paint.Style.FILL);
     99     }
    100 
    101     @Override
    102     public int getIntrinsicHeight() {
    103         return mHeight;
    104     }
    105 
    106     @Override
    107     public int getIntrinsicWidth() {
    108         return mWidth;
    109     }
    110 
    111     @Override
    112     public void draw(Canvas canvas) {
    113         mEmptyPaint.setColor(mBackgroundColor);
    114 
    115         float end = (mIsLayoutRtl) ? 0 : mWidth;
    116         float lastX = (mIsLayoutRtl) ? mWidth : 0;
    117 
    118         for (final Entry e : mEntries) {
    119             if (e.percentage == 0.0f) {
    120                 continue;
    121             }
    122 
    123             final float entryWidth = Math.max(mMinTickWidth, mWidth * e.percentage);
    124 
    125             // progress toward the end.
    126             final float nextX = lastX + ((lastX < end) ? entryWidth : -entryWidth);
    127 
    128             // if we've hit the limit, stop drawing.
    129             if (drawEntry(canvas, lastX, nextX, e.paint)) {
    130                 return;
    131             }
    132             lastX = nextX;
    133         }
    134 
    135         drawEntry(canvas, lastX, end, mEmptyPaint);
    136     }
    137 
    138     @Override
    139     public void setAlpha(int alpha) {
    140     }
    141 
    142     @Override
    143     public void setColorFilter(ColorFilter cf) {
    144     }
    145 
    146     @Override
    147     public int getOpacity() {
    148         return PixelFormat.OPAQUE;
    149     }
    150 
    151     /**
    152      * Draws a rectangle from the lesser of the two x inputs to the greater of
    153      * the two. If either of the two x inputs lie outside the bounds of this
    154      * drawable, limit the rectangle drawn to the bounds.
    155      *
    156      * @param canvas the canvas to draw to.
    157      * @param x1 the first x input. This may be greater or smaller than x2.
    158      * @param x2 the second x input. This may be greater or smaller than x1.
    159      * @param paint the color to draw.
    160      * @return true if either of the x inputs was beyond the bounds of this
    161      *         drawable, false otherwise.
    162      */
    163     private boolean drawEntry(Canvas canvas, float x1, float x2, Paint paint) {
    164         boolean hitLimit = false;
    165         float left = x1 > x2 ? x2 : x1;
    166         float right = x1 > x2 ? x1 : x2;
    167         if (left < 0) {
    168             left = 0;
    169             hitLimit = true;
    170         }
    171         if (right > mWidth) {
    172             right = mWidth;
    173             hitLimit = true;
    174         }
    175         canvas.drawRect(left, 0, right, mHeight, paint);
    176         return hitLimit;
    177     }
    178 }
    179