blob: 92f4ad8fe9b310b130a20be6c133392a7ed1c218 [file] [log] [blame]
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.gallery3d.filtershow.colorpicker;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import com.android.gallery3d.R;
import java.util.ArrayList;
public class ColorRectView extends View implements ColorListener {
private float mDpToPix;
private float mRadius = 80;
private float mCtrY = 100;
private Paint mWheelPaint1;
private Paint mWheelPaint2;
private Paint mWheelPaint3;
private float mCtrX = 100;
private Paint mDotPaint;
private float mDotRadus;
private float mBorder;
private int mBgcolor = 0;
private float mDotX = Float.NaN;
private float mDotY;
private int mSliderColor = 0xFF33B5E5;
private float[] mHSVO = new float[4];
private int[] mColors = new int[] {
0xFFFF0000,// red
0xFFFFFF00,// yellow
0xFF00FF00,// green
0xFF00FFFF,// cyan
0xFF0000FF,// blue
0xFFFF00FF,// magenta
0xFFFF0000,// red
};
private int mWidth;
private int mHeight;
public final static float DOT_SIZE = 20;
public final static float BORDER_SIZE = 10;
public ColorRectView(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
DisplayMetrics metrics = ctx.getResources().getDisplayMetrics();
mDpToPix = metrics.density;
mDotRadus = DOT_SIZE * mDpToPix;
mBorder = BORDER_SIZE * mDpToPix;
mWheelPaint1 = new Paint();
mWheelPaint2 = new Paint();
mWheelPaint3 = new Paint();
mDotPaint = new Paint();
mDotPaint.setStyle(Paint.Style.FILL);
mDotPaint.setColor(ctx.getResources().getColor(R.color.slider_dot_color));
mSliderColor = ctx.getResources().getColor(R.color.slider_line_color);
mWheelPaint1.setStyle(Paint.Style.FILL);
mWheelPaint2.setStyle(Paint.Style.FILL);
mWheelPaint3.setStyle(Paint.Style.FILL);
}
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
invalidate((int) (mDotX - mDotRadus), (int) (mDotY - mDotRadus), (int) (mDotX + mDotRadus),
(int) (mDotY + mDotRadus));
float x = event.getX();
float y = event.getY();
x = Math.max(Math.min(x, mWidth - mBorder), mBorder);
y = Math.max(Math.min(y, mHeight - mBorder), mBorder);
mDotX = x;
mDotY = y;
float sat = 1 - (mDotY - mBorder) / (mHeight - 2 * mBorder);
if (sat > 1) {
sat = 1;
}
double hue = Math.PI * 2 * (mDotX - mBorder) / (mHeight - 2 * mBorder);
mHSVO[0] = ((float) Math.toDegrees(hue) + 360) % 360;
mHSVO[1] = sat;
notifyColorListeners(mHSVO);
updateDotPaint();
invalidate((int) (mDotX - mDotRadus), (int) (mDotY - mDotRadus), (int) (mDotX + mDotRadus),
(int) (mDotY + mDotRadus));
return true;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mWidth = w;
mHeight = h;
mCtrY = h / 2f;
mCtrX = w / 2f;
mRadius = Math.min(mCtrY, mCtrX) - 2 * mBorder;
setUpColorPanel();
}
private void setUpColorPanel() {
float val = mHSVO[2];
int v = 0xFF000000 | 0x10101 * (int) (val * 0xFF);
int[] colors = new int[] {
0x0000000, v };
int[] colors2 = new int[] {
0x0000000, 0xFF000000 };
int[] wheelColor = new int[mColors.length];
float[] hsv = new float[3];
for (int i = 0; i < wheelColor.length; i++) {
Color.colorToHSV(mColors[i], hsv);
hsv[2] = mHSVO[2];
wheelColor[i] = Color.HSVToColor(hsv);
}
updateDot();
updateDotPaint();
SweepGradient sg = new SweepGradient(mCtrX, mCtrY, wheelColor, null);
LinearGradient lg = new LinearGradient(
mBorder, 0, mWidth - mBorder, 0, wheelColor, null, Shader.TileMode.CLAMP);
mWheelPaint1.setShader(lg);
LinearGradient rg = new LinearGradient(
0, mBorder, 0, mHeight - mBorder, colors, null, Shader.TileMode.CLAMP);
mWheelPaint2.setShader(rg);
LinearGradient rg2 = new LinearGradient(
0, mBorder, 0, mHeight - mBorder, colors2, null, Shader.TileMode.CLAMP);
mWheelPaint3.setShader(rg2);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(mBgcolor);
RectF rect = new RectF();
rect.left = mBorder;
rect.right = mWidth - mBorder;
rect.top = mBorder;
rect.bottom = mHeight - mBorder;
canvas.drawRect(rect, mWheelPaint1);
canvas.drawRect(rect, mWheelPaint3);
canvas.drawRect(rect, mWheelPaint2);
if (!Float.isNaN(mDotX)) {
canvas.drawCircle(mDotX, mDotY, mDotRadus, mDotPaint);
}
}
private void updateDot() {
double hue = mHSVO[0];
double sat = mHSVO[1];
mDotX = (float) (mBorder + (mHeight - 2 * mBorder) * Math.toRadians(hue) / (Math.PI * 2));
mDotY = (float) ((1 - sat) * (mHeight - 2 * mBorder) + mBorder);
}
private void updateDotPaint() {
int[] colors3 = new int[] {
mSliderColor, mSliderColor, 0x66000000, 0 };
RadialGradient g = new RadialGradient(mDotX, mDotY, mDotRadus, colors3, new float[] {
0, .3f, .31f, 1 }, Shader.TileMode.CLAMP);
mDotPaint.setShader(g);
}
@Override
public void setColor(float[] hsvo) {
System.arraycopy(hsvo, 0, mHSVO, 0, mHSVO.length);
setUpColorPanel();
invalidate();
updateDot();
updateDotPaint();
}
ArrayList<ColorListener> mColorListeners = new ArrayList<ColorListener>();
public void notifyColorListeners(float[] hsv) {
for (ColorListener l : mColorListeners) {
l.setColor(hsv);
}
}
public void addColorListener(ColorListener l) {
mColorListeners.add(l);
}
public void removeColorListener(ColorListener l) {
mColorListeners.remove(l);
}
}