OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 package org.chromium.ui; | 4 package org.chromium.ui; |
5 | 5 |
6 import android.content.Context; | 6 import android.content.Context; |
7 import android.graphics.Canvas; | 7 import android.graphics.Canvas; |
8 import android.graphics.Color; | 8 import android.graphics.Color; |
9 import android.graphics.Paint; | 9 import android.graphics.Paint; |
10 import android.graphics.Rect; | 10 import android.graphics.Rect; |
11 import android.util.AttributeSet; | 11 import android.util.AttributeSet; |
12 import android.view.MotionEvent; | 12 import android.view.MotionEvent; |
13 import android.view.View; | 13 import android.view.View; |
14 | 14 import android.view.ViewGroup; |
15 | 15 |
16 /** | 16 /** |
17 * Draws a grid of (predefined) colors and allows the user to choose one of | 17 * Draws a grid of (predefined) colors and allows the user to choose one of |
18 * those colors. | 18 * those colors. |
19 */ | 19 */ |
20 public class ColorPickerSimple extends View { | 20 public class ColorPickerSimple extends View { |
21 private static final int ROW_COUNT = 2; | |
22 | |
23 private static final int COLUMN_COUNT = 4; | 21 private static final int COLUMN_COUNT = 4; |
24 | 22 |
25 private static final int GRID_CELL_COUNT = ROW_COUNT * COLUMN_COUNT; | 23 private static final int MINIMUM_CELL_HEIGHT = 50; |
newt (away)
2013/08/19 23:18:19
MINIMUM_CELL_HEIGHT should be measured in DP, and
| |
24 private static final int GRID_LINE_WIDTH = 1; | |
26 | 25 |
27 private static final int[] COLORS = { Color.RED, | 26 private static final int[] DEFAULT_COLORS = { Color.RED, |
28 Color.CYAN, | 27 Color.CYAN, |
29 Color.BLUE, | 28 Color.BLUE, |
30 Color.GREEN, | 29 Color.GREEN, |
31 Color.MAGENTA, | 30 Color.MAGENTA, |
32 Color.YELLOW, | 31 Color.YELLOW, |
33 Color.BLACK, | 32 Color.BLACK, |
34 Color.WHITE | 33 Color.WHITE |
35 }; | 34 }; |
36 | 35 |
37 private Paint mBorderPaint; | 36 private Paint mBorderPaint; |
38 | 37 |
39 private Rect[] mBounds; | 38 private Rect[] mBounds; |
40 | 39 |
40 private int[] mColors; | |
41 | |
41 private Paint[] mPaints; | 42 private Paint[] mPaints; |
42 | 43 |
43 private OnColorChangedListener mOnColorTouchedListener; | 44 private OnColorChangedListener mOnColorTouchedListener; |
44 | 45 |
45 private int mLastTouchedXPosition; | 46 private int mLastTouchedXPosition; |
46 | 47 |
47 private int mLastTouchedYPosition; | 48 private int mLastTouchedYPosition; |
48 | 49 |
49 public ColorPickerSimple(Context context) { | 50 public ColorPickerSimple(Context context) { |
50 super(context); | 51 super(context); |
51 } | 52 } |
52 | 53 |
53 public ColorPickerSimple(Context context, AttributeSet attrs) { | 54 public ColorPickerSimple(Context context, AttributeSet attrs) { |
54 super(context, attrs); | 55 super(context, attrs); |
55 } | 56 } |
56 | 57 |
57 public ColorPickerSimple(Context context, AttributeSet attrs, int defStyle) { | 58 public ColorPickerSimple(Context context, AttributeSet attrs, int defStyle) { |
58 super(context, attrs, defStyle); | 59 super(context, attrs, defStyle); |
59 } | 60 } |
60 | 61 |
61 /** | 62 /** |
62 * Initializes the listener and precalculates the grid and color positions. | 63 * Initializes the listener and precalculates the grid and color positions. |
newt (away)
2013/08/19 23:18:19
explain what happens if colors is empty. Also, I'd
keishi
2013/08/26 05:28:54
Changed to use default colors when passed null.
| |
64 * TODO(keishi): Use colorLabels to improve accessibility. | |
63 * | 65 * |
66 * @param colors The list of colors that should be displayed. | |
67 * @param colorLabels The label text that describe the colors. | |
64 * @param onColorChangedListener The listener that gets notified when the us er touches | 68 * @param onColorChangedListener The listener that gets notified when the us er touches |
65 * a color. | 69 * a color. |
66 */ | 70 */ |
67 public void init(OnColorChangedListener onColorChangedListener) { | 71 public void init(int[] colors, |
Miguel Garcia
2013/08/19 14:43:27
I think, somewhere in the whole stack, preferably
keishi
2013/08/26 05:28:54
No. I checked the limits for <input type=text> sug
Miguel Garcia
2013/08/27 14:32:00
Do we really need 10K? Can we settle for 1K colors
newt (away)
2013/08/27 16:05:29
Should we limit the total amount of data sent over
keishi
2013/08/29 05:04:11
Added the 1024 char limit in Blink. I wonder if it
| |
72 String[] colorLabels, | |
73 OnColorChangedListener onColorChangedListener) { | |
68 mOnColorTouchedListener = onColorChangedListener; | 74 mOnColorTouchedListener = onColorChangedListener; |
69 | 75 |
70 // This will get calculated when the layout size is updated. | 76 // This will get calculated when the layout size is updated. |
71 mBounds = null; | 77 mBounds = null; |
72 | 78 |
73 mPaints = new Paint[GRID_CELL_COUNT]; | 79 if (colors.length == 0) |
newt (away)
2013/08/19 23:18:19
need curly braces
| |
74 for (int i = 0; i < GRID_CELL_COUNT; ++i) { | 80 mColors = DEFAULT_COLORS; |
81 else | |
82 mColors = colors; | |
83 | |
84 mPaints = new Paint[mColors.length]; | |
85 for (int i = 0; i < mColors.length; ++i) { | |
75 Paint newPaint = new Paint(); | 86 Paint newPaint = new Paint(); |
76 newPaint.setColor(COLORS[i]); | 87 newPaint.setColor(mColors[i]); |
77 mPaints[i] = newPaint; | 88 mPaints[i] = newPaint; |
78 } | 89 } |
79 | 90 |
80 mBorderPaint = new Paint(); | 91 mBorderPaint = new Paint(); |
81 int borderColor = getContext().getResources().getColor(R.color.color_pic ker_border_color); | 92 int borderColor = getContext().getResources().getColor(R.color.color_pic ker_border_color); |
82 mBorderPaint.setColor(borderColor); | 93 mBorderPaint.setColor(borderColor); |
83 | 94 |
95 int rowCount = (int)Math.ceil((double)mColors.length / COLUMN_COUNT); | |
newt (away)
2013/08/19 23:18:19
Calculate mRowCount only once, and store it as a m
| |
96 int minimumHeight = rowCount * (MINIMUM_CELL_HEIGHT + GRID_LINE_WIDTH) + GRID_LINE_WIDTH; | |
97 setMinimumHeight(Math.max(minimumHeight, getMinimumHeight())); | |
98 | |
84 // Responds to the user touching the grid and works out which color has been chosen as | 99 // Responds to the user touching the grid and works out which color has been chosen as |
85 // a result, depending on the X,Y coordinate. Note that we respond to th e click event | 100 // a result, depending on the X,Y coordinate. Note that we respond to th e click event |
86 // here, but the onClick() method doesn't provide us with the X,Y coordi nates, so we | 101 // here, but the onClick() method doesn't provide us with the X,Y coordi nates, so we |
87 // track them in onTouchEvent() below. This way the grid reacts properly to touch events | 102 // track them in onTouchEvent() below. This way the grid reacts properly to touch events |
88 // whereas if we put this onClick() code in onTouchEvent below then we g et some strange | 103 // whereas if we put this onClick() code in onTouchEvent below then we g et some strange |
89 // interactions with the ScrollView in the parent ColorPickerDialog. | 104 // interactions with the ScrollView in the parent ColorPickerDialog. |
90 setOnClickListener(new OnClickListener() { | 105 setOnClickListener(new OnClickListener() { |
91 @Override | 106 @Override |
92 public void onClick(View v) { | 107 public void onClick(View v) { |
93 if (mOnColorTouchedListener != null && getWidth() > 0 && getHeig ht() > 0) { | 108 if (mOnColorTouchedListener != null && getWidth() > 0 && getHeig ht() > 0) { |
109 int rowCount = (int)Math.ceil((double)mColors.length / COLUM N_COUNT); | |
newt (away)
2013/08/19 23:18:19
use mRowCount here and below.
| |
94 int column = mLastTouchedXPosition * COLUMN_COUNT / getWidth (); | 110 int column = mLastTouchedXPosition * COLUMN_COUNT / getWidth (); |
95 int row = mLastTouchedYPosition * ROW_COUNT / getHeight(); | 111 int row = mLastTouchedYPosition * rowCount / getHeight(); |
96 | 112 |
97 int colorIndex = (row * COLUMN_COUNT) + column; | 113 int colorIndex = (row * COLUMN_COUNT) + column; |
98 if (colorIndex >= 0 && colorIndex < COLORS.length) { | 114 if (colorIndex >= 0 && colorIndex < mColors.length) { |
99 mOnColorTouchedListener.onColorChanged(COLORS[colorIndex ]); | 115 mOnColorTouchedListener.onColorChanged(mColors[colorInde x]); |
100 } | 116 } |
101 } | 117 } |
102 } | 118 } |
103 }); | 119 }); |
104 } | 120 } |
105 | 121 |
106 /** | 122 /** |
107 * Draws the grid of colors, based on the rectangles calculated in onSizeCha nged(). | 123 * Draws the grid of colors, based on the rectangles calculated in onSizeCha nged(). |
108 * Also draws borders in between the colored rectangles. | 124 * Also draws borders in between the colored rectangles. |
109 * | 125 * |
110 * @param canvas The canvas the colors are drawn onto. | 126 * @param canvas The canvas the colors are drawn onto. |
111 */ | 127 */ |
112 @Override | 128 @Override |
113 public void onDraw(Canvas canvas) { | 129 public void onDraw(Canvas canvas) { |
114 if (mBounds == null || mPaints == null) { | 130 if (mBounds == null || mPaints == null) { |
115 return; | 131 return; |
116 } | 132 } |
117 | 133 |
118 canvas.drawColor(Color.WHITE); | 134 canvas.drawColor(Color.WHITE); |
119 | 135 |
120 // Draw the actual colored rectangles. | 136 // Draw the actual colored rectangles. |
121 for (int i = 0; i < GRID_CELL_COUNT; ++i) { | 137 for (int i = 0; i < mColors.length; ++i) { |
Miguel Garcia
2013/08/19 14:43:27
can you calculate the number of cells and rows at
| |
122 canvas.drawRect(mBounds[i], mPaints[i]); | 138 canvas.drawRect(mBounds[i], mPaints[i]); |
123 } | 139 } |
124 | 140 |
125 // Draw 1px borders between the rows. | 141 // Draw 1px borders between the rows. |
126 for (int i = 0; i < ROW_COUNT - 1; ++i) { | 142 int rowCount = (int)Math.ceil((double)mColors.length / COLUMN_COUNT); |
143 for (int i = 0; i < rowCount - 1; ++i) { | |
144 if (i * COLUMN_COUNT >= mBounds.length) | |
newt (away)
2013/08/19 23:18:19
this condition can never be true.
| |
145 break; | |
127 canvas.drawLine(0, | 146 canvas.drawLine(0, |
128 mBounds[i * COLUMN_COUNT].bottom + 1, | 147 mBounds[i * COLUMN_COUNT].bottom + 1, |
129 getWidth(), | 148 getWidth(), |
130 mBounds[i * COLUMN_COUNT].bottom + 1, | 149 mBounds[i * COLUMN_COUNT].bottom + 1, |
131 mBorderPaint); | 150 mBorderPaint); |
132 } | 151 } |
133 | 152 |
134 // Draw 1px borders between the columns. | 153 // Draw 1px borders between the columns. |
135 for (int j = 0; j < COLUMN_COUNT - 1; ++j) { | 154 for (int j = 0; j < COLUMN_COUNT - 1; ++j) { |
155 if (j >= mBounds.length) | |
156 break; | |
136 canvas.drawLine(mBounds[j].right + 1, | 157 canvas.drawLine(mBounds[j].right + 1, |
137 0, | 158 0, |
138 mBounds[j].right + 1, | 159 mBounds[j].right + 1, |
139 getHeight(), | 160 getHeight(), |
140 mBorderPaint); | 161 mBorderPaint); |
141 } | 162 } |
142 } | 163 } |
143 | 164 |
144 /** | 165 /** |
145 * Stores the X,Y coordinates of the touch so that we can use them in the on Click() listener | 166 * Stores the X,Y coordinates of the touch so that we can use them in the on Click() listener |
(...skipping 18 matching lines...) Expand all Loading... | |
164 calculateGrid(width, height); | 185 calculateGrid(width, height); |
165 } | 186 } |
166 | 187 |
167 /** | 188 /** |
168 * Calculates the sizes and positions of the cells in the grid, splitting | 189 * Calculates the sizes and positions of the cells in the grid, splitting |
169 * them up as evenly as possible. Leaves 3 pixels between each cell so that | 190 * them up as evenly as possible. Leaves 3 pixels between each cell so that |
170 * we can draw a border between them as well, and leaves a pixel around the | 191 * we can draw a border between them as well, and leaves a pixel around the |
171 * edge. | 192 * edge. |
172 */ | 193 */ |
173 private void calculateGrid(final int width, final int height) { | 194 private void calculateGrid(final int width, final int height) { |
174 mBounds = new Rect[GRID_CELL_COUNT]; | 195 mBounds = new Rect[mColors.length]; |
175 | 196 |
176 for (int i = 0; i < ROW_COUNT; ++i) { | 197 int rowCount = (int)Math.ceil((double)mColors.length / COLUMN_COUNT); |
newt (away)
2013/08/19 23:18:19
I don't see why you need to add/change lines 197-1
| |
198 double cellWidth = (width + GRID_LINE_WIDTH) / (double) COLUMN_COUNT; | |
199 double cellHeight = (height + GRID_LINE_WIDTH) / (double) rowCount; | |
200 for (int i = 0; i < rowCount; ++i) { | |
177 for (int j = 0; j < COLUMN_COUNT; ++j) { | 201 for (int j = 0; j < COLUMN_COUNT; ++j) { |
178 int left = j * (width + 1) / COLUMN_COUNT + 1; | 202 int index = (i * COLUMN_COUNT) + j; |
179 int right = (j + 1) * (width + 1) / COLUMN_COUNT - 2; | 203 if (index >= mBounds.length) |
204 break; | |
205 int left = (int) (j * cellWidth + GRID_LINE_WIDTH); | |
206 int right = (int) ((j + 1) * cellWidth - GRID_LINE_WIDTH * 2); | |
180 | 207 |
181 int top = i * (height + 1) / ROW_COUNT + 1; | 208 int top = (int) (i * cellHeight + GRID_LINE_WIDTH); |
182 int bottom = (i + 1) * (height + 1) / ROW_COUNT - 2; | 209 int bottom = (int) ((i + 1) * cellHeight - GRID_LINE_WIDTH * 2); |
183 | 210 |
184 Rect rect = new Rect(left, top, right, bottom); | 211 Rect rect = new Rect(left, top, right, bottom); |
185 mBounds[(i * COLUMN_COUNT) + j] = rect; | 212 mBounds[index] = rect; |
186 } | 213 } |
187 } | 214 } |
188 } | 215 } |
189 } | 216 } |
OLD | NEW |