1/*
2 * Copyright (C) 2012 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
17package com.android.systemui.statusbar.phone;
18
19import android.animation.LayoutTransition;
20import android.content.Context;
21import android.content.res.Resources;
22import android.util.AttributeSet;
23import android.view.View;
24import android.view.ViewGroup;
25import android.widget.FrameLayout;
26
27import com.android.systemui.R;
28
29/**
30 *
31 */
32class QuickSettingsContainerView extends FrameLayout {
33
34    // The number of columns in the QuickSettings grid
35    private int mNumColumns;
36
37    // The gap between tiles in the QuickSettings grid
38    private float mCellGap;
39
40    public QuickSettingsContainerView(Context context, AttributeSet attrs) {
41        super(context, attrs);
42
43        updateResources();
44    }
45
46    @Override
47    protected void onFinishInflate() {
48        super.onFinishInflate();
49
50        // TODO: Setup the layout transitions
51        LayoutTransition transitions = getLayoutTransition();
52    }
53
54    void updateResources() {
55        Resources r = getContext().getResources();
56        mCellGap = r.getDimension(R.dimen.quick_settings_cell_gap);
57        mNumColumns = r.getInteger(R.integer.quick_settings_num_columns);
58        requestLayout();
59    }
60
61    @Override
62    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
63        // Calculate the cell width dynamically
64        int width = MeasureSpec.getSize(widthMeasureSpec);
65        int height = MeasureSpec.getSize(heightMeasureSpec);
66        int availableWidth = (int) (width - getPaddingLeft() - getPaddingRight() -
67                (mNumColumns - 1) * mCellGap);
68        float cellWidth = (float) Math.ceil(((float) availableWidth) / mNumColumns);
69
70        // Update each of the children's widths accordingly to the cell width
71        final int N = getChildCount();
72        int cellHeight = 0;
73        int cursor = 0;
74        for (int i = 0; i < N; ++i) {
75            // Update the child's width
76            QuickSettingsTileView v = (QuickSettingsTileView) getChildAt(i);
77            if (v.getVisibility() != View.GONE) {
78                ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
79                int colSpan = v.getColumnSpan();
80                lp.width = (int) ((colSpan * cellWidth) + (colSpan - 1) * mCellGap);
81
82                // Measure the child
83                int newWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
84                int newHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
85                v.measure(newWidthSpec, newHeightSpec);
86
87                // Save the cell height
88                if (cellHeight <= 0) {
89                    cellHeight = v.getMeasuredHeight();
90                }
91                cursor += colSpan;
92            }
93        }
94
95        // Set the measured dimensions.  We always fill the tray width, but wrap to the height of
96        // all the tiles.
97        int numRows = (int) Math.ceil((float) cursor / mNumColumns);
98        int newHeight = (int) ((numRows * cellHeight) + ((numRows - 1) * mCellGap)) +
99                getPaddingTop() + getPaddingBottom();
100        setMeasuredDimension(width, newHeight);
101    }
102
103    @Override
104    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
105        final int N = getChildCount();
106        final boolean isLayoutRtl = isLayoutRtl();
107        final int width = getWidth();
108
109        int x = getPaddingStart();
110        int y = getPaddingTop();
111        int cursor = 0;
112
113        for (int i = 0; i < N; ++i) {
114            QuickSettingsTileView child = (QuickSettingsTileView) getChildAt(i);
115            ViewGroup.LayoutParams lp = child.getLayoutParams();
116            if (child.getVisibility() != GONE) {
117                final int col = cursor % mNumColumns;
118                final int colSpan = child.getColumnSpan();
119
120                final int childWidth = lp.width;
121                final int childHeight = lp.height;
122
123                int row = (int) (cursor / mNumColumns);
124
125                // Push the item to the next row if it can't fit on this one
126                if ((col + colSpan) > mNumColumns) {
127                    x = getPaddingStart();
128                    y += childHeight + mCellGap;
129                    row++;
130                }
131
132                final int childLeft = (isLayoutRtl) ? width - x - childWidth : x;
133                final int childRight = childLeft + childWidth;
134
135                final int childTop = y;
136                final int childBottom = childTop + childHeight;
137
138                // Layout the container
139                child.layout(childLeft, childTop, childRight, childBottom);
140
141                // Offset the position by the cell gap or reset the position and cursor when we
142                // reach the end of the row
143                cursor += child.getColumnSpan();
144                if (cursor < (((row + 1) * mNumColumns))) {
145                    x += childWidth + mCellGap;
146                } else {
147                    x = getPaddingStart();
148                    y += childHeight + mCellGap;
149                }
150            }
151        }
152    }
153}