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 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 int N = getChildCount(); 106 int x = getPaddingLeft(); 107 int y = getPaddingTop(); 108 int cursor = 0; 109 for (int i = 0; i < N; ++i) { 110 QuickSettingsTileView v = (QuickSettingsTileView) getChildAt(i); 111 ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) v.getLayoutParams(); 112 if (v.getVisibility() != GONE) { 113 int col = cursor % mNumColumns; 114 int colSpan = v.getColumnSpan(); 115 int row = (int) (cursor / mNumColumns); 116 117 // Push the item to the next row if it can't fit on this one 118 if ((col + colSpan) > mNumColumns) { 119 x = getPaddingLeft(); 120 y += lp.height + mCellGap; 121 row++; 122 } 123 124 // Layout the container 125 v.layout(x, y, x + lp.width, y + lp.height); 126 127 // Offset the position by the cell gap or reset the position and cursor when we 128 // reach the end of the row 129 cursor += v.getColumnSpan(); 130 if (cursor < (((row + 1) * mNumColumns))) { 131 x += lp.width + mCellGap; 132 } else { 133 x = getPaddingLeft(); 134 y += lp.height + mCellGap; 135 } 136 } 137 } 138 } 139}