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 17 package com.android.systemui.statusbar.phone; 18 19 import android.animation.LayoutTransition; 20 import android.content.Context; 21 import android.content.res.Resources; 22 import android.util.AttributeSet; 23 import android.view.View; 24 import android.view.ViewGroup; 25 import android.widget.FrameLayout; 26 27 import com.android.systemui.R; 28 29 /** 30 * 31 */ 32 class 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 }