App

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

SVPickerView.java
Go to the documentation of this file.
1 package mhr.appandroid.views.colorpicker;
2
3 import mhr.appandroid.R;
4 import android.content.Context;
5 import android.graphics.Bitmap;
6 import android.graphics.BitmapFactory;
7 import android.graphics.Canvas;
8 import android.graphics.Color;
9 import android.graphics.ComposeShader;
10 import android.graphics.LinearGradient;
11 import android.graphics.Paint;
12 import android.graphics.PorterDuff;
13 import android.graphics.Shader;
14 import android.graphics.Shader.TileMode;
15 import android.graphics.drawable.StateListDrawable;
16 import android.os.Bundle;
17 import android.os.Parcelable;
18 import android.util.AttributeSet;
19 import android.view.MotionEvent;
20 import android.view.View;
21 import android.view.ViewParent;
22 import android.widget.Toast;
23
24
32 public class SVPickerView extends View {
33 //----- Interface ---------------------------------------------------------------------------------------------------------------------------//
39 public interface OnSVPickerChangeListener {
44 public void onSVPickerChange(SVPickerView picker);
49 public void onSVPickerStartTrackingTouch(SVPickerView picker);
54 public void onSVPickerStopTrackingTouch(SVPickerView picker);
55 }
56
57 //----- Pole --------------------------------------------------------------------------------------------------------------------------------//
58 protected Bitmap cursor;
59 protected Bitmap cursorPressed;
60 protected Bitmap cursorNormal;
61 @Deprecated
62 protected StateListDrawable drCursor;
63 protected float cursorX;
64 protected int minX;
65 protected int maxX;
66 protected int lengthX;
67 protected float cursorY;
68 protected int minY;
69 protected int maxY;
70 protected int lengthY;
71 protected int margin;
72
73 protected Paint paint;
74 protected Shader baseShader;
75 protected Shader finalShader;
76
77 protected float[] actualColor = { 0.0f, 0.0f, 0.0f };
78 protected float[] fullColor = { 0.0f, 1.0f, 1.0f };
79
80 protected OnSVPickerChangeListener listener = null;
81 //----- Accessory a primitivní metody -------------------------------------------------------------------------------------------------------//
82
87 public void setOnSVChangedListener(OnSVPickerChangeListener listener) {
88 this.listener = listener;
89 }
90
95 public float getHue() {
96 return actualColor[0];
97 }
98
103 public void setHue(float hue) {
104 fullColor[0] = hue;
105 actualColor[0] = hue;
106 finalShader = null;
107 invalidate();
108 }
109
114 public int getColor() {
115 return Color.HSVToColor(actualColor);
116 }
117
122 public void getColor(float[] vals) {
123 vals[0] = actualColor[0];
124 vals[1] = actualColor[1];
125 vals[2] = actualColor[2];
126 }
127
132 public void setColor(int color) {
133 Color.colorToHSV(color, actualColor);
134 fullColor[0] = actualColor[0];
135 cursorX = actualColor[1] * lengthX;
136 cursorY = (1 - actualColor[2]) * lengthY;
137 finalShader = null;
138 invalidate();
139 }
140
145 public void setColor(float[] hsvColor) {
146 actualColor[0] = hsvColor[0];
147 actualColor[1] = hsvColor[1];
148 actualColor[2] = hsvColor[2];
149 fullColor[0] = actualColor[0];
150 cursorX = actualColor[1] * lengthX;
151 cursorY = (1 - actualColor[2]) * lengthY;
152 finalShader = null;
153 invalidate();
154 }
155
160 public float getSaturation() {
161 return actualColor[1];
162 }
163
168 public void setSaturation(float saturation) {
169 actualColor[1] = saturation;
170 cursorX = actualColor[1] * lengthX;
171 invalidate();
172 }
173
178 public float getValue() {
179 return actualColor[2];
180 }
181
186 public void setValue(float value) {
187 actualColor[2] = value;
188 cursorY = (1 - actualColor[2]) * lengthY;
189 invalidate();
190 }
191
192 //----- Pomocné metody ----------------------------------------------------------------------------------------------------------------------//
193 //----- Konstruktory ------------------------------------------------------------------------------------------------------------------------//
194 public SVPickerView(Context context) {
195 super(context);
196 init();
197 }
198
199 public SVPickerView(Context context, AttributeSet attrs) {
200 super(context, attrs);
201 init();
202 }
203
204 public SVPickerView(Context context, AttributeSet attrs, int defStyle) {
205 super(context, attrs, defStyle);
206 init();
207 }
208
212 protected void init() {
213 setLayerType(View.LAYER_TYPE_SOFTWARE, null);
214 cursorPressed = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_control_pressed_bw);
215 cursorNormal = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_control_normal_bw);
216 cursor = cursorNormal;
217 margin = cursor.getWidth() / 2;
218 paint = new Paint();
219 // drCursor = (StateListDrawable) getResources().getDrawable(R.drawable.bw_scrubber);
220 // drCursor.setState(new int[] { android.R.attr.state_enabled });
221 // margin = drCursor.getIntrinsicWidth() / 2;
222 }
223
224 @Override
225 public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
226 int width = MeasureSpec.getSize(widthMeasureSpec);
227 int height = MeasureSpec.getSize(heightMeasureSpec);
228 // Abychom získaly největší možný čtverec, je nutné nastavit řídící rozměr a ten co se má přizpůsobit na 0. Obrácený postup s hledáním minima nefunguje...
229 if (width < height) {
230 width = height;
231 } else {
232 height = width;
233 }
234 setMeasuredDimension(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
235 }
236
238 @Override
239 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
240 super.onSizeChanged(w, h, oldw, oldh);
241
242 // if (getLayoutParams() != null && w != h) {
243 // getLayoutParams().height = w;
244 // setLayoutParams(getLayoutParams());
245 // }
246
247
248 minX = margin;
249 maxX = w - margin;
250 lengthX = maxX - margin;
251 minY = margin;
252 maxY = h - margin;
253 lengthY = maxY - margin;
254 cursorX = actualColor[1] * lengthX;
255 cursorY = (1 - actualColor[2]) * lengthY;
256 baseShader = new LinearGradient(minX, minY, minX, maxY, 0xFFFFFFFF, 0xFF000000, TileMode.CLAMP);
257 finalShader = null;
258 }
259
261 @Override
262 protected void onDraw(Canvas canvas) {
263 if (finalShader == null) {
264 int rgb = Color.HSVToColor(fullColor);
265 Shader topShader = new LinearGradient(minX, minY, maxX, minY, 0xffffffff, rgb, TileMode.CLAMP);
266 finalShader = new ComposeShader(baseShader, topShader, PorterDuff.Mode.MULTIPLY);
267 paint.setShader(finalShader);
268 }
269 canvas.drawRect(minX, minY, maxX, maxY, paint);
270 canvas.drawBitmap(cursor, cursorX, cursorY, null);
271 }
272
274 @Override
275 public boolean onTouchEvent(MotionEvent ev) {
276 switch (ev.getAction()) {
277 case MotionEvent.ACTION_DOWN:
278 cursor = cursorPressed;
279 // drCursor.setState(new int[] {android.R.attr.state_pressed, android.R.attr.state_enabled});
280 break;
281 case MotionEvent.ACTION_UP:
282 cursor = cursorNormal;
283 // drCursor.setState(new int[] {android.R.attr.state_enabled});
284 break;
285 }
286 float x = ev.getX();
287 float y = ev.getY();
288 if (x < minX) {
289 cursorX = 0;
290 } else if (x > maxX) {
291 cursorX = maxX - margin;
292 } else {
293 cursorX = (int) x - margin;
294 }
295 if (y < minY) {
296 cursorY = 0;
297 } else if (y > maxY) {
298 cursorY = maxY - margin;
299 } else {
300 cursorY = (int) y - margin;
301 }
302 actualColor[1] = cursorX / lengthX;
303 actualColor[2] = 1 - cursorY / lengthY;
304 if (listener != null) {
305 switch (ev.getAction()) {
306 case MotionEvent.ACTION_DOWN:
307 listener.onSVPickerStartTrackingTouch(this);
308 break;
309 case MotionEvent.ACTION_UP:
310 listener.onSVPickerStopTrackingTouch(this);
311 break;
312 }
313 listener.onSVPickerChange(this);
314 }
315 invalidate();
316 ViewParent parent = getParent();
317 if (parent != null) {
318 parent.requestDisallowInterceptTouchEvent(true);
319 }
320 return true;
321 }
322 }