App
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;
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 
111 
112  protected View overlay;
113  protected boolean enabled = true;
114 
115  //----- Accessory a primitivní metody -------------------------------------------------------------------------------------------------------//
116 
118  this.selectedListener = selectedListener;
119  }
120 
122  this.changedListener = changedListener;
123  }
124 
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);
392  selectBtn.setOnClickListener(this);
393  cancelBtn.setOnClickListener(this);
394  oldColorV.setOnClickListener(this);
395 
396  // Nastaveni spravneho typu pozadi pro seekbary
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 
536  hueValueSB.invalidate();
538  saturationValueSB.invalidate();
539  setSeekBarGradient(valueValueSB, new int[] { 0xFF000000, getFullValueSelColor() });
540  valueValueSB.invalidate();
541  }
542 
546  protected void updateSVPicker() {
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) {
591  } else if (seekBar == hueValueSB) {
593  } else if (seekBar == saturationValueSB || seekBar == valueValueSB) {
595  }
596  if (changedListener != null) {
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) {
619  }
620  } else if (v == cancelBtn) {
622  if (changedListener != null) {
624  }
625  if (canceledListener != null) {
627  }
628  } else if (v == oldColorV) {
630  if (changedListener != null) {
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) {
646  }
647  }
648 
649  @Override
651  // Nevyužitá událost SVPickeru
652  }
653 
654  @Override
656  // Nevyužitá událost SeekBaru
657  }
658 }