OSDN Git Service

Automatic translation import
[android-x86/packages-apps-Eleven.git] / src / com / cyngn / eleven / widgets / ColorPickerView.java
1 /*
2  * Copyright (C) 2010 Daniel Nilsson Copyright (C) 2012 THe CyanogenMod Project
3  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
4  * use this file except in compliance with the License. You may obtain a copy of
5  * the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
6  * applicable law or agreed to in writing, software distributed under the
7  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
8  * OF ANY KIND, either express or implied. See the License for the specific
9  * language governing permissions and limitations under the License.
10  */
11
12 package com.cyngn.eleven.widgets;
13
14 import android.content.Context;
15 import android.graphics.Canvas;
16 import android.graphics.Color;
17 import android.graphics.ComposeShader;
18 import android.graphics.LinearGradient;
19 import android.graphics.Paint;
20 import android.graphics.Paint.Align;
21 import android.graphics.Paint.Style;
22 import android.graphics.Point;
23 import android.graphics.PorterDuff;
24 import android.graphics.RectF;
25 import android.graphics.Shader;
26 import android.graphics.Shader.TileMode;
27 import android.util.AttributeSet;
28 import android.view.MotionEvent;
29 import android.view.View;
30
31 /**
32  * Displays a color picker to the user and allow them to select a color. A
33  * slider for the alpha channel is also available. Enable it by setting
34  * setAlphaSliderVisible(boolean) to true.
35  * 
36  * @author Daniel Nilsson
37  */
38 public class ColorPickerView extends View {
39
40     public interface OnColorChangedListener {
41         public void onColorChanged(int color);
42     }
43
44     private final static int PANEL_SAT_VAL = 0;
45
46     private final static int PANEL_HUE = 1;
47
48     private final static int PANEL_ALPHA = 2;
49
50     /**
51      * The width in pixels of the border surrounding all color panels.
52      */
53     private final static float BORDER_WIDTH_PX = 1;
54
55     /**
56      * The width in dp of the hue panel.
57      */
58     private float HUE_PANEL_WIDTH = 30f;
59
60     /**
61      * The height in dp of the alpha panel
62      */
63     private float ALPHA_PANEL_HEIGHT = 20f;
64
65     /**
66      * The distance in dp between the different color panels.
67      */
68     private float PANEL_SPACING = 10f;
69
70     /**
71      * The radius in dp of the color palette tracker circle.
72      */
73     private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
74
75     /**
76      * The dp which the tracker of the hue or alpha panel will extend outside of
77      * its bounds.
78      */
79     private float RECTANGLE_TRACKER_OFFSET = 2f;
80
81     private static float mDensity = 1f;
82
83     private OnColorChangedListener mListener;
84
85     private Paint mSatValPaint;
86
87     private Paint mSatValTrackerPaint;
88
89     private Paint mHuePaint;
90
91     private Paint mHueTrackerPaint;
92
93     private Paint mAlphaPaint;
94
95     private Paint mAlphaTextPaint;
96
97     private Paint mBorderPaint;
98
99     private Shader mValShader;
100
101     private Shader mSatShader;
102
103     private Shader mHueShader;
104
105     private Shader mAlphaShader;
106
107     private int mAlpha = 0xff;
108
109     private float mHue = 360f;
110
111     private float mSat = 0f;
112
113     private float mVal = 0f;
114
115     private String mAlphaSliderText = "Alpha";
116
117     private int mSliderTrackerColor = 0xff1c1c1c;
118
119     private int mBorderColor = 0xff6E6E6E;
120
121     private boolean mShowAlphaPanel = false;
122
123     /*
124      * To remember which panel that has the "focus" when processing hardware
125      * button data.
126      */
127     private int mLastTouchedPanel = PANEL_SAT_VAL;
128
129     /**
130      * Offset from the edge we must have or else the finger tracker will get
131      * clipped when it is drawn outside of the view.
132      */
133     private float mDrawingOffset;
134
135     /*
136      * Distance form the edges of the view of where we are allowed to draw.
137      */
138     private RectF mDrawingRect;
139
140     private RectF mSatValRect;
141
142     private RectF mHueRect;
143
144     private RectF mAlphaRect;
145
146     private AlphaPatternDrawable mAlphaPattern;
147
148     private Point mStartTouchPoint = null;
149
150     public ColorPickerView(final Context context) {
151         this(context, null);
152     }
153
154     public ColorPickerView(final Context context, final AttributeSet attrs) {
155         this(context, attrs, 0);
156     }
157
158     public ColorPickerView(final Context context, final AttributeSet attrs, final int defStyle) {
159         super(context, attrs, defStyle);
160         init();
161     }
162
163     private void init() {
164         mDensity = getContext().getResources().getDisplayMetrics().density;
165         PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
166         RECTANGLE_TRACKER_OFFSET *= mDensity;
167         HUE_PANEL_WIDTH *= mDensity;
168         ALPHA_PANEL_HEIGHT *= mDensity;
169         PANEL_SPACING = PANEL_SPACING * mDensity;
170
171         mDrawingOffset = calculateRequiredOffset();
172
173         initPaintTools();
174
175         // Needed for receiving track ball motion events.
176         setFocusable(true);
177         setFocusableInTouchMode(true);
178     }
179
180     private void initPaintTools() {
181
182         mSatValPaint = new Paint();
183         mSatValTrackerPaint = new Paint();
184         mHuePaint = new Paint();
185         mHueTrackerPaint = new Paint();
186         mAlphaPaint = new Paint();
187         mAlphaTextPaint = new Paint();
188         mBorderPaint = new Paint();
189
190         mSatValTrackerPaint.setStyle(Style.STROKE);
191         mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
192         mSatValTrackerPaint.setAntiAlias(true);
193
194         mHueTrackerPaint.setColor(mSliderTrackerColor);
195         mHueTrackerPaint.setStyle(Style.STROKE);
196         mHueTrackerPaint.setStrokeWidth(2f * mDensity);
197         mHueTrackerPaint.setAntiAlias(true);
198
199         mAlphaTextPaint.setColor(0xff1c1c1c);
200         mAlphaTextPaint.setTextSize(14f * mDensity);
201         mAlphaTextPaint.setAntiAlias(true);
202         mAlphaTextPaint.setTextAlign(Align.CENTER);
203         mAlphaTextPaint.setFakeBoldText(true);
204
205     }
206
207     private float calculateRequiredOffset() {
208         float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
209         offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
210
211         return offset * 1.5f;
212     }
213
214     private int[] buildHueColorArray() {
215
216         final int[] hue = new int[361];
217
218         int count = 0;
219         for (int i = hue.length - 1; i >= 0; i--, count++) {
220             hue[count] = Color.HSVToColor(new float[] {
221                     i, 1f, 1f
222             });
223         }
224
225         return hue;
226     }
227
228     @Override
229     protected void onDraw(final Canvas canvas) {
230
231         if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) {
232             return;
233         }
234
235         drawSatValPanel(canvas);
236         drawHuePanel(canvas);
237         drawAlphaPanel(canvas);
238
239     }
240
241     private void drawSatValPanel(final Canvas canvas) {
242
243         final RectF rect = mSatValRect;
244
245         if (BORDER_WIDTH_PX > 0) {
246             mBorderPaint.setColor(mBorderColor);
247             canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX,
248                     rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
249         }
250
251         if (mValShader == null) {
252             mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
253                     0xffffffff, 0xff000000, TileMode.CLAMP);
254         }
255
256         final int rgb = Color.HSVToColor(new float[] {
257                 mHue, 1f, 1f
258         });
259
260         mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, 0xffffffff, rgb,
261                 TileMode.CLAMP);
262         final ComposeShader mShader = new ComposeShader(mValShader, mSatShader,
263                 PorterDuff.Mode.MULTIPLY);
264         mSatValPaint.setShader(mShader);
265
266         canvas.drawRect(rect, mSatValPaint);
267
268         final Point p = satValToPoint(mSat, mVal);
269
270         mSatValTrackerPaint.setColor(0xff000000);
271         canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity,
272                 mSatValTrackerPaint);
273
274         mSatValTrackerPaint.setColor(0xffdddddd);
275         canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
276
277     }
278
279     private void drawHuePanel(final Canvas canvas) {
280
281         final RectF rect = mHueRect;
282
283         if (BORDER_WIDTH_PX > 0) {
284             mBorderPaint.setColor(mBorderColor);
285             canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right
286                     + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
287         }
288
289         if (mHueShader == null) {
290             mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
291                     buildHueColorArray(), null, TileMode.CLAMP);
292             mHuePaint.setShader(mHueShader);
293         }
294
295         canvas.drawRect(rect, mHuePaint);
296
297         final float rectHeight = 4 * mDensity / 2;
298
299         final Point p = hueToPoint(mHue);
300
301         final RectF r = new RectF();
302         r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
303         r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
304         r.top = p.y - rectHeight;
305         r.bottom = p.y + rectHeight;
306
307         canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
308
309     }
310
311     private void drawAlphaPanel(final Canvas canvas) {
312
313         if (!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) {
314             return;
315         }
316
317         final RectF rect = mAlphaRect;
318
319         if (BORDER_WIDTH_PX > 0) {
320             mBorderPaint.setColor(mBorderColor);
321             canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right
322                     + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
323         }
324
325         mAlphaPattern.draw(canvas);
326
327         final float[] hsv = new float[] {
328                 mHue, mSat, mVal
329         };
330         final int color = Color.HSVToColor(hsv);
331         final int acolor = Color.HSVToColor(0, hsv);
332
333         mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, color, acolor,
334                 TileMode.CLAMP);
335
336         mAlphaPaint.setShader(mAlphaShader);
337
338         canvas.drawRect(rect, mAlphaPaint);
339
340         if (mAlphaSliderText != null && mAlphaSliderText != "") {
341             canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity,
342                     mAlphaTextPaint);
343         }
344
345         final float rectWidth = 4 * mDensity / 2;
346
347         final Point p = alphaToPoint(mAlpha);
348
349         final RectF r = new RectF();
350         r.left = p.x - rectWidth;
351         r.right = p.x + rectWidth;
352         r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
353         r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
354
355         canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
356
357     }
358
359     private Point hueToPoint(final float hue) {
360
361         final RectF rect = mHueRect;
362         final float height = rect.height();
363
364         final Point p = new Point();
365
366         p.y = (int)(height - hue * height / 360f + rect.top);
367         p.x = (int)rect.left;
368
369         return p;
370     }
371
372     private Point satValToPoint(final float sat, final float val) {
373
374         final RectF rect = mSatValRect;
375         final float height = rect.height();
376         final float width = rect.width();
377
378         final Point p = new Point();
379
380         p.x = (int)(sat * width + rect.left);
381         p.y = (int)((1f - val) * height + rect.top);
382
383         return p;
384     }
385
386     private Point alphaToPoint(final int alpha) {
387
388         final RectF rect = mAlphaRect;
389         final float width = rect.width();
390
391         final Point p = new Point();
392
393         p.x = (int)(width - alpha * width / 0xff + rect.left);
394         p.y = (int)rect.top;
395
396         return p;
397
398     }
399
400     private float[] pointToSatVal(float x, float y) {
401
402         final RectF rect = mSatValRect;
403         final float[] result = new float[2];
404
405         final float width = rect.width();
406         final float height = rect.height();
407
408         if (x < rect.left) {
409             x = 0f;
410         } else if (x > rect.right) {
411             x = width;
412         } else {
413             x = x - rect.left;
414         }
415
416         if (y < rect.top) {
417             y = 0f;
418         } else if (y > rect.bottom) {
419             y = height;
420         } else {
421             y = y - rect.top;
422         }
423
424         result[0] = 1.f / width * x;
425         result[1] = 1.f - 1.f / height * y;
426
427         return result;
428     }
429
430     private float pointToHue(float y) {
431
432         final RectF rect = mHueRect;
433
434         final float height = rect.height();
435
436         if (y < rect.top) {
437             y = 0f;
438         } else if (y > rect.bottom) {
439             y = height;
440         } else {
441             y = y - rect.top;
442         }
443
444         return 360f - y * 360f / height;
445     }
446
447     private int pointToAlpha(int x) {
448
449         final RectF rect = mAlphaRect;
450         final int width = (int)rect.width();
451
452         if (x < rect.left) {
453             x = 0;
454         } else if (x > rect.right) {
455             x = width;
456         } else {
457             x = x - (int)rect.left;
458         }
459
460         return 0xff - x * 0xff / width;
461
462     }
463
464     @Override
465     public boolean onTrackballEvent(final MotionEvent event) {
466
467         final float x = event.getX();
468         final float y = event.getY();
469
470         boolean update = false;
471
472         if (event.getAction() == MotionEvent.ACTION_MOVE) {
473
474             switch (mLastTouchedPanel) {
475
476                 case PANEL_SAT_VAL:
477
478                     float sat,
479                     val;
480
481                     sat = mSat + x / 50f;
482                     val = mVal - y / 50f;
483
484                     if (sat < 0f) {
485                         sat = 0f;
486                     } else if (sat > 1f) {
487                         sat = 1f;
488                     }
489
490                     if (val < 0f) {
491                         val = 0f;
492                     } else if (val > 1f) {
493                         val = 1f;
494                     }
495
496                     mSat = sat;
497                     mVal = val;
498
499                     update = true;
500
501                     break;
502
503                 case PANEL_HUE:
504
505                     float hue = mHue - y * 10f;
506
507                     if (hue < 0f) {
508                         hue = 0f;
509                     } else if (hue > 360f) {
510                         hue = 360f;
511                     }
512
513                     mHue = hue;
514
515                     update = true;
516
517                     break;
518
519                 case PANEL_ALPHA:
520
521                     if (!mShowAlphaPanel || mAlphaRect == null) {
522                         update = false;
523                     } else {
524
525                         int alpha = (int)(mAlpha - x * 10);
526
527                         if (alpha < 0) {
528                             alpha = 0;
529                         } else if (alpha > 0xff) {
530                             alpha = 0xff;
531                         }
532
533                         mAlpha = alpha;
534
535                         update = true;
536                     }
537
538                     break;
539             }
540
541         }
542
543         if (update) {
544
545             if (mListener != null) {
546                 mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
547                         mHue, mSat, mVal
548                 }));
549             }
550
551             invalidate();
552             return true;
553         }
554
555         return super.onTrackballEvent(event);
556     }
557
558     @Override
559     public boolean onTouchEvent(final MotionEvent event) {
560
561         boolean update = false;
562
563         switch (event.getAction()) {
564
565             case MotionEvent.ACTION_DOWN:
566
567                 mStartTouchPoint = new Point((int)event.getX(), (int)event.getY());
568
569                 update = moveTrackersIfNeeded(event);
570
571                 break;
572
573             case MotionEvent.ACTION_MOVE:
574
575                 update = moveTrackersIfNeeded(event);
576
577                 break;
578
579             case MotionEvent.ACTION_UP:
580
581                 mStartTouchPoint = null;
582
583                 update = moveTrackersIfNeeded(event);
584
585                 break;
586
587         }
588
589         if (update) {
590
591             if (mListener != null) {
592                 mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
593                         mHue, mSat, mVal
594                 }));
595             }
596
597             invalidate();
598             return true;
599         }
600
601         return super.onTouchEvent(event);
602     }
603
604     private boolean moveTrackersIfNeeded(final MotionEvent event) {
605
606         if (mStartTouchPoint == null) {
607             return false;
608         }
609
610         boolean update = false;
611
612         final int startX = mStartTouchPoint.x;
613         final int startY = mStartTouchPoint.y;
614
615         if (mHueRect.contains(startX, startY)) {
616             mLastTouchedPanel = PANEL_HUE;
617
618             mHue = pointToHue(event.getY());
619
620             update = true;
621         } else if (mSatValRect.contains(startX, startY)) {
622
623             mLastTouchedPanel = PANEL_SAT_VAL;
624
625             final float[] result = pointToSatVal(event.getX(), event.getY());
626
627             mSat = result[0];
628             mVal = result[1];
629
630             update = true;
631         } else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) {
632
633             mLastTouchedPanel = PANEL_ALPHA;
634
635             mAlpha = pointToAlpha((int)event.getX());
636
637             update = true;
638         }
639
640         return update;
641     }
642
643     @Override
644     protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
645
646         int width = 0;
647         int height = 0;
648
649         final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
650         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
651
652         int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
653         int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
654
655         widthAllowed = chooseWidth(widthMode, widthAllowed);
656         heightAllowed = chooseHeight(heightMode, heightAllowed);
657
658         if (!mShowAlphaPanel) {
659             height = (int)(widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
660
661             // If calculated height (based on the width) is more than the
662             // allowed height.
663             if (height > heightAllowed) {
664                 height = heightAllowed;
665                 width = (int)(height + PANEL_SPACING + HUE_PANEL_WIDTH);
666             } else {
667                 width = widthAllowed;
668             }
669         } else {
670
671             width = (int)(heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
672
673             if (width > widthAllowed) {
674                 width = widthAllowed;
675                 height = (int)(widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
676             } else {
677                 height = heightAllowed;
678             }
679
680         }
681
682         setMeasuredDimension(width, height);
683     }
684
685     private int chooseWidth(final int mode, final int size) {
686         if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
687             return size;
688         } else { // (mode == MeasureSpec.UNSPECIFIED)
689             return getPrefferedWidth();
690         }
691     }
692
693     private int chooseHeight(final int mode, final int size) {
694         if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
695             return size;
696         } else { // (mode == MeasureSpec.UNSPECIFIED)
697             return getPrefferedHeight();
698         }
699     }
700
701     private int getPrefferedWidth() {
702
703         int width = getPrefferedHeight();
704
705         if (mShowAlphaPanel) {
706             width -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
707         }
708
709         return (int)(width + HUE_PANEL_WIDTH + PANEL_SPACING);
710
711     }
712
713     private int getPrefferedHeight() {
714
715         int height = (int)(200 * mDensity);
716
717         if (mShowAlphaPanel) {
718             height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
719         }
720
721         return height;
722     }
723
724     @Override
725     protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
726         super.onSizeChanged(w, h, oldw, oldh);
727
728         mDrawingRect = new RectF();
729         mDrawingRect.left = mDrawingOffset + getPaddingLeft();
730         mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
731         mDrawingRect.top = mDrawingOffset + getPaddingTop();
732         mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
733
734         setUpSatValRect();
735         setUpHueRect();
736         setUpAlphaRect();
737     }
738
739     private void setUpSatValRect() {
740
741         final RectF dRect = mDrawingRect;
742         float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
743
744         if (mShowAlphaPanel) {
745             panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
746         }
747
748         final float left = dRect.left + BORDER_WIDTH_PX;
749         final float top = dRect.top + BORDER_WIDTH_PX;
750         final float bottom = top + panelSide;
751         final float right = left + panelSide;
752
753         mSatValRect = new RectF(left, top, right, bottom);
754     }
755
756     private void setUpHueRect() {
757         final RectF dRect = mDrawingRect;
758
759         final float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
760         final float top = dRect.top + BORDER_WIDTH_PX;
761         final float bottom = dRect.bottom - BORDER_WIDTH_PX
762                 - (mShowAlphaPanel ? PANEL_SPACING + ALPHA_PANEL_HEIGHT : 0);
763         final float right = dRect.right - BORDER_WIDTH_PX;
764
765         mHueRect = new RectF(left, top, right, bottom);
766     }
767
768     private void setUpAlphaRect() {
769
770         if (!mShowAlphaPanel) {
771             return;
772         }
773
774         final RectF dRect = mDrawingRect;
775
776         final float left = dRect.left + BORDER_WIDTH_PX;
777         final float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
778         final float bottom = dRect.bottom - BORDER_WIDTH_PX;
779         final float right = dRect.right - BORDER_WIDTH_PX;
780
781         mAlphaRect = new RectF(left, top, right, bottom);
782
783         mAlphaPattern = new AlphaPatternDrawable((int)(5 * mDensity));
784         mAlphaPattern.setBounds(Math.round(mAlphaRect.left), Math.round(mAlphaRect.top),
785                 Math.round(mAlphaRect.right), Math.round(mAlphaRect.bottom));
786
787     }
788
789     /**
790      * Set a OnColorChangedListener to get notified when the color selected by
791      * the user has changed.
792      * 
793      * @param listener
794      */
795     public void setOnColorChangedListener(final OnColorChangedListener listener) {
796         mListener = listener;
797     }
798
799     /**
800      * Set the color of the border surrounding all panels.
801      * 
802      * @param color
803      */
804     public void setBorderColor(final int color) {
805         mBorderColor = color;
806         invalidate();
807     }
808
809     /**
810      * Get the color of the border surrounding all panels.
811      */
812     public int getBorderColor() {
813         return mBorderColor;
814     }
815
816     /**
817      * Get the current color this view is showing.
818      * 
819      * @return the current color.
820      */
821     public int getColor() {
822         return Color.HSVToColor(mAlpha, new float[] {
823                 mHue, mSat, mVal
824         });
825     }
826
827     /**
828      * Set the color the view should show.
829      * 
830      * @param color The color that should be selected.
831      */
832     public void setColor(final int color) {
833         setColor(color, false);
834     }
835
836     /**
837      * Set the color this view should show.
838      * 
839      * @param color The color that should be selected.
840      * @param callback If you want to get a callback to your
841      *            OnColorChangedListener.
842      */
843     public void setColor(final int color, final boolean callback) {
844
845         final int alpha = Color.alpha(color);
846         final int red = Color.red(color);
847         final int blue = Color.blue(color);
848         final int green = Color.green(color);
849
850         final float[] hsv = new float[3];
851
852         Color.RGBToHSV(red, green, blue, hsv);
853
854         mAlpha = alpha;
855         mHue = hsv[0];
856         mSat = hsv[1];
857         mVal = hsv[2];
858
859         if (callback && mListener != null) {
860             mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
861                     mHue, mSat, mVal
862             }));
863         }
864
865         invalidate();
866     }
867
868     /**
869      * Get the drawing offset of the color picker view. The drawing offset is
870      * the distance from the side of a panel to the side of the view minus the
871      * padding. Useful if you want to have your own panel below showing the
872      * currently selected color and want to align it perfectly.
873      * 
874      * @return The offset in pixels.
875      */
876     public float getDrawingOffset() {
877         return mDrawingOffset;
878     }
879
880     /**
881      * Set if the user is allowed to adjust the alpha panel. Default is false.
882      * If it is set to false no alpha will be set.
883      * 
884      * @param visible
885      */
886     public void setAlphaSliderVisible(final boolean visible) {
887
888         if (mShowAlphaPanel != visible) {
889             mShowAlphaPanel = visible;
890
891             /*
892              * Reset all shader to force a recreation. Otherwise they will not
893              * look right after the size of the view has changed.
894              */
895             mValShader = null;
896             mSatShader = null;
897             mHueShader = null;
898             mAlphaShader = null;
899
900             requestLayout();
901         }
902
903     }
904
905     public void setSliderTrackerColor(final int color) {
906         mSliderTrackerColor = color;
907
908         mHueTrackerPaint.setColor(mSliderTrackerColor);
909
910         invalidate();
911     }
912
913     public int getSliderTrackerColor() {
914         return mSliderTrackerColor;
915     }
916
917     /**
918      * Set the text that should be shown in the alpha slider. Set to null to
919      * disable text.
920      * 
921      * @param res string resource id.
922      */
923     public void setAlphaSliderText(final int res) {
924         final String text = getContext().getString(res);
925         setAlphaSliderText(text);
926     }
927
928     /**
929      * Set the text that should be shown in the alpha slider. Set to null to
930      * disable text.
931      * 
932      * @param text Text that should be shown.
933      */
934     public void setAlphaSliderText(final String text) {
935         mAlphaSliderText = text;
936         invalidate();
937     }
938
939     /**
940      * Get the current value of the text that will be shown in the alpha slider.
941      * 
942      * @return
943      */
944     public String getAlphaSliderText() {
945         return mAlphaSliderText;
946     }
947 }