1f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford/*
2f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford * Copyright (C) 2013 The Android Open Source Project
3f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford *
4f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford * Licensed under the Apache License, Version 2.0 (the "License");
5f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford * you may not use this file except in compliance with the License.
6f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford * You may obtain a copy of the License at
7f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford *
8f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford *      http://www.apache.org/licenses/LICENSE-2.0
9f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford *
10f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford * Unless required by applicable law or agreed to in writing, software
11f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford * distributed under the License is distributed on an "AS IS" BASIS,
12f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford * See the License for the specific language governing permissions and
14f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford * limitations under the License.
15f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford */
16f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
17f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordpackage com.android.gallery3d.filtershow.colorpicker;
18f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
19f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.content.Context;
20f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.graphics.Bitmap;
21f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.graphics.BitmapShader;
22f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.graphics.Canvas;
23f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.graphics.Color;
24f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.graphics.LinearGradient;
25f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.graphics.Paint;
26f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.graphics.RadialGradient;
27f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.graphics.Shader;
28f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.util.AttributeSet;
29f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.util.DisplayMetrics;
30f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.view.MotionEvent;
31f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport android.view.View;
32f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
33f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport com.android.gallery3d.R;
34f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
35f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport java.util.ArrayList;
36f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordimport java.util.Arrays;
37f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
38f4b659334750a5aa75f929d18857a2ab93c9d939John Hofordpublic class ColorSaturationView extends View implements ColorListener {
39f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
40f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private float mRadius;
41f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private float mWidth;
42f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private Paint mBarPaint1;
43f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private Paint mLinePaint1;
44f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private Paint mLinePaint2;
45f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private Paint mCheckPaint;
46f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
47f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private float mHeight;
48f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private Paint mDotPaint;
49f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private int mBgcolor = 0;
50f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
51f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private float mDotRadius;
52f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private float mBorder;
53f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
54f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private float[] mHSVO = new float[4];
55f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private int mSliderColor;
56f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private float mDotX = mBorder;
57f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private float mDotY = mBorder;
58f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private final static float DOT_SIZE = ColorRectView.DOT_SIZE;
59f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    public final static float BORDER_SIZE = 20;;
60f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
61f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private ArrayList<ColorListener> mColorListeners = new ArrayList<ColorListener>();
62f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
63f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    public ColorSaturationView(Context ctx, AttributeSet attrs) {
64f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        super(ctx, attrs);
65f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        DisplayMetrics metrics = ctx.getResources().getDisplayMetrics();
66f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        float mDpToPix = metrics.density;
67f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mDotRadius = DOT_SIZE * mDpToPix;
68f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mBorder = BORDER_SIZE * mDpToPix;
69f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mBarPaint1 = new Paint();
70f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
71f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mDotPaint = new Paint();
72f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
73f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mDotPaint.setStyle(Paint.Style.FILL);
74f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mDotPaint.setColor(ctx.getResources().getColor(R.color.slider_dot_color));
75f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mSliderColor = ctx.getResources().getColor(R.color.slider_line_color);
76f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
77f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mBarPaint1.setStyle(Paint.Style.FILL);
78f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
79f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mLinePaint1 = new Paint();
80f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mLinePaint1.setColor(Color.GRAY);
81f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mLinePaint2 = new Paint();
82f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mLinePaint2.setColor(mSliderColor);
83f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mLinePaint2.setStrokeWidth(4);
84f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
85f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        int[] colors = new int[16 * 16];
86f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        for (int i = 0; i < colors.length; i++) {
87f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford            int y = i / (16 * 8);
88f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford            int x = (i / 8) % 2;
89f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford            colors[i] = (x == y) ? 0xFFAAAAAA : 0xFF444444;
90f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        }
91f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        Bitmap bitmap = Bitmap.createBitmap(colors, 16, 16, Bitmap.Config.ARGB_8888);
92f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        BitmapShader bs = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
93f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mCheckPaint = new Paint();
94f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mCheckPaint.setShader(bs);
95f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    }
96f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
97f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    public boolean onDown(MotionEvent e) {
98f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        return true;
99f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    }
100f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
101f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    @Override
102f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    public boolean onTouchEvent(MotionEvent event) {
103f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        float ox = mDotX;
104f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        float oy = mDotY;
105f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
106f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        float x = event.getX();
107f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        float y = event.getY();
108f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
109f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mDotX = x;
110f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
111f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        if (mDotX < mBorder) {
112f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford            mDotX = mBorder;
113f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        }
114f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
115f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        if (mDotX > mWidth - mBorder) {
116f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford            mDotX = mWidth - mBorder;
117f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        }
118f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mHSVO[3] = (mDotX - mBorder) / (mWidth - mBorder * 2);
119f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        notifyColorListeners(mHSVO);
120f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        setupButton();
121f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        invalidate((int) (ox - mDotRadius), (int) (oy - mDotRadius), (int) (ox + mDotRadius),
122f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford                (int) (oy + mDotRadius));
123f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        invalidate(
124f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford                (int) (mDotX - mDotRadius), (int) (mDotY - mDotRadius), (int) (mDotX + mDotRadius),
125f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford                (int) (mDotY + mDotRadius));
126f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
127f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        return true;
128f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    }
129f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
130f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private void setupButton() {
131f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        float pos = mHSVO[3] * (mWidth - mBorder * 2);
132f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mDotX = pos + mBorder;
133f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
134f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        int[] colors3 = new int[] {
135f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mSliderColor, mSliderColor, 0x66000000, 0 };
136f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        RadialGradient g = new RadialGradient(mDotX, mDotY, mDotRadius, colors3, new float[] {
137f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        0, .3f, .31f, 1 }, Shader.TileMode.CLAMP);
138f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mDotPaint.setShader(g);
139f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    }
140f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
141f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    @Override
142f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
143f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mWidth = w;
144f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mHeight = h;
145f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mDotY = mHeight / 2;
146f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        updatePaint();
147f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        setupButton();
148f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    }
149f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
150f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    private void updatePaint() {
151f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        float[]hsvo = Arrays.copyOf(mHSVO, 4);
152f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        hsvo[3] = 1;
153f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        hsvo[2] = 1;
154f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        hsvo[1] = 1;
155f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        int color2 = Color.HSVToColor(hsvo);
156f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        hsvo[1] = 0;
157f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        int color1 = Color.HSVToColor(hsvo);
158f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        Shader sg = new LinearGradient(
159f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford                mBorder, mBorder, mWidth - mBorder, mBorder,
160f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford                color1, color2, Shader.TileMode.CLAMP);
161f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mBarPaint1.setShader(sg);
162f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
163f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    }
164f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
165f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    @Override
166f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    protected void onDraw(Canvas canvas) {
167f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        super.onDraw(canvas);
168f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        canvas.drawColor(mBgcolor);
169f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        canvas.drawRect(mBorder, mBorder, mWidth - mBorder, mHeight - mBorder, mCheckPaint);
170f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        canvas.drawRect(mBorder, mBorder, mWidth - mBorder, mHeight - mBorder, mBarPaint1);
171f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        canvas.drawLine(mDotX, mDotY, mWidth - mBorder, mDotY, mLinePaint1);
172f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        canvas.drawLine(mBorder, mDotY, mDotX, mDotY, mLinePaint2);
173a900c0a7b4f3fd4797290428a97c48066a2689ebIan Rogers        if (!Float.isNaN(mDotX)) {
174f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford            canvas.drawCircle(mDotX, mDotY, mDotRadius, mDotPaint);
175f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        }
176f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    }
177f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
178f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    @Override
179f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    public void setColor(float[] hsv) {
180f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        System.arraycopy(hsv, 0, mHSVO, 0, mHSVO.length);
181f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
182f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        float oy = mDotY;
183f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
184f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        updatePaint();
185f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        setupButton();
186f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        invalidate();
187f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    }
188f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
189f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    public void notifyColorListeners(float[] hsvo) {
190f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        for (ColorListener l : mColorListeners) {
191f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford            l.setColor(hsvo);
192f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        }
193f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    }
194f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
195f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    public void addColorListener(ColorListener l) {
196f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mColorListeners.add(l);
197f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    }
198f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford
199f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    public void removeColorListener(ColorListener l) {
200f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford        mColorListeners.remove(l);
201f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford    }
202f4b659334750a5aa75f929d18857a2ab93c9d939John Hoford}
203