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