Home | History | Annotate | Download | only in colorpicker
      1 /*
      2  * Copyright (C) 2013 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.gallery3d.filtershow.colorpicker;
     18 
     19 import android.content.Context;
     20 import android.graphics.Bitmap;
     21 import android.graphics.Canvas;
     22 import android.graphics.Color;
     23 import android.graphics.LinearGradient;
     24 import android.graphics.Paint;
     25 import android.graphics.RadialGradient;
     26 import android.graphics.Rect;
     27 import android.graphics.RectF;
     28 import android.graphics.Shader;
     29 import android.graphics.SweepGradient;
     30 import android.util.AttributeSet;
     31 import android.util.DisplayMetrics;
     32 import android.view.MotionEvent;
     33 import android.view.View;
     34 
     35 import com.android.gallery3d.R;
     36 
     37 import java.util.ArrayList;
     38 
     39 public class ColorSVRectView extends View implements ColorListener {
     40     private float mDpToPix;
     41 
     42     private float mCtrY = 100;
     43     private Paint mPaint1;
     44 
     45     private float mCtrX = 100;
     46     private Paint mDotPaint = new Paint();
     47     private float mDotRadus;
     48     private float mBorder;
     49 
     50     private float mDotX = Float.NaN;
     51     private float mDotY;
     52     private int mSliderColor = 0xFF33B5E5;
     53     private float[] mHSVO = new float[]{0, 1, 1, 1};
     54     RectF mRect = new RectF();
     55 
     56     private int mWidth;
     57     private int mHeight;
     58     public final static float DOT_SIZE = 20;
     59     public final static float BORDER_SIZE = 20;
     60     Bitmap mBitmap;
     61 
     62     public ColorSVRectView(Context ctx, AttributeSet attrs) {
     63         super(ctx, attrs);
     64 
     65         DisplayMetrics metrics = ctx.getResources().getDisplayMetrics();
     66         mDpToPix = metrics.density;
     67         mDotRadus = DOT_SIZE * mDpToPix;
     68         mBorder = BORDER_SIZE * mDpToPix;
     69 
     70         mPaint1 = new Paint();
     71 
     72 
     73         mDotPaint.setStyle(Paint.Style.FILL);
     74         if (isInEditMode()) {
     75             mDotPaint.setColor(0x646464);
     76             mSliderColor = 0x888888;
     77         } else {
     78             mDotPaint.setColor(ctx.getResources().getColor(R.color.slider_dot_color));
     79             mSliderColor = ctx.getResources().getColor(R.color.slider_line_color);
     80         }
     81         mPaint1.setStyle(Paint.Style.FILL);
     82         mPaint1.setAntiAlias(true);
     83         mPaint1.setFilterBitmap(true);
     84 
     85         mBitmap = Bitmap.createBitmap(64, 46, Bitmap.Config.ARGB_8888);
     86         fillBitmap();
     87     }
     88 
     89     @Override
     90     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     91         super.onMeasure(widthMeasureSpec, widthMeasureSpec);
     92     }
     93 
     94     void fillBitmap() {
     95         int w = mBitmap.getWidth();
     96         int h = mBitmap.getHeight();
     97         int[] buff = new int[w * h];
     98         float[] hsv = new float[3];
     99         hsv[0] = mHSVO[0];
    100         for (int i = 0; i < w * h; i++) {
    101             float sat = (i % w) / (float) w;
    102             float val = (w - i / w) / (float) w;
    103             hsv[1] = sat;
    104             hsv[2] = val;
    105             buff[i] = Color.HSVToColor(hsv);
    106         }
    107         mBitmap.setPixels(buff, 0, w, 0, 0, w, h);
    108     }
    109 
    110     private void setUpColorPanel() {
    111         updateDot();
    112         updateDotPaint();
    113         fillBitmap();
    114 
    115     }
    116 
    117 
    118     @Override
    119     protected void onDraw(Canvas canvas) {
    120         super.onDraw(canvas);
    121         Rect r = canvas.getClipBounds();
    122         mRect.set(r);
    123         mRect.top += mBorder;
    124         mRect.bottom -= mBorder;
    125         mRect.left += mBorder;
    126         mRect.right -= mBorder;
    127         canvas.drawBitmap(mBitmap, null, mRect, mPaint1);
    128 
    129         if (mDotX != Float.NaN) {
    130 
    131             canvas.drawCircle(mDotX, mDotY, mDotRadus, mDotPaint);
    132         }
    133     }
    134 
    135 
    136     public boolean onDown(MotionEvent e) {
    137         return true;
    138     }
    139 
    140     @Override
    141     public boolean onTouchEvent(MotionEvent event) {
    142 
    143         invalidate((int) (mDotX - mDotRadus), (int) (mDotY - mDotRadus), (int) (mDotX + mDotRadus),
    144                 (int) (mDotY + mDotRadus));
    145         float x = event.getX();
    146         float y = event.getY();
    147 
    148         x = Math.max(Math.min(x, mWidth - mBorder), mBorder);
    149         y = Math.max(Math.min(y, mHeight - mBorder), mBorder);
    150         mDotX = x;
    151         mDotY = y;
    152         float sat = 1 - (mDotY - mBorder) / (mHeight - 2 * mBorder);
    153         if (sat > 1) {
    154             sat = 1;
    155         }
    156 
    157         float value = (mDotX - mBorder) / (mHeight - 2 * mBorder);
    158         mHSVO[2] = sat;
    159         mHSVO[1] = value;
    160         notifyColorListeners(mHSVO);
    161         updateDotPaint();
    162         invalidate((int) (mDotX - mDotRadus), (int) (mDotY - mDotRadus), (int) (mDotX + mDotRadus),
    163                 (int) (mDotY + mDotRadus));
    164 
    165         return true;
    166     }
    167 
    168     @Override
    169     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    170         mWidth = w;
    171         mHeight = h;
    172         mCtrY = h / 2f;
    173         mCtrX = w / 2f;
    174 
    175         setUpColorPanel();
    176     }
    177 
    178 
    179     private void updateDot() {
    180 
    181         double hue = mHSVO[0];
    182         double sat = mHSVO[1];
    183         double val = mHSVO[2];
    184         double opc = mHSVO[3];
    185 
    186         mDotX = (float) (mBorder + (mHeight - 2 * mBorder) * sat);
    187         mDotY = (float) ((1 - val) * (mHeight - 2 * mBorder) + mBorder);
    188 
    189     }
    190 
    191     private void updateDotPaint() {
    192         int[] colors3 = new int[]{
    193                 mSliderColor, mSliderColor, 0x66000000, 0};
    194         RadialGradient g = new RadialGradient(mDotX, mDotY, mDotRadus, colors3, new float[]{
    195                 0, .3f, .31f, 1}, Shader.TileMode.CLAMP);
    196         mDotPaint.setShader(g);
    197 
    198     }
    199 
    200     @Override
    201     public void setColor(float[] hsvo) {
    202         if (hsvo[0] == mHSVO[0]
    203                 && hsvo[1] == mHSVO[1]
    204                 && hsvo[2] == mHSVO[2]) {
    205             mHSVO[3] = hsvo[3]; // we don't update if color stays the same
    206             return;
    207         }
    208         System.arraycopy(hsvo, 0, mHSVO, 0, mHSVO.length);
    209 
    210         setUpColorPanel();
    211         invalidate();
    212 
    213         updateDot();
    214         updateDotPaint();
    215 
    216     }
    217 
    218     ArrayList<ColorListener> mColorListeners = new ArrayList<ColorListener>();
    219 
    220     public void notifyColorListeners(float[] hsv) {
    221         for (ColorListener l : mColorListeners) {
    222             l.setColor(hsv);
    223         }
    224     }
    225 
    226     public void addColorListener(ColorListener l) {
    227         mColorListeners.add(l);
    228     }
    229 
    230     public void removeColorListener(ColorListener l) {
    231         mColorListeners.remove(l);
    232     }
    233 }
    234