Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2014 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.printspooler.widget;
     18 
     19 import android.content.Context;
     20 import android.content.res.TypedArray;
     21 import android.util.AttributeSet;
     22 import android.view.View;
     23 import android.view.ViewGroup;
     24 import com.android.printspooler.R;
     25 
     26 /**
     27  * This class is a layout manager for the print options. The options are
     28  * arranged in a configurable number of columns and enough rows to fit all
     29  * the options given the column count.
     30  */
     31 @SuppressWarnings("unused")
     32 public final class PrintOptionsLayout extends ViewGroup {
     33 
     34     private int mColumnCount;
     35 
     36     public PrintOptionsLayout(Context context, AttributeSet attrs) {
     37         super(context, attrs);
     38 
     39         TypedArray typedArray = context.obtainStyledAttributes(attrs,
     40                 R.styleable.PrintOptionsLayout);
     41         mColumnCount = typedArray.getInteger(R.styleable.PrintOptionsLayout_columnCount, 0);
     42         typedArray.recycle();
     43     }
     44 
     45     public void setColumnCount(int columnCount) {
     46         if (mColumnCount != columnCount) {
     47             mColumnCount = columnCount;
     48             requestLayout();
     49         }
     50     }
     51 
     52     @Override
     53     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     54         final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
     55         final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
     56 
     57         final int columnWidth = (widthSize != 0)
     58                 ? (widthSize - mPaddingLeft - mPaddingRight) / mColumnCount : 0;
     59 
     60         int width = 0;
     61         int height = 0;
     62         int childState = 0;
     63 
     64         final int childCount = getChildCount();
     65         final int rowCount = childCount / mColumnCount + childCount % mColumnCount;
     66 
     67         for (int row = 0; row < rowCount; row++) {
     68             int rowWidth = 0;
     69             int rowHeight = 0;
     70 
     71             for (int col = 0; col < mColumnCount; col++) {
     72                 final int childIndex = row * mColumnCount + col;
     73 
     74                 if (childIndex >= childCount) {
     75                     break;
     76                 }
     77 
     78                 View child = getChildAt(childIndex);
     79 
     80                 if (child.getVisibility() == GONE) {
     81                     continue;
     82                 }
     83 
     84                 MarginLayoutParams childParams = (MarginLayoutParams) child.getLayoutParams();
     85 
     86                 final int childWidthMeasureSpec;
     87                 if (columnWidth > 0) {
     88                     childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
     89                             columnWidth - childParams.getMarginStart() - childParams.getMarginEnd(),
     90                             MeasureSpec.EXACTLY);
     91                 } else {
     92                     childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
     93                             getPaddingStart() + getPaddingEnd() + width, childParams.width);
     94                 }
     95 
     96                 final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
     97                         getPaddingTop() + getPaddingBottom() + height, childParams.height);
     98 
     99                 child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    100 
    101                 childState = combineMeasuredStates(childState, child.getMeasuredState());
    102 
    103                 rowWidth += child.getMeasuredWidth() + childParams.getMarginStart()
    104                         + childParams.getMarginEnd();
    105 
    106                 rowHeight = Math.max(rowHeight, child.getMeasuredHeight() + childParams.topMargin
    107                         + childParams.bottomMargin);
    108             }
    109 
    110             width = Math.max(width, rowWidth);
    111             height += rowHeight;
    112         }
    113 
    114         width += getPaddingStart() + getPaddingEnd();
    115         width = Math.max(width, getMinimumWidth());
    116 
    117         height += getPaddingTop() + getPaddingBottom();
    118         height = Math.max(height, getMinimumHeight());
    119 
    120         setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, childState),
    121                 resolveSizeAndState(height, heightMeasureSpec,
    122                         childState << MEASURED_HEIGHT_STATE_SHIFT));
    123     }
    124 
    125     @Override
    126     protected void onLayout(boolean changed, int l, int t, int r, int b) {
    127         final int childCount = getChildCount();
    128         final int rowCount = childCount / mColumnCount + childCount % mColumnCount;
    129 
    130         int cellStart = getPaddingStart();
    131         int cellTop = getPaddingTop();
    132 
    133         for (int row = 0; row < rowCount; row++) {
    134             int rowHeight = 0;
    135 
    136             for (int col = 0; col < mColumnCount; col++) {
    137                 final int childIndex = row * mColumnCount + col;
    138 
    139                 if (childIndex >= childCount) {
    140                     break;
    141                 }
    142 
    143                 View child = getChildAt(childIndex);
    144 
    145                 if (child.getVisibility() == GONE) {
    146                     continue;
    147                 }
    148 
    149                 MarginLayoutParams childParams = (MarginLayoutParams) child.getLayoutParams();
    150 
    151                 final int childLeft = cellStart + childParams.getMarginStart();
    152                 final int childTop = cellTop + childParams.topMargin;
    153                 final int childRight = childLeft + child.getMeasuredWidth();
    154                 final int childBottom = childTop + child.getMeasuredHeight();
    155 
    156                 child.layout(childLeft, childTop, childRight, childBottom);
    157 
    158                 cellStart = childRight + childParams.getMarginEnd();
    159 
    160                 rowHeight = Math.max(rowHeight, child.getMeasuredHeight()
    161                         + childParams.topMargin + childParams.bottomMargin);
    162             }
    163 
    164             cellStart = getPaddingStart();
    165             cellTop += rowHeight;
    166         }
    167     }
    168 
    169     @Override
    170     public LayoutParams generateLayoutParams(AttributeSet attrs) {
    171         return new ViewGroup.MarginLayoutParams(getContext(), attrs);
    172     }
    173 }
    174