1package com.android.systemui.qs;
2
3import android.content.Context;
4import android.content.res.Resources;
5import android.util.AttributeSet;
6import android.view.View;
7import android.view.ViewGroup;
8
9import com.android.systemui.R;
10import com.android.systemui.qs.QSPanel.QSTileLayout;
11import com.android.systemui.qs.QSPanel.TileRecord;
12
13import java.util.ArrayList;
14
15public class TileLayout extends ViewGroup implements QSTileLayout {
16
17    private static final float TILE_ASPECT = 1.2f;
18
19    private static final String TAG = "TileLayout";
20
21    protected int mColumns;
22    protected int mCellWidth;
23    protected int mCellHeight;
24    protected int mCellMargin;
25
26    protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
27    private int mCellMarginTop;
28    private boolean mListening;
29
30    public TileLayout(Context context) {
31        this(context, null);
32    }
33
34    public TileLayout(Context context, AttributeSet attrs) {
35        super(context, attrs);
36        setFocusableInTouchMode(true);
37        updateResources();
38    }
39
40    @Override
41    public int getOffsetTop(TileRecord tile) {
42        return getTop();
43    }
44
45    @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
54    public void addTile(TileRecord tile) {
55        mRecords.add(tile);
56        tile.tile.setListening(this, mListening);
57        addView(tile.tileView);
58    }
59
60    @Override
61    public void removeTile(TileRecord tile) {
62        mRecords.remove(tile);
63        tile.tile.setListening(this, false);
64        removeView(tile.tileView);
65    }
66
67    public void removeAllViews() {
68        for (TileRecord record : mRecords) {
69            record.tile.setListening(this, false);
70        }
71        mRecords.clear();
72        super.removeAllViews();
73    }
74
75    public boolean updateResources() {
76        final Resources res = mContext.getResources();
77        final int columns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns));
78        mCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height);
79        mCellMargin = res.getDimensionPixelSize(R.dimen.qs_tile_margin);
80        mCellMarginTop = res.getDimensionPixelSize(R.dimen.qs_tile_margin_top);
81        if (mColumns != columns) {
82            mColumns = columns;
83            requestLayout();
84            return true;
85        }
86        return false;
87    }
88
89    @Override
90    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
91        final int numTiles = mRecords.size();
92        final int width = MeasureSpec.getSize(widthMeasureSpec);
93        final int rows = (numTiles + mColumns - 1) / mColumns;
94        mCellWidth = (width - (mCellMargin * (mColumns + 1))) / mColumns;
95
96        View previousView = this;
97        for (TileRecord record : mRecords) {
98            if (record.tileView.getVisibility() == GONE) continue;
99            record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight));
100            previousView = record.tileView.updateAccessibilityOrder(previousView);
101        }
102        int height = (mCellHeight + mCellMargin) * rows + (mCellMarginTop - mCellMargin);
103        if (height < 0) height = 0;
104        setMeasuredDimension(width, height);
105    }
106
107    private static int exactly(int size) {
108        return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
109    }
110
111    @Override
112    protected void onLayout(boolean changed, int l, int t, int r, int b) {
113        final int w = getWidth();
114        boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
115        int row = 0;
116        int column = 0;
117        for (int i = 0; i < mRecords.size(); i++, column++) {
118            if (column == mColumns) {
119                row++;
120                column -= mColumns;
121            }
122            TileRecord record = mRecords.get(i);
123            int left = getColumnStart(column);
124            final int top = getRowTop(row);
125            int right;
126            if (isRtl) {
127                right = w - left;
128                left = right - mCellWidth;
129            } else {
130                right = left + mCellWidth;
131            }
132            record.tileView.layout(left, top, right, top + record.tileView.getMeasuredHeight());
133        }
134    }
135
136    private int getRowTop(int row) {
137        return row * (mCellHeight + mCellMargin) + mCellMarginTop;
138    }
139
140    private int getColumnStart(int column) {
141        return column * (mCellWidth + mCellMargin) + mCellMargin;
142    }
143}
144