App

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

- File List
- File Members

ColorPickerView.java
Go to the documentation of this file.
1 package mhr.appandroid.views.colorpicker;
2
3 import mhr.appandroid.R;
4 import mhr.appandroid.views.colorpicker.SVPickerView.OnSVPickerChangeListener;
5 import android.app.Activity;
6 import android.content.Context;
7 import android.graphics.Color;
8 import android.graphics.LinearGradient;
9 import android.graphics.Paint;
10 import android.graphics.Paint.Style;
11 import android.graphics.Path;
12 import android.graphics.Shader;
13 import android.graphics.Shader.TileMode;
14 import android.graphics.drawable.Drawable;
15 import android.graphics.drawable.GradientDrawable;
16 import android.graphics.drawable.ScaleDrawable;
17 import android.graphics.drawable.ShapeDrawable;
18 import android.graphics.drawable.GradientDrawable.Orientation;
19 import android.graphics.drawable.shapes.PathShape;
20 import android.graphics.drawable.shapes.RectShape;
21 import android.os.Bundle;
22 import android.os.Parcelable;
23 import android.util.AttributeSet;
24 import android.view.View;
25 import android.widget.Button;
26 import android.widget.FrameLayout;
27 import android.widget.SeekBar;
28 import android.widget.SeekBar.OnSeekBarChangeListener;
29 import android.widget.TextView;
30 import android.widget.Toast;
31 import android.view.View.OnClickListener;
32
49 public class ColorPickerView extends FrameLayout implements OnSeekBarChangeListener, OnSVPickerChangeListener, OnClickListener {
50
51 //----- Interface ---------------------------------------------------------------------------------------------------------------------------//
52
53 public interface OnColorSelectedListener {
59 public void onColorSelected(ColorPickerView v);
60 }
61
62 public interface OnColorChangedListener {
68 public void onColorChanged(ColorPickerView v);
69 }
70
71 public interface OnColorCanceledListener {
77 public void onColorCanceled(ColorPickerView v);
78 }
79
80 //----- Pole --------------------------------------------------------------------------------------------------------------------------------//
81 protected SeekBar redValueSB;
82 protected SeekBar greenValueSB;
83 protected SeekBar blueValueSB;
84 protected SeekBar hueValueSB;
85 protected SeekBar saturationValueSB;
86 protected SeekBar valueValueSB;
87 protected SVPickerView svPicker;
88
89 protected View newColorV;
90 protected View oldColorV;
91
92 protected TextView redValueTV;
93 protected TextView greenValueTV;
94 protected TextView blueValueTV;
95 protected TextView hueValueTV;
96 protected TextView saturationValueTV;
97 protected TextView valueValueTV;
98
99 protected Button selectBtn;
100 protected Button cancelBtn;
101
102 protected int newColor = 0xFF000000;
103 protected int oldColor = 0xFF000000;
104 protected float[] newColorHSV = new float[3];
105 protected int[] newColorRGB = new int[3];
106 protected float[] tmp = new float[3];
107
108 protected OnColorSelectedListener selectedListener = null;
109 protected OnColorChangedListener changedListener = null;
110 protected OnColorCanceledListener canceledListener = null;
111
112 protected View overlay;
113 protected boolean enabled = true;
114
115 //----- Accessory a primitivní metody -------------------------------------------------------------------------------------------------------//
116
117 public void setOnSelectedListener(OnColorSelectedListener selectedListener) {
118 this.selectedListener = selectedListener;
119 }
120
121 public void setOnChangedListener(OnColorChangedListener changedListener) {
122 this.changedListener = changedListener;
123 }
124
125 public void setOnCanceledListener(OnColorCanceledListener canceledListener) {
126 this.canceledListener = canceledListener;
127 }
128
129 public int getNewColor() {
130 return newColor;
131 }
132
133 public int getOldColor() {
134 return oldColor;
135 }
136
137 public int getNativeNewColor() {
138 return getNativeColor(newColor);
139 }
140
141 public int getNativeOldColor() {
142 return getNativeColor(oldColor);
143 }
144
145 public void setNewColor(int color) {
146 setColor(color);
147 updateRGBSeekBars(true);
148 updateHSVSeekBars(true);
149 updateSVPicker();
150 updateNewColor();
151 }
152
153 public void setOldColor(int color) {
154 oldColor = color;
155 oldColorV.setBackgroundColor(oldColor);
156 }
157
158 public void setNativeOldColor(int nativeColor) {
159 oldColor = getAndroidColor(nativeColor);
160 oldColorV.setBackgroundColor(oldColor);
161 }
162
163 public void setNativeNewColor(int nativeColor) {
164 setNewColor(getAndroidColor(nativeColor));
165 }
166
171 public void setState(int color) {
172 setNewColor(color);
173 setOldColor(color);
174 }
175
180 public void setNativeState(int nativeColor) {
181 setNativeNewColor(nativeColor);
182 setNativeOldColor(nativeColor);
183 }
184
189 public void setPickerEnabled(Boolean enabled) {
190 this.enabled = enabled;
191 if (enabled) {
192 overlay.setVisibility(VISIBLE);
193 } else {
194 overlay.setVisibility(GONE);
195 }
196 }
197
198 public boolean isPickerEnabled() {
199 return enabled;
200 }
201
202 //----- Pomocné metody ----------------------------------------------------------------------------------------------------------------------//
203
209 protected void initSeekBar(SeekBar sb) {
210 Path pth = new Path(); // Cara presne uprostred
211 pth.moveTo(0, 50);
212 pth.lineTo(100, 50);
213 ShapeDrawable sdr = new ShapeDrawable(new PathShape(pth, 100, 100));
214 Paint paint = sdr.getPaint();
215 paint.setStyle(Style.STROKE);
216 paint.setStrokeWidth(20); // tloustka je 20%
217 sb.setProgressDrawable(sdr);
218 }
219
227 protected int getNativeColor(int r, int g, int b) {
228 // Nativni: 0xAABBGGRR Android:0xAARRGGBB
229 return 0xFF000000 | (b << 16) | (g << 8) | r;
230 }
231
237 protected int getNativeColor(int clr) {
238 // Nativni: 0xAABBGGRR Android:0xAARRGGBB
239 return 0xFF000000 | ((clr & 0x000000FF) << 16) | (clr & 0x0000FF00) | ((clr & 0x00FF0000) >> 16);
240 }
241
247 protected int getAndroidColor(int nativeClr) {
248 // Nativni: 0xAABBGGRR Android:0xAARRGGBB
249 return 0xFF000000 | ((nativeClr & 0x000000FF) << 16) | (nativeClr & 0x0000FF00) | ((nativeClr & 0x00FF0000) >> 16);
250 }
251
257 protected void setSeekBarGradient(SeekBar sb, int[] colors) {
258 ((ShapeDrawable) sb.getProgressDrawable()).getPaint().setShader(new LinearGradient(0, 0, 100, 0, colors, null, TileMode.CLAMP));
259 }
260
265 protected int getFullySaturatedSelColor() {
266 tmp[0] = newColorHSV[0];
267 tmp[1] = 1.000f;
268 tmp[2] = newColorHSV[2];
269 return Color.HSVToColor(tmp);
270 }
271
276 protected int getFullValueSelColor() {
277 tmp[0] = newColorHSV[0];
278 tmp[1] = newColorHSV[1];
279 tmp[2] = 1.000f;
280 return Color.HSVToColor(tmp);
281 }
282
287 protected int getFullyDesaturatedSelColor() {
288 tmp[0] = newColorHSV[0];
289 tmp[1] = 0.000f;
290 tmp[2] = newColorHSV[2];
291 return Color.HSVToColor(tmp);
292 }
293
298 protected int[] getHueSwatchForNewColor() {
299 int[] retVal = new int[7];
300
301 tmp[1] = newColorHSV[1];
302 tmp[2] = newColorHSV[2];
303
304 tmp[0] = 0;
305 retVal[0] = Color.HSVToColor(tmp);
306
307 tmp[0] = 60;
308 retVal[1] = Color.HSVToColor(tmp);
309
310 tmp[0] = 120;
311 retVal[2] = Color.HSVToColor(tmp);
312
313 tmp[0] = 180;
314 retVal[3] = Color.HSVToColor(tmp);
315
316 tmp[0] = 240;
317 retVal[4] = Color.HSVToColor(tmp);
318
319 tmp[0] = 300;
320 retVal[5] = Color.HSVToColor(tmp);
321
322 tmp[0] = 360;
323 retVal[6] = Color.HSVToColor(tmp);
324
325 return retVal;
326 }
327
328 //----- Konstruktory ------------------------------------------------------------------------------------------------------------------------//
329 public ColorPickerView(Context context) {
330 super(context);
331 init();
332 }
333
334 public ColorPickerView(Context context, AttributeSet attrs) {
335 super(context, attrs);
336 init();
337 }
338
339 public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
340 super(context, attrs, defStyle);
341 init();
342 }
343
347 protected void init() {
348 if (isInEditMode()) {
349 TextView tv = new TextView(getContext());
350 tv.setText("ColorPickerView, preview not availiable.");
351 addView(tv);
352 return;
353 }
354 try {
355 ((Activity) getContext()).getLayoutInflater().inflate(R.layout.view_color_picker, this, true);
356 } catch (ClassCastException exc) {
357 // Tento kod probehne, pokud je poroblem s pretypovanim, napriklad pro nahled v Eclipse, behem behu programu by nemel nastat
358 TextView tv = new TextView(getContext());
359 tv.setText("Prewiew not available, requires Activity to be Context.");
360 addView(tv);
361 return;
362 }
363
364 // Inicializace promennych, pro rychly pristup k prvkum formulare
365 redValueSB = (SeekBar) findViewById(R.id.RedValueSB);
366 greenValueSB = (SeekBar) findViewById(R.id.GreenValueSB);
367 blueValueSB = (SeekBar) findViewById(R.id.BlueValueSB);
368 hueValueSB = (SeekBar) findViewById(R.id.HueValueSB);
369 saturationValueSB = (SeekBar) findViewById(R.id.SaturationValueSB);
370 valueValueSB = (SeekBar) findViewById(R.id.ValueValueSB);
371 svPicker = (SVPickerView) findViewById(R.id.SVPicker);
372 redValueTV = (TextView) findViewById(R.id.RedValueTV);
373 greenValueTV = (TextView) findViewById(R.id.GreenValueTV);
374 blueValueTV = (TextView) findViewById(R.id.BlueValueTV);
375 hueValueTV = (TextView) findViewById(R.id.HueValueTV);
376 saturationValueTV = (TextView) findViewById(R.id.SaturationValueTV);
377 valueValueTV = (TextView) findViewById(R.id.ValueValueTV);
378 newColorV = findViewById(R.id.NewColorView);
379 oldColorV = findViewById(R.id.OldColorView);
380 selectBtn = (Button) findViewById(R.id.SelectColorBtn);
381 cancelBtn = (Button) findViewById(R.id.CancelColorBtn);
382 overlay = findViewById(R.id.ColorPickerDisabledOverlay);
383
384 // Nastaveni sebe jako posluchace udalosti potomku.
385 redValueSB.setOnSeekBarChangeListener(this);
386 greenValueSB.setOnSeekBarChangeListener(this);
387 blueValueSB.setOnSeekBarChangeListener(this);
388 hueValueSB.setOnSeekBarChangeListener(this);
389 saturationValueSB.setOnSeekBarChangeListener(this);
390 valueValueSB.setOnSeekBarChangeListener(this);
391 svPicker.setOnSVChangedListener(this);
392 selectBtn.setOnClickListener(this);
393 cancelBtn.setOnClickListener(this);
394 oldColorV.setOnClickListener(this);
395
396 // Nastaveni spravneho typu pozadi pro seekbary
397 initSeekBar(redValueSB);
398 initSeekBar(greenValueSB);
399 initSeekBar(blueValueSB);
400 initSeekBar(hueValueSB);
401 initSeekBar(saturationValueSB);
402 initSeekBar(valueValueSB);
403
404 // Nastaveni barev
405 setNewColor(0xFFFFFFFF);
406 setOldColor(0xFF000000);
407 }
408
409 @Override
410 public void onRestoreInstanceState(Parcelable state) {
411 if (state instanceof Bundle) {
412 Bundle bundle = (Bundle) state;
413 setOldColor(bundle.getInt("oldColor"));
414 setNewColor(bundle.getInt("newColor"));
415 super.onRestoreInstanceState(bundle.getParcelable("instanceState"));
416 return;
417 }
418
419 super.onRestoreInstanceState(state);
420 }
421 //----- Destruktory -------------------------------------------------------------------------------------------------------------------------//
422
423 @Override
424 public Parcelable onSaveInstanceState() {
425 Bundle bundle = new Bundle();
426 bundle.putParcelable("instanceState", super.onSaveInstanceState());
427 bundle.putInt("newColor", newColor);
428 bundle.putInt("oldColor", oldColor);
429 return bundle;
430 }
431 //----- Metody ------------------------------------------------------------------------------------------------------------------------------//
432
437 protected void setColor(int color) {
438 newColor = color;
439 newColorRGB[0] = (newColor & 0x00FF0000) >> 16;
440 newColorRGB[1] = (newColor & 0x0000FF00) >> 8;
441 newColorRGB[2] = (newColor & 0x000000FF);
442 Color.colorToHSV(newColor, newColorHSV);
443 }
444
449 protected void setColor(int r, int g, int b) {
450 newColor = 0xFF000000 | (r << 16) | (g << 8) | b;
451 newColorRGB[0] = r;
452 newColorRGB[1] = g;
453 newColorRGB[2] = b;
454 Color.colorToHSV(newColor, newColorHSV);
455 }
456
461 protected void setColor(float[] color) {
462 newColor = Color.HSVToColor(color);
463 newColorRGB[0] = (newColor & 0x00FF0000) >> 16;
464 newColorRGB[1] = (newColor & 0x0000FF00) >> 8;
465 newColorRGB[2] = (newColor & 0x000000FF);
466 newColorHSV[0] = color[0];
467 newColorHSV[1] = color[1];
468 newColorHSV[2] = color[2];
469 }
470
475 protected void setColor(float h, float s, float v) {
476 newColorHSV[0] = h;
477 newColorHSV[1] = s;
478 newColorHSV[2] = v;
479 newColor = Color.HSVToColor(newColorHSV);
480 newColorRGB[0] = (newColor & 0x00FF0000) >> 16;
481 newColorRGB[1] = (newColor & 0x0000FF00) >> 8;
482 newColorRGB[2] = (newColor & 0x000000FF);
483 }
484
488 protected void updateNewColor() {
489 newColorV.setBackgroundColor(newColor);
490 }
491
497 protected void updateRGBSeekBars(boolean reposition) {
498 if (reposition) {
499 redValueSB.setProgress(newColorRGB[0]);
500 greenValueSB.setProgress(newColorRGB[1]);
501 blueValueSB.setProgress(newColorRGB[2]);
502 }
503
504 redValueTV.setText(Integer.toString(newColorRGB[0]));
505 greenValueTV.setText(Integer.toString(newColorRGB[1]));
506 blueValueTV.setText(Integer.toString(newColorRGB[2]));
507
508 setSeekBarGradient(redValueSB, new int[] { (newColor & 0xFF00FFFF), (newColor & 0xFF00FFFF) | 0x00FF0000 });
509 redValueSB.invalidate();
510 setSeekBarGradient(greenValueSB, new int[] { (newColor & 0xFFFF00FF), (newColor & 0xFFFF00FF) | 0x0000FF00 });
511 greenValueSB.invalidate();
512 setSeekBarGradient(blueValueSB, new int[] { (newColor & 0xFFFFFF00), (newColor & 0xFFFFFF00) | 0x000000FF });
513 blueValueSB.invalidate();
514
515 }
516
522 protected void updateHSVSeekBars(boolean reposition) {
523 int h = Math.round(newColorHSV[0]);
524 int s = Math.round(newColorHSV[1] * 255);
525 int v = Math.round(newColorHSV[2] * 255);
526 if (reposition) {
527 hueValueSB.setProgress(h);
528 saturationValueSB.setProgress(s);
529 valueValueSB.setProgress(v);
530 }
531 hueValueTV.setText(Integer.toString(h));
532 saturationValueTV.setText(Integer.toString(s));
533 valueValueTV.setText(Integer.toString(v));
534
535 setSeekBarGradient(hueValueSB, getHueSwatchForNewColor());
536 hueValueSB.invalidate();
537 setSeekBarGradient(saturationValueSB, new int[] { getFullyDesaturatedSelColor(), getFullySaturatedSelColor() });
538 saturationValueSB.invalidate();
539 setSeekBarGradient(valueValueSB, new int[] { 0xFF000000, getFullValueSelColor() });
540 valueValueSB.invalidate();
541 }
542
546 protected void updateSVPicker() {
547 svPicker.setColor(newColorHSV);
548 }
549
553 protected void updateStateFromRGBSeekBars() {
554 setColor(redValueSB.getProgress(), greenValueSB.getProgress(), blueValueSB.getProgress());
555 updateRGBSeekBars(false);
556 updateHSVSeekBars(true);
557 updateSVPicker();
558 updateNewColor();
559 }
560
564 protected void updateStateFromHSeekBar() {
565 setColor(hueValueSB.getProgress(), newColorHSV[1], newColorHSV[2]);
566 updateRGBSeekBars(true);
567 updateHSVSeekBars(false);
568 updateSVPicker();
569 updateNewColor();
570 }
571
575 protected void updateStateFromSVSeekBars() {
576 setColor(hueValueSB.getProgress(), saturationValueSB.getProgress() / 255.f, valueValueSB.getProgress() / 255.f);
577 updateRGBSeekBars(true);
578 updateHSVSeekBars(false);
579 updateSVPicker();
580 updateNewColor();
581 }
582
584 @Override
585 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
586 if (!fromUser) {
587 return;
588 }
589 if (seekBar == redValueSB || seekBar == greenValueSB || seekBar == blueValueSB) {
590 updateStateFromRGBSeekBars();
591 } else if (seekBar == hueValueSB) {
592 updateStateFromHSeekBar();
593 } else if (seekBar == saturationValueSB || seekBar == valueValueSB) {
594 updateStateFromSVSeekBars();
595 }
596 if (changedListener != null) {
597 changedListener.onColorChanged(this);
598 }
599 }
600
601 @Override
602 public void onStartTrackingTouch(SeekBar seekBar) {
603 // Nevyužitá událost SeekBaru
604 }
605
606 @Override
607 public void onStopTrackingTouch(SeekBar seekBar) {
608 // Nevyužitá událost SeekBaru
609 }
610
612 @Override
613 public void onClick(View v) {
614 if (v == selectBtn) {
615 oldColor = newColor;
616 oldColorV.setBackgroundColor(oldColor);
617 if (selectedListener != null) {
618 selectedListener.onColorSelected(this);
619 }
620 } else if (v == cancelBtn) {
621 setNewColor(oldColor);
622 if (changedListener != null) {
623 changedListener.onColorChanged(this);
624 }
625 if (canceledListener != null) {
626 canceledListener.onColorCanceled(this);
627 }
628 } else if (v == oldColorV) {
629 setNewColor(oldColor);
630 if (changedListener != null) {
631 changedListener.onColorChanged(this);
632 }
633 }
634 }
635
637 @Override
638 public void onSVPickerChange(SVPickerView picker) {
639 picker.getColor(tmp);
640 setColor(tmp);
641 updateRGBSeekBars(true);
642 updateHSVSeekBars(true);
643 updateNewColor();
644 if (changedListener != null) {
645 changedListener.onColorChanged(this);
646 }
647 }
648
649 @Override
650 public void onSVPickerStartTrackingTouch(SVPickerView picker) {
651 // Nevyužitá událost SVPickeru
652 }
653
654 @Override
655 public void onSVPickerStopTrackingTouch(SVPickerView picker) {
656 // Nevyužitá událost SeekBaru
657 }
658 }