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