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.Canvas; 21 import android.graphics.Color; 22 import android.graphics.LinearGradient; 23 import android.graphics.Paint; 24 import android.graphics.RadialGradient; 25 import android.graphics.RectF; 26 import android.graphics.Shader; 27 import android.graphics.SweepGradient; 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 37 public class ColorRectView extends View implements ColorListener { 38 private float mDpToPix; 39 private float mRadius = 80; 40 private float mCtrY = 100; 41 private Paint mWheelPaint1; 42 private Paint mWheelPaint2; 43 private Paint mWheelPaint3; 44 private float mCtrX = 100; 45 private Paint mDotPaint; 46 private float mDotRadus; 47 private float mBorder; 48 private int mBgcolor = 0; 49 private float mDotX = Float.NaN; 50 private float mDotY; 51 private int mSliderColor = 0xFF33B5E5; 52 private float[] mHSVO = new float[4]; 53 private int[] mColors = new int[] { 54 0xFFFF0000,// red 55 0xFFFFFF00,// yellow 56 0xFF00FF00,// green 57 0xFF00FFFF,// cyan 58 0xFF0000FF,// blue 59 0xFFFF00FF,// magenta 60 0xFFFF0000,// red 61 }; 62 private int mWidth; 63 private int mHeight; 64 public final static float DOT_SIZE = 20; 65 public final static float BORDER_SIZE = 10; 66 67 public ColorRectView(Context ctx, AttributeSet attrs) { 68 super(ctx, attrs); 69 70 DisplayMetrics metrics = ctx.getResources().getDisplayMetrics(); 71 mDpToPix = metrics.density; 72 mDotRadus = DOT_SIZE * mDpToPix; 73 mBorder = BORDER_SIZE * mDpToPix; 74 75 mWheelPaint1 = new Paint(); 76 mWheelPaint2 = new Paint(); 77 mWheelPaint3 = new Paint(); 78 mDotPaint = new Paint(); 79 80 mDotPaint.setStyle(Paint.Style.FILL); 81 mDotPaint.setColor(ctx.getResources().getColor(R.color.slider_dot_color)); 82 mSliderColor = ctx.getResources().getColor(R.color.slider_line_color); 83 mWheelPaint1.setStyle(Paint.Style.FILL); 84 mWheelPaint2.setStyle(Paint.Style.FILL); 85 mWheelPaint3.setStyle(Paint.Style.FILL); 86 } 87 88 public boolean onDown(MotionEvent e) { 89 return true; 90 } 91 92 @Override 93 public boolean onTouchEvent(MotionEvent event) { 94 95 invalidate((int) (mDotX - mDotRadus), (int) (mDotY - mDotRadus), (int) (mDotX + mDotRadus), 96 (int) (mDotY + mDotRadus)); 97 float x = event.getX(); 98 float y = event.getY(); 99 100 x = Math.max(Math.min(x, mWidth - mBorder), mBorder); 101 y = Math.max(Math.min(y, mHeight - mBorder), mBorder); 102 mDotX = x; 103 mDotY = y; 104 float sat = 1 - (mDotY - mBorder) / (mHeight - 2 * mBorder); 105 if (sat > 1) { 106 sat = 1; 107 } 108 109 double hue = Math.PI * 2 * (mDotX - mBorder) / (mHeight - 2 * mBorder); 110 mHSVO[0] = ((float) Math.toDegrees(hue) + 360) % 360; 111 mHSVO[1] = sat; 112 notifyColorListeners(mHSVO); 113 updateDotPaint(); 114 invalidate((int) (mDotX - mDotRadus), (int) (mDotY - mDotRadus), (int) (mDotX + mDotRadus), 115 (int) (mDotY + mDotRadus)); 116 117 return true; 118 } 119 120 @Override 121 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 122 mWidth = w; 123 mHeight = h; 124 mCtrY = h / 2f; 125 mCtrX = w / 2f; 126 mRadius = Math.min(mCtrY, mCtrX) - 2 * mBorder; 127 setUpColorPanel(); 128 } 129 130 private void setUpColorPanel() { 131 float val = mHSVO[2]; 132 int v = 0xFF000000 | 0x10101 * (int) (val * 0xFF); 133 int[] colors = new int[] { 134 0x0000000, v }; 135 int[] colors2 = new int[] { 136 0x0000000, 0xFF000000 }; 137 int[] wheelColor = new int[mColors.length]; 138 float[] hsv = new float[3]; 139 for (int i = 0; i < wheelColor.length; i++) { 140 Color.colorToHSV(mColors[i], hsv); 141 hsv[2] = mHSVO[2]; 142 wheelColor[i] = Color.HSVToColor(hsv); 143 } 144 updateDot(); 145 updateDotPaint(); 146 SweepGradient sg = new SweepGradient(mCtrX, mCtrY, wheelColor, null); 147 LinearGradient lg = new LinearGradient( 148 mBorder, 0, mWidth - mBorder, 0, wheelColor, null, Shader.TileMode.CLAMP); 149 150 mWheelPaint1.setShader(lg); 151 LinearGradient rg = new LinearGradient( 152 0, mBorder, 0, mHeight - mBorder, colors, null, Shader.TileMode.CLAMP); 153 mWheelPaint2.setShader(rg); 154 LinearGradient rg2 = new LinearGradient( 155 0, mBorder, 0, mHeight - mBorder, colors2, null, Shader.TileMode.CLAMP); 156 mWheelPaint3.setShader(rg2); 157 } 158 159 @Override 160 protected void onDraw(Canvas canvas) { 161 super.onDraw(canvas); 162 canvas.drawColor(mBgcolor); 163 RectF rect = new RectF(); 164 rect.left = mBorder; 165 rect.right = mWidth - mBorder; 166 rect.top = mBorder; 167 rect.bottom = mHeight - mBorder; 168 169 canvas.drawRect(rect, mWheelPaint1); 170 canvas.drawRect(rect, mWheelPaint3); 171 canvas.drawRect(rect, mWheelPaint2); 172 173 if (mDotX != Float.NaN) { 174 175 canvas.drawCircle(mDotX, mDotY, mDotRadus, mDotPaint); 176 } 177 } 178 179 private void updateDot() { 180 181 double hue = mHSVO[0]; 182 double sat = mHSVO[1]; 183 184 mDotX = (float) (mBorder + (mHeight - 2 * mBorder) * Math.toRadians(hue) / (Math.PI * 2)); 185 mDotY = (float) ((1 - sat) * (mHeight - 2 * mBorder) + mBorder); 186 187 } 188 189 private void updateDotPaint() { 190 int[] colors3 = new int[] { 191 mSliderColor, mSliderColor, 0x66000000, 0 }; 192 RadialGradient g = new RadialGradient(mDotX, mDotY, mDotRadus, colors3, new float[] { 193 0, .3f, .31f, 1 }, Shader.TileMode.CLAMP); 194 mDotPaint.setShader(g); 195 196 } 197 198 @Override 199 public void setColor(float[] hsvo) { 200 System.arraycopy(hsvo, 0, mHSVO, 0, mHSVO.length); 201 202 setUpColorPanel(); 203 invalidate(); 204 205 updateDot(); 206 updateDotPaint(); 207 208 } 209 210 ArrayList<ColorListener> mColorListeners = new ArrayList<ColorListener>(); 211 212 public void notifyColorListeners(float[] hsv) { 213 for (ColorListener l : mColorListeners) { 214 l.setColor(hsv); 215 } 216 } 217 218 public void addColorListener(ColorListener l) { 219 mColorListeners.add(l); 220 } 221 222 public void removeColorListener(ColorListener l) { 223 mColorListeners.remove(l); 224 } 225 } 226