12cfe25aefb32ed215f1c661d9670baf276fb7776James Kung/* 22cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * Copyright (C) 2013 The Android Open Source Project 32cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * 42cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * Licensed under the Apache License, Version 2.0 (the "License"); 52cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * you may not use this file except in compliance with the License. 62cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * You may obtain a copy of the License at 72cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * 82cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * http://www.apache.org/licenses/LICENSE-2.0 92cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * 102cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * Unless required by applicable law or agreed to in writing, software 112cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * distributed under the License is distributed on an "AS IS" BASIS, 122cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * See the License for the specific language governing permissions and 142cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * limitations under the License. 152cfe25aefb32ed215f1c661d9670baf276fb7776James Kung */ 162cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 172cfe25aefb32ed215f1c661d9670baf276fb7776James Kungpackage com.android.colorpicker; 182cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 192cfe25aefb32ed215f1c661d9670baf276fb7776James Kungimport android.content.Context; 203f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzsteinimport android.content.res.Resources; 212cfe25aefb32ed215f1c661d9670baf276fb7776James Kungimport android.util.AttributeSet; 222cfe25aefb32ed215f1c661d9670baf276fb7776James Kungimport android.view.View; 232cfe25aefb32ed215f1c661d9670baf276fb7776James Kungimport android.view.ViewGroup; 242cfe25aefb32ed215f1c661d9670baf276fb7776James Kungimport android.widget.ImageView; 252cfe25aefb32ed215f1c661d9670baf276fb7776James Kungimport android.widget.TableLayout; 262cfe25aefb32ed215f1c661d9670baf276fb7776James Kungimport android.widget.TableRow; 272cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 282cfe25aefb32ed215f1c661d9670baf276fb7776James Kungimport com.android.colorpicker.ColorPickerSwatch.OnColorSelectedListener; 292cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 302cfe25aefb32ed215f1c661d9670baf276fb7776James Kung/** 312cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * A color picker custom view which creates an grid of color squares. The number of squares per 322cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * row (and the padding between the squares) is determined by the user. 332cfe25aefb32ed215f1c661d9670baf276fb7776James Kung */ 342cfe25aefb32ed215f1c661d9670baf276fb7776James Kungpublic class ColorPickerPalette extends TableLayout { 352cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 362cfe25aefb32ed215f1c661d9670baf276fb7776James Kung public OnColorSelectedListener mOnColorSelectedListener; 372cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 383f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein private String mDescription; 393f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein private String mDescriptionSelected; 403f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein 412cfe25aefb32ed215f1c661d9670baf276fb7776James Kung private int mSwatchLength; 422cfe25aefb32ed215f1c661d9670baf276fb7776James Kung private int mMarginSize; 432cfe25aefb32ed215f1c661d9670baf276fb7776James Kung private int mNumColumns; 442cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 452cfe25aefb32ed215f1c661d9670baf276fb7776James Kung public ColorPickerPalette(Context context, AttributeSet attrs) { 462cfe25aefb32ed215f1c661d9670baf276fb7776James Kung super(context, attrs); 472cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 482cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 492cfe25aefb32ed215f1c661d9670baf276fb7776James Kung public ColorPickerPalette(Context context) { 502cfe25aefb32ed215f1c661d9670baf276fb7776James Kung super(context); 512cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 522cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 532cfe25aefb32ed215f1c661d9670baf276fb7776James Kung /** 542cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * Initialize the size, columns, and listener. Size should be a pre-defined size (SIZE_LARGE 552cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * or SIZE_SMALL) from ColorPickerDialogFragment. 562cfe25aefb32ed215f1c661d9670baf276fb7776James Kung */ 572cfe25aefb32ed215f1c661d9670baf276fb7776James Kung public void init(int size, int columns, OnColorSelectedListener listener) { 582cfe25aefb32ed215f1c661d9670baf276fb7776James Kung mNumColumns = columns; 593f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein Resources res = getResources(); 602cfe25aefb32ed215f1c661d9670baf276fb7776James Kung if (size == ColorPickerDialog.SIZE_LARGE) { 613f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein mSwatchLength = res.getDimensionPixelSize(R.dimen.color_swatch_large); 623f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein mMarginSize = res.getDimensionPixelSize(R.dimen.color_swatch_margins_large); 632cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } else { 643f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein mSwatchLength = res.getDimensionPixelSize(R.dimen.color_swatch_small); 653f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein mMarginSize = res.getDimensionPixelSize(R.dimen.color_swatch_margins_small); 662cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 672cfe25aefb32ed215f1c661d9670baf276fb7776James Kung mOnColorSelectedListener = listener; 683f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein 693f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein mDescription = res.getString(R.string.color_swatch_description); 703f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein mDescriptionSelected = res.getString(R.string.color_swatch_description_selected); 712cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 722cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 732cfe25aefb32ed215f1c661d9670baf276fb7776James Kung private TableRow createTableRow() { 742cfe25aefb32ed215f1c661d9670baf276fb7776James Kung TableRow row = new TableRow(getContext()); 752cfe25aefb32ed215f1c661d9670baf276fb7776James Kung ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, 762cfe25aefb32ed215f1c661d9670baf276fb7776James Kung LayoutParams.WRAP_CONTENT); 772cfe25aefb32ed215f1c661d9670baf276fb7776James Kung row.setLayoutParams(params); 782cfe25aefb32ed215f1c661d9670baf276fb7776James Kung return row; 792cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 802cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 812cfe25aefb32ed215f1c661d9670baf276fb7776James Kung /** 822cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * Adds swatches to table in a serpentine format. 832cfe25aefb32ed215f1c661d9670baf276fb7776James Kung */ 842cfe25aefb32ed215f1c661d9670baf276fb7776James Kung public void drawPalette(int[] colors, int selectedColor) { 852cfe25aefb32ed215f1c661d9670baf276fb7776James Kung if (colors == null) { 862cfe25aefb32ed215f1c661d9670baf276fb7776James Kung return; 872cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 882cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 892cfe25aefb32ed215f1c661d9670baf276fb7776James Kung this.removeAllViews(); 903f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein int tableElements = 0; 912cfe25aefb32ed215f1c661d9670baf276fb7776James Kung int rowElements = 0; 922cfe25aefb32ed215f1c661d9670baf276fb7776James Kung int rowNumber = 0; 932cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 942cfe25aefb32ed215f1c661d9670baf276fb7776James Kung // Fills the table with swatches based on the array of colors. 952cfe25aefb32ed215f1c661d9670baf276fb7776James Kung TableRow row = createTableRow(); 963f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein for (int color : colors) { 973f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein tableElements++; 983f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein 993f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein View colorSwatch = createColorSwatch(color, selectedColor); 1003f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein setSwatchDescription(rowNumber, tableElements, rowElements, color == selectedColor, 1013f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein colorSwatch); 1023f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein addSwatchToRow(row, colorSwatch, rowNumber); 1033f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein 1042cfe25aefb32ed215f1c661d9670baf276fb7776James Kung rowElements++; 1052cfe25aefb32ed215f1c661d9670baf276fb7776James Kung if (rowElements == mNumColumns) { 1062cfe25aefb32ed215f1c661d9670baf276fb7776James Kung addView(row); 1072cfe25aefb32ed215f1c661d9670baf276fb7776James Kung row = createTableRow(); 1082cfe25aefb32ed215f1c661d9670baf276fb7776James Kung rowElements = 0; 1092cfe25aefb32ed215f1c661d9670baf276fb7776James Kung rowNumber++; 1102cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 1112cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 1122cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 1132cfe25aefb32ed215f1c661d9670baf276fb7776James Kung // Create blank views to fill the row if the last row has not been filled. 1142cfe25aefb32ed215f1c661d9670baf276fb7776James Kung if (rowElements > 0) { 1152cfe25aefb32ed215f1c661d9670baf276fb7776James Kung while (rowElements != mNumColumns) { 1162cfe25aefb32ed215f1c661d9670baf276fb7776James Kung addSwatchToRow(row, createBlankSpace(), rowNumber); 1172cfe25aefb32ed215f1c661d9670baf276fb7776James Kung rowElements++; 1182cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 1192cfe25aefb32ed215f1c661d9670baf276fb7776James Kung addView(row); 1202cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 1212cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 1222cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 1232cfe25aefb32ed215f1c661d9670baf276fb7776James Kung /** 1242cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * Appends a swatch to the end of the row for even-numbered rows (starting with row 0), 1252cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * to the beginning of a row for odd-numbered rows. 1262cfe25aefb32ed215f1c661d9670baf276fb7776James Kung */ 1272cfe25aefb32ed215f1c661d9670baf276fb7776James Kung private void addSwatchToRow(TableRow row, View swatch, int rowNumber) { 1282cfe25aefb32ed215f1c661d9670baf276fb7776James Kung if (rowNumber % 2 == 0) { 1292cfe25aefb32ed215f1c661d9670baf276fb7776James Kung row.addView(swatch); 1302cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } else { 1312cfe25aefb32ed215f1c661d9670baf276fb7776James Kung row.addView(swatch, 0); 1322cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 1332cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 1342cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 1352cfe25aefb32ed215f1c661d9670baf276fb7776James Kung /** 1363f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein * Add a content description to the specified swatch view. Because the colors get added in a 1373f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein * snaking form, every other row will need to compensate for the fact that the colors are added 1383f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein * in an opposite direction from their left->right/top->bottom order, which is how the system 1393f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein * will arrange them for accessibility purposes. 1403f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein */ 1413f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein private void setSwatchDescription(int rowNumber, int index, int rowElements, boolean selected, 1423f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein View swatch) { 1433f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein int accessibilityIndex; 1443f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein if (rowNumber % 2 == 0) { 1453f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein // We're in a regular-ordered row 1463f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein accessibilityIndex = index; 1473f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein } else { 1483f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein // We're in a backwards-ordered row. 1493f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein int rowMax = ((rowNumber + 1) * mNumColumns); 1503f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein accessibilityIndex = rowMax - rowElements; 1513f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein } 1523f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein 1533f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein String description; 1543f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein if (selected) { 1553f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein description = String.format(mDescriptionSelected, accessibilityIndex); 1563f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein } else { 1573f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein description = String.format(mDescription, accessibilityIndex); 1583f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein } 1593f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein swatch.setContentDescription(description); 1603f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein } 1613f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein 1623f672cabe031e42b31eea2d5fd187bc4ad607f77Sam Blitzstein /** 1632cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * Creates a blank space to fill the row. 1642cfe25aefb32ed215f1c661d9670baf276fb7776James Kung */ 1652cfe25aefb32ed215f1c661d9670baf276fb7776James Kung private ImageView createBlankSpace() { 1662cfe25aefb32ed215f1c661d9670baf276fb7776James Kung ImageView view = new ImageView(getContext()); 1672cfe25aefb32ed215f1c661d9670baf276fb7776James Kung TableRow.LayoutParams params = new TableRow.LayoutParams(mSwatchLength, mSwatchLength); 1682cfe25aefb32ed215f1c661d9670baf276fb7776James Kung params.setMargins(mMarginSize, mMarginSize, mMarginSize, mMarginSize); 1692cfe25aefb32ed215f1c661d9670baf276fb7776James Kung view.setLayoutParams(params); 1702cfe25aefb32ed215f1c661d9670baf276fb7776James Kung return view; 1712cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 1722cfe25aefb32ed215f1c661d9670baf276fb7776James Kung 1732cfe25aefb32ed215f1c661d9670baf276fb7776James Kung /** 1742cfe25aefb32ed215f1c661d9670baf276fb7776James Kung * Creates a color swatch. 1752cfe25aefb32ed215f1c661d9670baf276fb7776James Kung */ 1762cfe25aefb32ed215f1c661d9670baf276fb7776James Kung private ColorPickerSwatch createColorSwatch(int color, int selectedColor) { 1772cfe25aefb32ed215f1c661d9670baf276fb7776James Kung ColorPickerSwatch view = new ColorPickerSwatch(getContext(), color, 1782cfe25aefb32ed215f1c661d9670baf276fb7776James Kung color == selectedColor, mOnColorSelectedListener); 1792cfe25aefb32ed215f1c661d9670baf276fb7776James Kung TableRow.LayoutParams params = new TableRow.LayoutParams(mSwatchLength, mSwatchLength); 1802cfe25aefb32ed215f1c661d9670baf276fb7776James Kung params.setMargins(mMarginSize, mMarginSize, mMarginSize, mMarginSize); 1812cfe25aefb32ed215f1c661d9670baf276fb7776James Kung view.setLayoutParams(params); 1822cfe25aefb32ed215f1c661d9670baf276fb7776James Kung return view; 1832cfe25aefb32ed215f1c661d9670baf276fb7776James Kung } 1842cfe25aefb32ed215f1c661d9670baf276fb7776James Kung} 185