Home | History | Annotate | Download | only in colorpicker
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.colorpicker;
     18 
     19 import android.content.Context;
     20 import android.content.res.Resources;
     21 import android.util.AttributeSet;
     22 import android.view.View;
     23 import android.view.ViewGroup;
     24 import android.widget.ImageView;
     25 import android.widget.TableLayout;
     26 import android.widget.TableRow;
     27 
     28 import com.android.colorpicker.ColorPickerSwatch.OnColorSelectedListener;
     29 
     30 /**
     31  * A color picker custom view which creates an grid of color squares.  The number of squares per
     32  * row (and the padding between the squares) is determined by the user.
     33  */
     34 public class ColorPickerPalette extends TableLayout {
     35 
     36     public OnColorSelectedListener mOnColorSelectedListener;
     37 
     38     private String mDescription;
     39     private String mDescriptionSelected;
     40 
     41     private int mSwatchLength;
     42     private int mMarginSize;
     43     private int mNumColumns;
     44 
     45     public ColorPickerPalette(Context context, AttributeSet attrs) {
     46         super(context, attrs);
     47     }
     48 
     49     public ColorPickerPalette(Context context) {
     50         super(context);
     51     }
     52 
     53     /**
     54      * Initialize the size, columns, and listener.  Size should be a pre-defined size (SIZE_LARGE
     55      * or SIZE_SMALL) from ColorPickerDialogFragment.
     56      */
     57     public void init(int size, int columns, OnColorSelectedListener listener) {
     58         mNumColumns = columns;
     59         Resources res = getResources();
     60         if (size == ColorPickerDialog.SIZE_LARGE) {
     61             mSwatchLength = res.getDimensionPixelSize(R.dimen.color_swatch_large);
     62             mMarginSize = res.getDimensionPixelSize(R.dimen.color_swatch_margins_large);
     63         } else {
     64             mSwatchLength = res.getDimensionPixelSize(R.dimen.color_swatch_small);
     65             mMarginSize = res.getDimensionPixelSize(R.dimen.color_swatch_margins_small);
     66         }
     67         mOnColorSelectedListener = listener;
     68 
     69         mDescription = res.getString(R.string.color_swatch_description);
     70         mDescriptionSelected = res.getString(R.string.color_swatch_description_selected);
     71     }
     72 
     73     private TableRow createTableRow() {
     74         TableRow row = new TableRow(getContext());
     75         ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,
     76                 LayoutParams.WRAP_CONTENT);
     77         row.setLayoutParams(params);
     78         return row;
     79     }
     80 
     81     /**
     82      * Adds swatches to table in a serpentine format.
     83      */
     84     public void drawPalette(int[] colors, int selectedColor) {
     85         drawPalette(colors, selectedColor, null);
     86     }
     87 
     88     /**
     89      * Adds swatches to table in a serpentine format.
     90      */
     91     public void drawPalette(int[] colors, int selectedColor, String[] colorContentDescriptions) {
     92         if (colors == null) {
     93             return;
     94         }
     95 
     96         this.removeAllViews();
     97         int tableElements = 0;
     98         int rowElements = 0;
     99         int rowNumber = 0;
    100 
    101         // Fills the table with swatches based on the array of colors.
    102         TableRow row = createTableRow();
    103         for (int color : colors) {
    104             View colorSwatch = createColorSwatch(color, selectedColor);
    105             setSwatchDescription(rowNumber, tableElements, rowElements, color == selectedColor,
    106                     colorSwatch, colorContentDescriptions);
    107             addSwatchToRow(row, colorSwatch, rowNumber);
    108 
    109             tableElements++;
    110             rowElements++;
    111             if (rowElements == mNumColumns) {
    112                 addView(row);
    113                 row = createTableRow();
    114                 rowElements = 0;
    115                 rowNumber++;
    116             }
    117         }
    118 
    119         // Create blank views to fill the row if the last row has not been filled.
    120         if (rowElements > 0) {
    121             while (rowElements != mNumColumns) {
    122                 addSwatchToRow(row, createBlankSpace(), rowNumber);
    123                 rowElements++;
    124             }
    125             addView(row);
    126         }
    127     }
    128 
    129     /**
    130      * Appends a swatch to the end of the row for even-numbered rows (starting with row 0),
    131      * to the beginning of a row for odd-numbered rows.
    132      */
    133     private static void addSwatchToRow(TableRow row, View swatch, int rowNumber) {
    134         if (rowNumber % 2 == 0) {
    135             row.addView(swatch);
    136         } else {
    137             row.addView(swatch, 0);
    138         }
    139     }
    140 
    141     /**
    142      * Add a content description to the specified swatch view. Because the colors get added in a
    143      * snaking form, every other row will need to compensate for the fact that the colors are added
    144      * in an opposite direction from their left->right/top->bottom order, which is how the system
    145      * will arrange them for accessibility purposes.
    146      */
    147     private void setSwatchDescription(int rowNumber, int index, int rowElements, boolean selected,
    148             View swatch, String[] contentDescriptions) {
    149         String description;
    150         if (contentDescriptions != null && contentDescriptions.length > index) {
    151             description = contentDescriptions[index];
    152         } else {
    153             int accessibilityIndex;
    154             if (rowNumber % 2 == 0) {
    155                 // We're in a regular-ordered row
    156                 accessibilityIndex = index + 1;
    157             } else {
    158                 // We're in a backwards-ordered row.
    159                 int rowMax = ((rowNumber + 1) * mNumColumns);
    160                 accessibilityIndex = rowMax - rowElements;
    161             }
    162 
    163             if (selected) {
    164                 description = String.format(mDescriptionSelected, accessibilityIndex);
    165             } else {
    166                 description = String.format(mDescription, accessibilityIndex);
    167             }
    168         }
    169         swatch.setContentDescription(description);
    170     }
    171 
    172     /**
    173      * Creates a blank space to fill the row.
    174      */
    175     private ImageView createBlankSpace() {
    176         ImageView view = new ImageView(getContext());
    177         TableRow.LayoutParams params = new TableRow.LayoutParams(mSwatchLength, mSwatchLength);
    178         params.setMargins(mMarginSize, mMarginSize, mMarginSize, mMarginSize);
    179         view.setLayoutParams(params);
    180         return view;
    181     }
    182 
    183     /**
    184      * Creates a color swatch.
    185      */
    186     private ColorPickerSwatch createColorSwatch(int color, int selectedColor) {
    187         ColorPickerSwatch view = new ColorPickerSwatch(getContext(), color,
    188                 color == selectedColor, mOnColorSelectedListener);
    189         TableRow.LayoutParams params = new TableRow.LayoutParams(mSwatchLength, mSwatchLength);
    190         params.setMargins(mMarginSize, mMarginSize, mMarginSize, mMarginSize);
    191         view.setLayoutParams(params);
    192         return view;
    193     }
    194 }
    195