blob: 65135ab142d71289f053578bdae6782192a886c3 [file] [log] [blame]
Jason Monk520ea062015-08-18 14:53:06 -04001package com.android.systemui.qs;
2
3import android.content.Context;
4import android.content.res.Resources;
Jason Monkcaf37622015-08-18 12:33:50 -04005import android.util.AttributeSet;
Jason Monk520ea062015-08-18 14:53:06 -04006import android.view.View;
7import android.view.ViewGroup;
Winsonc0d70582016-01-29 10:24:39 -08008
Jason Monk520ea062015-08-18 14:53:06 -04009import com.android.systemui.R;
Jason Monkcaf37622015-08-18 12:33:50 -040010import com.android.systemui.qs.QSPanel.QSTileLayout;
Jason Monk520ea062015-08-18 14:53:06 -040011import com.android.systemui.qs.QSPanel.TileRecord;
12
13import java.util.ArrayList;
14
Jason Monkcaf37622015-08-18 12:33:50 -040015public class TileLayout extends ViewGroup implements QSTileLayout {
Jason Monk520ea062015-08-18 14:53:06 -040016
17 private static final float TILE_ASPECT = 1.2f;
18
19 private static final String TAG = "TileLayout";
20
Jason Monkcaf37622015-08-18 12:33:50 -040021 protected int mColumns;
Xiaohui Chen2f3551b2016-04-07 10:37:25 -070022 protected int mCellWidth;
23 protected int mCellHeight;
24 protected int mCellMargin;
Jason Monk520ea062015-08-18 14:53:06 -040025
Jason Monkcaf37622015-08-18 12:33:50 -040026 protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
Jason Monk6573ef22016-04-06 12:37:18 -040027 private int mCellMarginTop;
Jason Monk1bec6af2016-05-31 15:40:58 -040028 private boolean mListening;
Jason Monkcaf37622015-08-18 12:33:50 -040029
30 public TileLayout(Context context) {
31 this(context, null);
32 }
33
34 public TileLayout(Context context, AttributeSet attrs) {
35 super(context, attrs);
Julia Reynolds20aef8a2016-05-04 16:44:08 -040036 setFocusableInTouchMode(true);
Jason Monk520ea062015-08-18 14:53:06 -040037 updateResources();
38 }
39
Jason Monkcaf37622015-08-18 12:33:50 -040040 @Override
41 public int getOffsetTop(TileRecord tile) {
42 return getTop();
43 }
44
Jason Monk1bec6af2016-05-31 15:40:58 -040045 @Override
46 public void setListening(boolean listening) {
47 if (mListening == listening) return;
48 mListening = listening;
49 for (TileRecord record : mRecords) {
50 record.tile.setListening(this, mListening);
51 }
52 }
53
Jason Monkcaf37622015-08-18 12:33:50 -040054 public void addTile(TileRecord tile) {
55 mRecords.add(tile);
Jason Monk1bec6af2016-05-31 15:40:58 -040056 tile.tile.setListening(this, mListening);
Jason Monkcaf37622015-08-18 12:33:50 -040057 addView(tile.tileView);
58 }
59
60 @Override
61 public void removeTile(TileRecord tile) {
62 mRecords.remove(tile);
Jason Monk1bec6af2016-05-31 15:40:58 -040063 tile.tile.setListening(this, false);
Jason Monkcaf37622015-08-18 12:33:50 -040064 removeView(tile.tileView);
65 }
66
Jason Monkbd6dbb02015-09-03 15:46:25 -040067 public void removeAllViews() {
Jason Monk1bec6af2016-05-31 15:40:58 -040068 for (TileRecord record : mRecords) {
69 record.tile.setListening(this, false);
70 }
Jason Monkbd6dbb02015-09-03 15:46:25 -040071 mRecords.clear();
72 super.removeAllViews();
73 }
74
Jason Monk9d02a432016-01-20 16:33:46 -050075 public boolean updateResources() {
Jason Monk520ea062015-08-18 14:53:06 -040076 final Resources res = mContext.getResources();
77 final int columns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns));
Jason Monk9d02a432016-01-20 16:33:46 -050078 mCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height);
79 mCellMargin = res.getDimensionPixelSize(R.dimen.qs_tile_margin);
Jason Monk6573ef22016-04-06 12:37:18 -040080 mCellMarginTop = res.getDimensionPixelSize(R.dimen.qs_tile_margin_top);
Jason Monk520ea062015-08-18 14:53:06 -040081 if (mColumns != columns) {
82 mColumns = columns;
Jason Monk6573ef22016-04-06 12:37:18 -040083 requestLayout();
Jason Monk9d02a432016-01-20 16:33:46 -050084 return true;
Jason Monk520ea062015-08-18 14:53:06 -040085 }
Jason Monk9d02a432016-01-20 16:33:46 -050086 return false;
Jason Monk94a1bf62015-10-20 08:43:36 -070087 }
88
Jason Monk520ea062015-08-18 14:53:06 -040089 @Override
90 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Jason Monk9d02a432016-01-20 16:33:46 -050091 final int numTiles = mRecords.size();
Jason Monk520ea062015-08-18 14:53:06 -040092 final int width = MeasureSpec.getSize(widthMeasureSpec);
Jason Monk9d02a432016-01-20 16:33:46 -050093 final int rows = (numTiles + mColumns - 1) / mColumns;
94 mCellWidth = (width - (mCellMargin * (mColumns + 1))) / mColumns;
Jason Monk520ea062015-08-18 14:53:06 -040095
96 View previousView = this;
97 for (TileRecord record : mRecords) {
Jason Monk520ea062015-08-18 14:53:06 -040098 if (record.tileView.getVisibility() == GONE) continue;
Jason Monk9d02a432016-01-20 16:33:46 -050099 record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight));
Jason Monk520ea062015-08-18 14:53:06 -0400100 previousView = record.tileView.updateAccessibilityOrder(previousView);
101 }
Evan Laird92fbcb22018-02-16 15:25:53 +0000102 int height = (mCellHeight + mCellMargin) * rows + (mCellMarginTop - mCellMargin);
Jason Monkcedcb942017-02-06 14:37:29 -0800103 if (height < 0) height = 0;
104 setMeasuredDimension(width, height);
Jason Monk520ea062015-08-18 14:53:06 -0400105 }
106
Amin Shaikh7e6e64c2018-02-07 16:07:24 -0500107 @Override
108 public boolean hasOverlappingRendering() {
109 return false;
110 }
111
Jason Monk520ea062015-08-18 14:53:06 -0400112 private static int exactly(int size) {
113 return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
114 }
115
116 @Override
117 protected void onLayout(boolean changed, int l, int t, int r, int b) {
118 final int w = getWidth();
119 boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
Jason Monk9d02a432016-01-20 16:33:46 -0500120 int row = 0;
121 int column = 0;
122 for (int i = 0; i < mRecords.size(); i++, column++) {
123 if (column == mColumns) {
124 row++;
125 column -= mColumns;
126 }
127 TileRecord record = mRecords.get(i);
128 int left = getColumnStart(column);
129 final int top = getRowTop(row);
Jason Monk520ea062015-08-18 14:53:06 -0400130 int right;
Jason Monk520ea062015-08-18 14:53:06 -0400131 if (isRtl) {
132 right = w - left;
Jason Monk9d02a432016-01-20 16:33:46 -0500133 left = right - mCellWidth;
Jason Monk520ea062015-08-18 14:53:06 -0400134 } else {
Jason Monk9d02a432016-01-20 16:33:46 -0500135 right = left + mCellWidth;
Jason Monk520ea062015-08-18 14:53:06 -0400136 }
137 record.tileView.layout(left, top, right, top + record.tileView.getMeasuredHeight());
138 }
139 }
140
141 private int getRowTop(int row) {
Jason Monk6573ef22016-04-06 12:37:18 -0400142 return row * (mCellHeight + mCellMargin) + mCellMarginTop;
Jason Monk520ea062015-08-18 14:53:06 -0400143 }
144
Jason Monk9d02a432016-01-20 16:33:46 -0500145 private int getColumnStart(int column) {
146 return column * (mCellWidth + mCellMargin) + mCellMargin;
Jason Monk520ea062015-08-18 14:53:06 -0400147 }
Jason Monk520ea062015-08-18 14:53:06 -0400148}