1d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung/* 2d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * Copyright (C) 2012 The Android Open Source Project 3d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * 4d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * you may not use this file except in compliance with the License. 6d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * You may obtain a copy of the License at 7d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * 8d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 9d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * 10d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * Unless required by applicable law or agreed to in writing, software 11d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * See the License for the specific language governing permissions and 14d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * limitations under the License. 15d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung */ 16d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 17d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungpackage com.android.systemui.statusbar.phone; 18d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 19d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.animation.LayoutTransition; 20d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.content.Context; 21d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.content.res.Resources; 22d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.util.AttributeSet; 23c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chungimport android.view.View; 24d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.view.ViewGroup; 25d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.widget.FrameLayout; 26d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 27d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport com.android.systemui.R; 28d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 29d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung/** 30d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * 31d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung */ 32d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungclass QuickSettingsContainerView extends FrameLayout { 33d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 34d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // The number of columns in the QuickSettings grid 35d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung private int mNumColumns; 36d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 37d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // The gap between tiles in the QuickSettings grid 38d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung private float mCellGap; 39d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 40d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung public QuickSettingsContainerView(Context context, AttributeSet attrs) { 41d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung super(context, attrs); 42d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 43d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung updateResources(); 44d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 45d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 46d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung @Override 47d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung protected void onFinishInflate() { 48d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung super.onFinishInflate(); 49d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 50d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // TODO: Setup the layout transitions 51d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung LayoutTransition transitions = getLayoutTransition(); 52d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 53d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 54d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung void updateResources() { 55d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung Resources r = getContext().getResources(); 56d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung mCellGap = r.getDimension(R.dimen.quick_settings_cell_gap); 57d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung mNumColumns = r.getInteger(R.integer.quick_settings_num_columns); 58d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung requestLayout(); 59d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 60d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 61d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung @Override 62d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 63d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Calculate the cell width dynamically 64d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int width = MeasureSpec.getSize(widthMeasureSpec); 65d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int height = MeasureSpec.getSize(heightMeasureSpec); 66d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int availableWidth = (int) (width - getPaddingLeft() - getPaddingRight() - 67d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung (mNumColumns - 1) * mCellGap); 68f4b5ab193c95675c07b8e361846d21d79571da0eWinson Chung float cellWidth = (float) Math.ceil(((float) availableWidth) / mNumColumns); 69d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 70d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Update each of the children's widths accordingly to the cell width 71d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int N = getChildCount(); 72d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int cellHeight = 0; 73d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int cursor = 0; 74d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung for (int i = 0; i < N; ++i) { 75d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Update the child's width 76d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung QuickSettingsTileView v = (QuickSettingsTileView) getChildAt(i); 77c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung if (v.getVisibility() != View.GONE) { 78c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams(); 79c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung int colSpan = v.getColumnSpan(); 80c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung lp.width = (int) ((colSpan * cellWidth) + (colSpan - 1) * mCellGap); 81c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung 82c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung // Measure the child 83c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung int newWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); 84c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung int newHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); 85c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung v.measure(newWidthSpec, newHeightSpec); 86c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung 87c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung // Save the cell height 88c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung if (cellHeight <= 0) { 89c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung cellHeight = v.getMeasuredHeight(); 90c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung } 91c86b23b9a6bc4763ff3fbe8d0ae8a9b2e21a1649Winson Chung cursor += colSpan; 92d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 93d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 94d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 95d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Set the measured dimensions. We always fill the tray width, but wrap to the height of 96d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // all the tiles. 97d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int numRows = (int) Math.ceil((float) cursor / mNumColumns); 98d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int newHeight = (int) ((numRows * cellHeight) + ((numRows - 1) * mCellGap)) + 99d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung getPaddingTop() + getPaddingBottom(); 100d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung setMeasuredDimension(width, newHeight); 101d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 102d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 103d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung @Override 104d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 105d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int N = getChildCount(); 106d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int x = getPaddingLeft(); 107d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int y = getPaddingTop(); 108d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int cursor = 0; 109d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung for (int i = 0; i < N; ++i) { 110d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung QuickSettingsTileView v = (QuickSettingsTileView) getChildAt(i); 111d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) v.getLayoutParams(); 112d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung if (v.getVisibility() != GONE) { 113d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int col = cursor % mNumColumns; 114d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int colSpan = v.getColumnSpan(); 115d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int row = (int) (cursor / mNumColumns); 116d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 117d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Push the item to the next row if it can't fit on this one 118d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung if ((col + colSpan) > mNumColumns) { 119d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung x = getPaddingLeft(); 120d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung y += lp.height + mCellGap; 121d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung row++; 122d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 123d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 124d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Layout the container 125d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung v.layout(x, y, x + lp.width, y + lp.height); 126d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 127d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Offset the position by the cell gap or reset the position and cursor when we 128d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // reach the end of the row 129d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung cursor += v.getColumnSpan(); 130d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung if (cursor < (((row + 1) * mNumColumns))) { 131d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung x += lp.width + mCellGap; 132d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } else { 133d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung x = getPaddingLeft(); 134d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung y += lp.height + mCellGap; 135d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 136d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 137d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 138d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 139d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung}