Home | History | Annotate | Download | only in qs
      1 package com.android.systemui.qs;
      2 
      3 import android.content.Context;
      4 import android.content.res.Resources;
      5 import android.util.AttributeSet;
      6 import android.view.View;
      7 import android.view.ViewGroup;
      8 
      9 import com.android.systemui.R;
     10 import com.android.systemui.qs.QSPanel.QSTileLayout;
     11 import com.android.systemui.qs.QSPanel.TileRecord;
     12 
     13 import java.util.ArrayList;
     14 
     15 public 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 mCellMarginHorizontal;
     25     protected int mCellMarginVertical;
     26     protected int mSidePadding;
     27 
     28     protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
     29     private int mCellMarginTop;
     30     private boolean mListening;
     31 
     32     public TileLayout(Context context) {
     33         this(context, null);
     34     }
     35 
     36     public TileLayout(Context context, AttributeSet attrs) {
     37         super(context, attrs);
     38         setFocusableInTouchMode(true);
     39         updateResources();
     40     }
     41 
     42     @Override
     43     public int getOffsetTop(TileRecord tile) {
     44         return getTop();
     45     }
     46 
     47     @Override
     48     public void setListening(boolean listening) {
     49         if (mListening == listening) return;
     50         mListening = listening;
     51         for (TileRecord record : mRecords) {
     52             record.tile.setListening(this, mListening);
     53         }
     54     }
     55 
     56     public void addTile(TileRecord tile) {
     57         mRecords.add(tile);
     58         tile.tile.setListening(this, mListening);
     59         addView(tile.tileView);
     60     }
     61 
     62     @Override
     63     public void removeTile(TileRecord tile) {
     64         mRecords.remove(tile);
     65         tile.tile.setListening(this, false);
     66         removeView(tile.tileView);
     67     }
     68 
     69     public void removeAllViews() {
     70         for (TileRecord record : mRecords) {
     71             record.tile.setListening(this, false);
     72         }
     73         mRecords.clear();
     74         super.removeAllViews();
     75     }
     76 
     77     public boolean updateResources() {
     78         final Resources res = mContext.getResources();
     79         final int columns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns));
     80         mCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height);
     81         mCellMarginHorizontal = res.getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal);
     82         mCellMarginVertical= res.getDimensionPixelSize(R.dimen.qs_tile_margin_vertical);
     83         mCellMarginTop = res.getDimensionPixelSize(R.dimen.qs_tile_margin_top);
     84         mSidePadding = res.getDimensionPixelOffset(R.dimen.qs_tile_layout_margin_side);
     85         if (mColumns != columns) {
     86             mColumns = columns;
     87             requestLayout();
     88             return true;
     89         }
     90         return false;
     91     }
     92 
     93     @Override
     94     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     95         final int numTiles = mRecords.size();
     96         final int width = MeasureSpec.getSize(widthMeasureSpec)
     97                 - getPaddingStart() - getPaddingEnd();
     98         final int numRows = (numTiles + mColumns - 1) / mColumns;
     99         mCellWidth = (width - mSidePadding * 2 - (mCellMarginHorizontal * mColumns)) / mColumns;
    100 
    101         // Measure each QS tile.
    102         View previousView = this;
    103         for (TileRecord record : mRecords) {
    104             if (record.tileView.getVisibility() == GONE) continue;
    105             record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight));
    106             previousView = record.tileView.updateAccessibilityOrder(previousView);
    107         }
    108 
    109         // Only include the top margin in our measurement if we have more than 1 row to show.
    110         // Otherwise, don't add the extra margin buffer at top.
    111         int height = (mCellHeight + mCellMarginVertical) * numRows +
    112                 (numRows != 0 ? (mCellMarginTop - mCellMarginVertical) : 0);
    113         if (height < 0) height = 0;
    114 
    115         setMeasuredDimension(width, height);
    116     }
    117 
    118     @Override
    119     public boolean hasOverlappingRendering() {
    120         return false;
    121     }
    122 
    123     private static int exactly(int size) {
    124         return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
    125     }
    126 
    127     @Override
    128     protected void onLayout(boolean changed, int l, int t, int r, int b) {
    129         final int w = getWidth();
    130         final boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
    131         int row = 0;
    132         int column = 0;
    133 
    134         // Layout each QS tile.
    135         for (int i = 0; i < mRecords.size(); i++, column++) {
    136             // If we reached the last column available to layout a tile, wrap back to the next row.
    137             if (column == mColumns) {
    138                 column = 0;
    139                 row++;
    140             }
    141 
    142             final TileRecord record = mRecords.get(i);
    143             final int top = getRowTop(row);
    144             final int left = getColumnStart(isRtl ? mColumns - column - 1 : column);
    145             final int right = left + mCellWidth;
    146             record.tileView.layout(left, top, right, top + record.tileView.getMeasuredHeight());
    147         }
    148     }
    149 
    150     private int getRowTop(int row) {
    151         return row * (mCellHeight + mCellMarginVertical) + mCellMarginTop;
    152     }
    153 
    154     private int getColumnStart(int column) {
    155         return getPaddingStart() + mSidePadding + mCellMarginHorizontal / 2 +
    156                 column *  (mCellWidth + mCellMarginHorizontal);
    157     }
    158 }
    159