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.BitmapShader; 22 import android.graphics.Canvas; 23 import android.graphics.Color; 24 import android.graphics.LinearGradient; 25 import android.graphics.Paint; 26 import android.graphics.RadialGradient; 27 import android.graphics.Shader; 28 import android.util.AttributeSet; 29 import android.util.DisplayMetrics; 30 import android.view.MotionEvent; 31 import android.view.View; 32 33 import com.android.gallery3d.R; 34 35 import java.util.ArrayList; 36 import java.util.Arrays; 37 38 public class ColorSaturationView extends View implements ColorListener { 39 40 private float mRadius; 41 private float mWidth; 42 private Paint mBarPaint1; 43 private Paint mLinePaint1; 44 private Paint mLinePaint2; 45 private Paint mCheckPaint; 46 47 private float mHeight; 48 private Paint mDotPaint; 49 private int mBgcolor = 0; 50 51 private float mDotRadius; 52 private float mBorder; 53 54 private float[] mHSVO = new float[4]; 55 private int mSliderColor; 56 private float mDotX = mBorder; 57 private float mDotY = mBorder; 58 private final static float DOT_SIZE = ColorRectView.DOT_SIZE; 59 public final static float BORDER_SIZE = 20;; 60 61 private ArrayList<ColorListener> mColorListeners = new ArrayList<ColorListener>(); 62 63 public ColorSaturationView(Context ctx, AttributeSet attrs) { 64 super(ctx, attrs); 65 DisplayMetrics metrics = ctx.getResources().getDisplayMetrics(); 66 float mDpToPix = metrics.density; 67 mDotRadius = DOT_SIZE * mDpToPix; 68 mBorder = BORDER_SIZE * mDpToPix; 69 mBarPaint1 = new Paint(); 70 71 mDotPaint = new Paint(); 72 73 mDotPaint.setStyle(Paint.Style.FILL); 74 mDotPaint.setColor(ctx.getResources().getColor(R.color.slider_dot_color)); 75 mSliderColor = ctx.getResources().getColor(R.color.slider_line_color); 76 77 mBarPaint1.setStyle(Paint.Style.FILL); 78 79 mLinePaint1 = new Paint(); 80 mLinePaint1.setColor(Color.GRAY); 81 mLinePaint2 = new Paint(); 82 mLinePaint2.setColor(mSliderColor); 83 mLinePaint2.setStrokeWidth(4); 84 85 int[] colors = new int[16 * 16]; 86 for (int i = 0; i < colors.length; i++) { 87 int y = i / (16 * 8); 88 int x = (i / 8) % 2; 89 colors[i] = (x == y) ? 0xFFAAAAAA : 0xFF444444; 90 } 91 Bitmap bitmap = Bitmap.createBitmap(colors, 16, 16, Bitmap.Config.ARGB_8888); 92 BitmapShader bs = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 93 mCheckPaint = new Paint(); 94 mCheckPaint.setShader(bs); 95 } 96 97 public boolean onDown(MotionEvent e) { 98 return true; 99 } 100 101 @Override 102 public boolean onTouchEvent(MotionEvent event) { 103 float ox = mDotX; 104 float oy = mDotY; 105 106 float x = event.getX(); 107 float y = event.getY(); 108 109 mDotX = x; 110 111 if (mDotX < mBorder) { 112 mDotX = mBorder; 113 } 114 115 if (mDotX > mWidth - mBorder) { 116 mDotX = mWidth - mBorder; 117 } 118 mHSVO[3] = (mDotX - mBorder) / (mWidth - mBorder * 2); 119 notifyColorListeners(mHSVO); 120 setupButton(); 121 invalidate((int) (ox - mDotRadius), (int) (oy - mDotRadius), (int) (ox + mDotRadius), 122 (int) (oy + mDotRadius)); 123 invalidate( 124 (int) (mDotX - mDotRadius), (int) (mDotY - mDotRadius), (int) (mDotX + mDotRadius), 125 (int) (mDotY + mDotRadius)); 126 127 return true; 128 } 129 130 private void setupButton() { 131 float pos = mHSVO[3] * (mWidth - mBorder * 2); 132 mDotX = pos + mBorder; 133 134 int[] colors3 = new int[] { 135 mSliderColor, mSliderColor, 0x66000000, 0 }; 136 RadialGradient g = new RadialGradient(mDotX, mDotY, mDotRadius, colors3, new float[] { 137 0, .3f, .31f, 1 }, Shader.TileMode.CLAMP); 138 mDotPaint.setShader(g); 139 } 140 141 @Override 142 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 143 mWidth = w; 144 mHeight = h; 145 mDotY = mHeight / 2; 146 updatePaint(); 147 setupButton(); 148 } 149 150 private void updatePaint() { 151 float[]hsvo = Arrays.copyOf(mHSVO, 4); 152 hsvo[3] = 1; 153 hsvo[2] = 1; 154 hsvo[1] = 1; 155 int color2 = Color.HSVToColor(hsvo); 156 hsvo[1] = 0; 157 int color1 = Color.HSVToColor(hsvo); 158 Shader sg = new LinearGradient( 159 mBorder, mBorder, mWidth - mBorder, mBorder, 160 color1, color2, Shader.TileMode.CLAMP); 161 mBarPaint1.setShader(sg); 162 163 } 164 165 @Override 166 protected void onDraw(Canvas canvas) { 167 super.onDraw(canvas); 168 canvas.drawColor(mBgcolor); 169 canvas.drawRect(mBorder, mBorder, mWidth - mBorder, mHeight - mBorder, mCheckPaint); 170 canvas.drawRect(mBorder, mBorder, mWidth - mBorder, mHeight - mBorder, mBarPaint1); 171 canvas.drawLine(mDotX, mDotY, mWidth - mBorder, mDotY, mLinePaint1); 172 canvas.drawLine(mBorder, mDotY, mDotX, mDotY, mLinePaint2); 173 if (mDotX != Float.NaN) { 174 canvas.drawCircle(mDotX, mDotY, mDotRadius, mDotPaint); 175 } 176 } 177 178 @Override 179 public void setColor(float[] hsv) { 180 System.arraycopy(hsv, 0, mHSVO, 0, mHSVO.length); 181 182 float oy = mDotY; 183 184 updatePaint(); 185 setupButton(); 186 invalidate(); 187 } 188 189 public void notifyColorListeners(float[] hsvo) { 190 for (ColorListener l : mColorListeners) { 191 l.setColor(hsvo); 192 } 193 } 194 195 public void addColorListener(ColorListener l) { 196 mColorListeners.add(l); 197 } 198 199 public void removeColorListener(ColorListener l) { 200 mColorListeners.remove(l); 201 } 202 } 203