- add sources.
[platform/framework/web/crosswalk.git] / src / ui / android / java / src / org / chromium / ui / ColorPickerAdvanced.java
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.ui;
6
7 import android.content.Context;
8 import android.graphics.Color;
9 import android.util.AttributeSet;
10 import android.view.LayoutInflater;
11 import android.view.View;
12 import android.view.accessibility.AccessibilityEvent;
13 import android.widget.LinearLayout;
14 import android.widget.SeekBar;
15 import android.widget.SeekBar.OnSeekBarChangeListener;
16
17 /**
18  * Represents a more advanced way for the user to choose a color, based on selecting each of
19  * the Hue, Saturation and Value attributes.
20  */
21 public class ColorPickerAdvanced extends LinearLayout implements OnSeekBarChangeListener {
22     private static final int HUE_SEEK_BAR_MAX = 360;
23
24     private static final int HUE_COLOR_COUNT = 7;
25
26     private static final int SATURATION_SEEK_BAR_MAX = 100;
27
28     private static final int SATURATION_COLOR_COUNT = 2;
29
30     private static final int VALUE_SEEK_BAR_MAX = 100;
31
32     private static final int VALUE_COLOR_COUNT = 2;
33
34     ColorPickerAdvancedComponent mHueDetails;
35
36     ColorPickerAdvancedComponent mSaturationDetails;
37
38     ColorPickerAdvancedComponent mValueDetails;
39
40     private OnColorChangedListener mOnColorChangedListener;
41
42     private int mCurrentColor;
43
44     private final float[] mCurrentHsvValues = new float[3];
45
46     public ColorPickerAdvanced(Context context, AttributeSet attrs) {
47         super(context, attrs);
48         init();
49     }
50
51     public ColorPickerAdvanced(Context context, AttributeSet attrs, int defStyle) {
52         super(context, attrs, defStyle);
53         init();
54     }
55
56     public ColorPickerAdvanced(Context context) {
57         super(context);
58         init();
59     }
60
61     /**
62      * Initializes all the views and variables in the advanced view.
63      */
64     private void init() {
65         setOrientation(LinearLayout.VERTICAL);
66
67         mHueDetails = createAndAddNewGradient(R.string.color_picker_hue,
68                 HUE_SEEK_BAR_MAX, this);
69         mSaturationDetails = createAndAddNewGradient(R.string.color_picker_saturation,
70                 SATURATION_SEEK_BAR_MAX, this);
71         mValueDetails = createAndAddNewGradient(R.string.color_picker_value,
72                 VALUE_SEEK_BAR_MAX, this);
73
74         refreshGradientComponents();
75     }
76
77     /**
78      * Creates a new GradientDetails object from the parameters provided, initializes it,
79      * and adds it to this advanced view.
80      *
81      * @param textResourceId The text to display for the label.
82      * @param seekBarMax The maximum value of the seek bar for the gradient.
83      * @param seekBarListener Object listening to when the user changes the seek bar.
84      *
85      * @return A new GradientDetails object initialized with the given parameters.
86      */
87     public ColorPickerAdvancedComponent createAndAddNewGradient(int textResourceId,
88             int seekBarMax,
89             OnSeekBarChangeListener seekBarListener) {
90         LayoutInflater inflater = (LayoutInflater) getContext()
91                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
92         View newComponent = inflater.inflate(R.layout.color_picker_advanced_component, null);
93         addView(newComponent);
94
95         return new ColorPickerAdvancedComponent(newComponent,
96                 textResourceId,
97                 seekBarMax,
98                 seekBarListener);
99     }
100
101     /**
102      * Sets the listener for when the user changes the color.
103      *
104      * @param onColorChangedListener The object listening for the change in color.
105      */
106     public void setListener(OnColorChangedListener onColorChangedListener) {
107         mOnColorChangedListener = onColorChangedListener;
108     }
109
110     /**
111      * @return The color the user has currently chosen.
112      */
113     public int getColor() {
114         return mCurrentColor;
115     }
116
117     /**
118      * Sets the color that the user has currently chosen.
119      *
120      * @param color The currently chosen color.
121      */
122     public void setColor(int color) {
123         mCurrentColor = color;
124         Color.colorToHSV(mCurrentColor, mCurrentHsvValues);
125         refreshGradientComponents();
126     }
127
128     /**
129      * Notifies the listener, if there is one, of a change in the selected color.
130      */
131     private void notifyColorChanged() {
132         if (mOnColorChangedListener != null) {
133             mOnColorChangedListener.onColorChanged(getColor());
134         }
135     }
136
137     /**
138      * Callback for when a slider is updated on the advanced view.
139      *
140      * @param seekBar The color slider that was updated.
141      * @param progress The new value of the color slider.
142      * @param fromUser Whether it was the user the changed the value, or whether
143      *            we were setting it up.
144      */
145     @Override
146     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
147         if (fromUser) {
148             mCurrentHsvValues[0] = mHueDetails.getValue();
149             mCurrentHsvValues[1] = mSaturationDetails.getValue() / 100.0f;
150             mCurrentHsvValues[2] = mValueDetails.getValue() / 100.0f;
151
152             mCurrentColor = Color.HSVToColor(mCurrentHsvValues);
153
154             updateHueGradient();
155             updateSaturationGradient();
156             updateValueGradient();
157
158             notifyColorChanged();
159         }
160     }
161
162     /**
163      * Updates only the hue gradient display with the hue value for the
164      * currently selected color.
165      */
166     private void updateHueGradient() {
167         float[] tempHsvValues = new float[3];
168         tempHsvValues[1] = mCurrentHsvValues[1];
169         tempHsvValues[2] = mCurrentHsvValues[2];
170
171         int[] newColors = new int[HUE_COLOR_COUNT];
172
173         for (int i = 0; i < HUE_COLOR_COUNT; ++i) {
174             tempHsvValues[0] = i * 60.0f;
175             newColors[i] = Color.HSVToColor(tempHsvValues);
176         }
177         mHueDetails.setGradientColors(newColors);
178     }
179
180     /**
181      * Updates only the saturation gradient display with the saturation value
182      * for the currently selected color.
183      */
184     private void updateSaturationGradient() {
185         float[] tempHsvValues = new float[3];
186         tempHsvValues[0] = mCurrentHsvValues[0];
187         tempHsvValues[1] = 0.0f;
188         tempHsvValues[2] = mCurrentHsvValues[2];
189
190         int[] newColors = new int[SATURATION_COLOR_COUNT];
191
192         newColors[0] = Color.HSVToColor(tempHsvValues);
193
194         tempHsvValues[1] = 1.0f;
195         newColors[1] = Color.HSVToColor(tempHsvValues);
196         mSaturationDetails.setGradientColors(newColors);
197     }
198
199     /**
200      * Updates only the Value gradient display with the Value amount for
201      * the currently selected color.
202      */
203     private void updateValueGradient() {
204         float[] tempHsvValues = new float[3];
205         tempHsvValues[0] = mCurrentHsvValues[0];
206         tempHsvValues[1] = mCurrentHsvValues[1];
207         tempHsvValues[2] = 0.0f;
208
209         int[] newColors = new int[VALUE_COLOR_COUNT];
210
211         newColors[0] = Color.HSVToColor(tempHsvValues);
212
213         tempHsvValues[2] = 1.0f;
214         newColors[1] = Color.HSVToColor(tempHsvValues);
215         mValueDetails.setGradientColors(newColors);
216     }
217
218     /**
219      * Updates all the gradient displays to show the currently selected color.
220      */
221     private void refreshGradientComponents() {
222         // Round and bound the saturation value.
223         int saturationValue = Math.round(mCurrentHsvValues[1] * 100.0f);
224         saturationValue = Math.min(saturationValue, SATURATION_SEEK_BAR_MAX);
225         saturationValue = Math.max(saturationValue, 0);
226
227         // Round and bound the Value amount.
228         int valueValue = Math.round(mCurrentHsvValues[2] * 100.0f);
229         valueValue = Math.min(valueValue, VALUE_SEEK_BAR_MAX);
230         valueValue = Math.max(valueValue, 0);
231
232         // Don't need to round the hue value since its possible values match the seek bar
233         // range directly.
234         mHueDetails.setValue(mCurrentHsvValues[0]);
235         mSaturationDetails.setValue(saturationValue);
236         mValueDetails.setValue(valueValue);
237
238         updateHueGradient();
239         updateSaturationGradient();
240         updateValueGradient();
241     }
242
243     @Override
244     public void onStartTrackingTouch(SeekBar seekBar) {
245         // Do nothing.
246     }
247
248     @Override
249     public void onStopTrackingTouch(SeekBar seekBar) {
250         // Do nothing.
251     }
252 }