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 (!Float.isNaN(mDotX)) { 174 canvas.drawCircle(mDotX, mDotY, mDotRadus, mDotPaint); 175 } 176 } 177 178 private void updateDot() { 179 180 double hue = mHSVO[0]; 181 double sat = mHSVO[1]; 182 183 mDotX = (float) (mBorder + (mHeight - 2 * mBorder) * Math.toRadians(hue) / (Math.PI * 2)); 184 mDotY = (float) ((1 - sat) * (mHeight - 2 * mBorder) + mBorder); 185 186 } 187 188 private void updateDotPaint() { 189 int[] colors3 = new int[] { 190 mSliderColor, mSliderColor, 0x66000000, 0 }; 191 RadialGradient g = new RadialGradient(mDotX, mDotY, mDotRadus, colors3, new float[] { 192 0, .3f, .31f, 1 }, Shader.TileMode.CLAMP); 193 mDotPaint.setShader(g); 194 195 } 196 197 @Override 198 public void setColor(float[] hsvo) { 199 System.arraycopy(hsvo, 0, mHSVO, 0, mHSVO.length); 200 201 setUpColorPanel(); 202 invalidate(); 203 204 updateDot(); 205 updateDotPaint(); 206 207 } 208 209 ArrayList<ColorListener> mColorListeners = new ArrayList<ColorListener>(); 210 211 public void notifyColorListeners(float[] hsv) { 212 for (ColorListener l : mColorListeners) { 213 l.setColor(hsv); 214 } 215 } 216 217 public void addColorListener(ColorListener l) { 218 mColorListeners.add(l); 219 } 220 221 public void removeColorListener(ColorListener l) { 222 mColorListeners.remove(l); 223 } 224 } 225