Home | History | Annotate | Download | only in applications
      1 /**
      2  *
      3  */
      4 package com.android.settings.applications;
      5 
      6 import android.content.Context;
      7 import android.graphics.Canvas;
      8 import android.graphics.LinearGradient;
      9 import android.graphics.Paint;
     10 import android.graphics.Path;
     11 import android.graphics.Rect;
     12 import android.graphics.Shader;
     13 import android.util.AttributeSet;
     14 import android.util.DisplayMetrics;
     15 import android.view.MotionEvent;
     16 import android.widget.LinearLayout;
     17 import com.android.settings.Utils;
     18 
     19 public class LinearColorBar extends LinearLayout {
     20 
     21     static final int RIGHT_COLOR = 0xffced7db;
     22     static final int GRAY_COLOR = 0xff555555;
     23     static final int WHITE_COLOR = 0xffffffff;
     24 
     25     private float mRedRatio;
     26     private float mYellowRatio;
     27     private float mGreenRatio;
     28 
     29     private int mLeftColor;
     30     private int mMiddleColor;
     31     private int mRightColor = RIGHT_COLOR;
     32 
     33     private boolean mShowIndicator = true;
     34     private boolean mShowingGreen;
     35 
     36     private OnRegionTappedListener mOnRegionTappedListener;
     37     private int mColoredRegions = REGION_RED | REGION_YELLOW | REGION_GREEN;
     38 
     39     final Rect mRect = new Rect();
     40     final Paint mPaint = new Paint();
     41 
     42     int mLastInterestingLeft, mLastInterestingRight;
     43     int mLineWidth;
     44 
     45     int mLastLeftDiv, mLastRightDiv;
     46     int mLastRegion;
     47 
     48     final Path mColorPath = new Path();
     49     final Path mEdgePath = new Path();
     50     final Paint mColorGradientPaint = new Paint();
     51     final Paint mEdgeGradientPaint = new Paint();
     52 
     53     public static final int REGION_RED = 1<<0;
     54     public static final int REGION_YELLOW = 1<<1;
     55     public static final int REGION_GREEN = 1<<2;
     56     public static final int REGION_ALL = REGION_RED | REGION_YELLOW | REGION_GREEN;
     57 
     58     public interface OnRegionTappedListener {
     59         public void onRegionTapped(int region);
     60     }
     61 
     62     public LinearColorBar(Context context, AttributeSet attrs) {
     63         super(context, attrs);
     64         setWillNotDraw(false);
     65         mPaint.setStyle(Paint.Style.FILL);
     66         mColorGradientPaint.setStyle(Paint.Style.FILL);
     67         mColorGradientPaint.setAntiAlias(true);
     68         mEdgeGradientPaint.setStyle(Paint.Style.STROKE);
     69         mLineWidth = getResources().getDisplayMetrics().densityDpi >= DisplayMetrics.DENSITY_HIGH
     70                 ? 2 : 1;
     71         mEdgeGradientPaint.setStrokeWidth(mLineWidth);
     72         mEdgeGradientPaint.setAntiAlias(true);
     73         mLeftColor = mMiddleColor = Utils.getColorAccent(context);
     74     }
     75 
     76     public void setOnRegionTappedListener(OnRegionTappedListener listener) {
     77         if (listener != mOnRegionTappedListener) {
     78             mOnRegionTappedListener = listener;
     79             setClickable(listener != null);
     80         }
     81     }
     82 
     83     public void setColoredRegions(int regions) {
     84         mColoredRegions = regions;
     85         invalidate();
     86     }
     87 
     88     public void setRatios(float red, float yellow, float green) {
     89         mRedRatio = red;
     90         mYellowRatio = yellow;
     91         mGreenRatio = green;
     92         invalidate();
     93     }
     94 
     95     public void setColors(int red, int yellow, int green) {
     96         mLeftColor = red;
     97         mMiddleColor = yellow;
     98         mRightColor = green;
     99         updateIndicator();
    100         invalidate();
    101     }
    102 
    103     public void setShowIndicator(boolean showIndicator) {
    104         mShowIndicator = showIndicator;
    105         updateIndicator();
    106         invalidate();
    107     }
    108 
    109     public void setShowingGreen(boolean showingGreen) {
    110         if (mShowingGreen != showingGreen) {
    111             mShowingGreen = showingGreen;
    112             updateIndicator();
    113             invalidate();
    114         }
    115     }
    116 
    117     private void updateIndicator() {
    118         int off = getPaddingTop() - getPaddingBottom();
    119         if (off < 0) off = 0;
    120         mRect.top = off;
    121         mRect.bottom = getHeight();
    122         if (!mShowIndicator) {
    123             return;
    124         }
    125         if (mShowingGreen) {
    126             mColorGradientPaint.setShader(new LinearGradient(
    127                     0, 0, 0, off-2, mRightColor &0xffffff, mRightColor, Shader.TileMode.CLAMP));
    128         } else {
    129             mColorGradientPaint.setShader(new LinearGradient(
    130                     0, 0, 0, off-2, mMiddleColor&0xffffff, mMiddleColor, Shader.TileMode.CLAMP));
    131         }
    132         mEdgeGradientPaint.setShader(new LinearGradient(
    133                 0, 0, 0, off/2, 0x00a0a0a0, 0xffa0a0a0, Shader.TileMode.CLAMP));
    134     }
    135 
    136     @Override
    137     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    138         super.onSizeChanged(w, h, oldw, oldh);
    139         updateIndicator();
    140     }
    141 
    142     @Override
    143     public boolean onTouchEvent(MotionEvent event) {
    144         if (mOnRegionTappedListener != null) {
    145             switch (event.getAction()) {
    146                 case MotionEvent.ACTION_DOWN: {
    147                     final int x = (int) event.getX();
    148                     if (x < mLastLeftDiv) {
    149                         mLastRegion = REGION_RED;
    150                     } else if (x < mLastRightDiv) {
    151                         mLastRegion = REGION_YELLOW;
    152                     } else {
    153                         mLastRegion = REGION_GREEN;
    154                     }
    155                     invalidate();
    156                 } break;
    157             }
    158         }
    159         return super.onTouchEvent(event);
    160     }
    161 
    162     @Override
    163     protected void dispatchSetPressed(boolean pressed) {
    164         invalidate();
    165     }
    166 
    167     @Override
    168     public boolean performClick() {
    169         if (mOnRegionTappedListener != null && mLastRegion != 0) {
    170             mOnRegionTappedListener.onRegionTapped(mLastRegion);
    171             mLastRegion = 0;
    172         }
    173         return super.performClick();
    174     }
    175 
    176     private int pickColor(int color, int region) {
    177         if (isPressed() && (mLastRegion&region) != 0) {
    178             return WHITE_COLOR;
    179         }
    180         if ((mColoredRegions&region) == 0) {
    181             return GRAY_COLOR;
    182         }
    183         return color;
    184     }
    185 
    186     @Override
    187     protected void onDraw(Canvas canvas) {
    188         super.onDraw(canvas);
    189 
    190         int width = getWidth();
    191 
    192         int left = 0;
    193 
    194         int right = left + (int)(width*mRedRatio);
    195         int right2 = right + (int)(width*mYellowRatio);
    196         int right3 = right2 + (int)(width*mGreenRatio);
    197 
    198         int indicatorLeft, indicatorRight;
    199         if (mShowingGreen) {
    200             indicatorLeft = right2;
    201             indicatorRight = right3;
    202         } else {
    203             indicatorLeft = right;
    204             indicatorRight = right2;
    205         }
    206 
    207         if (mLastInterestingLeft != indicatorLeft || mLastInterestingRight != indicatorRight) {
    208             mColorPath.reset();
    209             mEdgePath.reset();
    210             if (mShowIndicator && indicatorLeft < indicatorRight) {
    211                 final int midTopY = mRect.top;
    212                 final int midBottomY = 0;
    213                 final int xoff = 2;
    214                 mColorPath.moveTo(indicatorLeft, mRect.top);
    215                 mColorPath.cubicTo(indicatorLeft, midBottomY,
    216                         -xoff, midTopY,
    217                         -xoff, 0);
    218                 mColorPath.lineTo(width+xoff-1, 0);
    219                 mColorPath.cubicTo(width+xoff-1, midTopY,
    220                         indicatorRight, midBottomY,
    221                         indicatorRight, mRect.top);
    222                 mColorPath.close();
    223                 final float lineOffset = mLineWidth+.5f;
    224                 mEdgePath.moveTo(-xoff+lineOffset, 0);
    225                 mEdgePath.cubicTo(-xoff+lineOffset, midTopY,
    226                         indicatorLeft+lineOffset, midBottomY,
    227                         indicatorLeft+lineOffset, mRect.top);
    228                 mEdgePath.moveTo(width+xoff-1-lineOffset, 0);
    229                 mEdgePath.cubicTo(width+xoff-1-lineOffset, midTopY,
    230                         indicatorRight-lineOffset, midBottomY,
    231                         indicatorRight-lineOffset, mRect.top);
    232             }
    233             mLastInterestingLeft = indicatorLeft;
    234             mLastInterestingRight = indicatorRight;
    235         }
    236 
    237         if (!mEdgePath.isEmpty()) {
    238             canvas.drawPath(mEdgePath, mEdgeGradientPaint);
    239             canvas.drawPath(mColorPath, mColorGradientPaint);
    240         }
    241 
    242         if (left < right) {
    243             mRect.left = left;
    244             mRect.right = right;
    245             mPaint.setColor(pickColor(mLeftColor, REGION_RED));
    246             canvas.drawRect(mRect, mPaint);
    247             width -= (right-left);
    248             left = right;
    249         }
    250 
    251         mLastLeftDiv = right;
    252         mLastRightDiv = right2;
    253 
    254         right = right2;
    255 
    256         if (left < right) {
    257             mRect.left = left;
    258             mRect.right = right;
    259             mPaint.setColor(pickColor(mMiddleColor, REGION_YELLOW));
    260             canvas.drawRect(mRect, mPaint);
    261             width -= (right-left);
    262             left = right;
    263         }
    264 
    265 
    266         right = left + width;
    267         if (left < right) {
    268             mRect.left = left;
    269             mRect.right = right;
    270             mPaint.setColor(pickColor(mRightColor, REGION_GREEN));
    271             canvas.drawRect(mRect, mPaint);
    272         }
    273     }
    274 }