1a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav/*
2a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Copyright (C) 2014 The Android Open Source Project
3a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *
4a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Licensed under the Apache License, Version 2.0 (the "License");
5a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * you may not use this file except in compliance with the License.
6a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * You may obtain a copy of the License at
7a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *
8a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *      http://www.apache.org/licenses/LICENSE-2.0
9a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *
10a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Unless required by applicable law or agreed to in writing, software
11a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * distributed under the License is distributed on an "AS IS" BASIS,
12a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * See the License for the specific language governing permissions and
14a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * limitations under the License.
15a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav */
16a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
17a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavpackage com.android.printspooler.widget;
18a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
19a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.content.Context;
20a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.content.res.TypedArray;
21a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.util.AttributeSet;
22a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.view.View;
23a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.view.ViewGroup;
24a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport com.android.printspooler.R;
25a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
26a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav/**
27a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * This class is a layout manager for the print options. The options are
28a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * arranged in a configurable number of columns and enough rows to fit all
29a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * the options given the column count.
30a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav */
31a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav@SuppressWarnings("unused")
32a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavpublic final class PrintOptionsLayout extends ViewGroup {
33a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
34525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    private int mColumnCount;
35a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
36a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public PrintOptionsLayout(Context context, AttributeSet attrs) {
37a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        super(context, attrs);
38a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
39a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        TypedArray typedArray = context.obtainStyledAttributes(attrs,
40a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                R.styleable.PrintOptionsLayout);
41a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        mColumnCount = typedArray.getInteger(R.styleable.PrintOptionsLayout_columnCount, 0);
42a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        typedArray.recycle();
43a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
44a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
45525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    public void setColumnCount(int columnCount) {
46525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        if (mColumnCount != columnCount) {
47525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            mColumnCount = columnCount;
48525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            requestLayout();
49525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        }
50525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    }
51525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
52a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    @Override
53a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
54a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
55a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
56a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
57a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int columnWidth = (widthSize != 0)
58a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                ? (widthSize - mPaddingLeft - mPaddingRight) / mColumnCount : 0;
59a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
60a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        int width = 0;
61a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        int height = 0;
62a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        int childState = 0;
63a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
64a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int childCount = getChildCount();
65a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int rowCount = childCount / mColumnCount + childCount % mColumnCount;
66a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
67a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        for (int row = 0; row < rowCount; row++) {
68a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            int rowWidth = 0;
69a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            int rowHeight = 0;
70a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
71a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            for (int col = 0; col < mColumnCount; col++) {
72a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                final int childIndex = row * mColumnCount + col;
73a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
74a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (childIndex >= childCount) {
75a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    break;
76a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
77a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
78a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                View child = getChildAt(childIndex);
79a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
80a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (child.getVisibility() == GONE) {
81a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    continue;
82a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
83a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
84a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                MarginLayoutParams childParams = (MarginLayoutParams) child.getLayoutParams();
85a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
86a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                final int childWidthMeasureSpec;
87a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (columnWidth > 0) {
88a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
89a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                            columnWidth - childParams.getMarginStart() - childParams.getMarginEnd(),
90a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                            MeasureSpec.EXACTLY);
91a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                } else {
923ab1ec05491d5da8eea070889c03b6ea4f2af5bcSvetoslav                    childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
93a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                            getPaddingStart() + getPaddingEnd() + width, childParams.width);
94a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
95a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
96a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
97a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        getPaddingTop() + getPaddingBottom() + height, childParams.height);
98a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
99a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
100a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
101a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                childState = combineMeasuredStates(childState, child.getMeasuredState());
102a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
103a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                rowWidth += child.getMeasuredWidth() + childParams.getMarginStart()
104a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        + childParams.getMarginEnd();
105a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
106a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                rowHeight = Math.max(rowHeight, child.getMeasuredHeight() + childParams.topMargin
107a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        + childParams.bottomMargin);
108a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            }
109a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
110a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            width = Math.max(width, rowWidth);
111a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            height += rowHeight;
112a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
113a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
114a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        width += getPaddingStart() + getPaddingEnd();
115a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        width = Math.max(width, getMinimumWidth());
116a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
117a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        height += getPaddingTop() + getPaddingBottom();
118a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        height = Math.max(height, getMinimumHeight());
119a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
120a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, childState),
121a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                resolveSizeAndState(height, heightMeasureSpec,
122a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        childState << MEASURED_HEIGHT_STATE_SHIFT));
123a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
124a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
125a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    @Override
126a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    protected void onLayout(boolean changed, int l, int t, int r, int b) {
127a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int childCount = getChildCount();
128a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int rowCount = childCount / mColumnCount + childCount % mColumnCount;
129a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
130a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        int cellStart = getPaddingStart();
131a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        int cellTop = getPaddingTop();
132a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
133a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        for (int row = 0; row < rowCount; row++) {
134a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            int rowHeight = 0;
135a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
136a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            for (int col = 0; col < mColumnCount; col++) {
137a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                final int childIndex = row * mColumnCount + col;
138a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
139a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (childIndex >= childCount) {
140a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    break;
141a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
142a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
143a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                View child = getChildAt(childIndex);
144a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
145a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (child.getVisibility() == GONE) {
146a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    continue;
147a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
148a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
149a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                MarginLayoutParams childParams = (MarginLayoutParams) child.getLayoutParams();
150a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
151a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                final int childLeft = cellStart + childParams.getMarginStart();
152a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                final int childTop = cellTop + childParams.topMargin;
153a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                final int childRight = childLeft + child.getMeasuredWidth();
154a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                final int childBottom = childTop + child.getMeasuredHeight();
155a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
156a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                child.layout(childLeft, childTop, childRight, childBottom);
157a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
158a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                cellStart = childRight + childParams.getMarginEnd();
159a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
160a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                rowHeight = Math.max(rowHeight, child.getMeasuredHeight()
161a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        + childParams.topMargin + childParams.bottomMargin);
162a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            }
163a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
164a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            cellStart = getPaddingStart();
16538781bd2c2c61385651314098b4a615cb8e8efa1Svet Ganov            cellTop += rowHeight;
166a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
167a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
168a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
169a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    @Override
170a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public LayoutParams generateLayoutParams(AttributeSet attrs) {
171a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        return new ViewGroup.MarginLayoutParams(getContext(), attrs);
172a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
173a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav}
174