Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b3f02e2 authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Fix layout of DoubleLineTileLayout

With this CL, the layout calculates how many columns it can safely show
given the available space and distributes the tiles accordingly. This
prevents the tiles from going out of the bounds of the container
(happening even in Default Display Size).

With the change in the minimum horizontal margin, the three lowest
Display Size will show three columns and the others will show 2. Showing
two columns has not great expansion animations.

Opening a bug to explore UI.

Fixes: 151810573
Bug: 152429614
Test: manual

Change-Id: I8e123c4497f51f0d5c83b8eb14319f488a96bc9a
parent dce5a573
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -477,6 +477,7 @@
    <dimen name="qs_tile_height">106dp</dimen>
    <dimen name="qs_tile_layout_margin_side">6dp</dimen>
    <dimen name="qs_tile_margin_horizontal">18dp</dimen>
    <dimen name="qs_tile_margin_horizontal_two_line">2dp</dimen>
    <dimen name="qs_tile_margin_vertical">24dp</dimen>
    <dimen name="qs_tile_margin_top_bottom">12dp</dimen>
    <dimen name="qs_tile_margin_top_bottom_negative">-12dp</dimen>
+50 −25
Original line number Diff line number Diff line
@@ -25,13 +25,18 @@ import com.android.systemui.qs.TileLayout.exactly

class DoubleLineTileLayout(context: Context) : ViewGroup(context), QSPanel.QSTileLayout {

    companion object {
        private const val NUM_LINES = 2
    }

    protected val mRecords = ArrayList<QSPanel.TileRecord>()
    private var _listening = false
    private var smallTileSize = 0
    private val twoLineHeight
        get() = smallTileSize * 2 + cellMarginVertical
        get() = smallTileSize * NUM_LINES + cellMarginVertical * (NUM_LINES - 1)
    private var cellMarginHorizontal = 0
    private var cellMarginVertical = 0
    private var tilesToShow = 0

    init {
        isFocusableInTouchMode = true
@@ -68,7 +73,7 @@ class DoubleLineTileLayout(context: Context) : ViewGroup(context), QSPanel.QSTil
    override fun updateResources(): Boolean {
        with(mContext.resources) {
            smallTileSize = getDimensionPixelSize(R.dimen.qs_quick_tile_size)
            cellMarginHorizontal = getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal)
            cellMarginHorizontal = getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal_two_line)
            cellMarginVertical = getDimensionPixelSize(R.dimen.new_qs_vertical_margin)
        }
        requestLayout()
@@ -83,11 +88,12 @@ class DoubleLineTileLayout(context: Context) : ViewGroup(context), QSPanel.QSTil
        }
    }

    override fun getNumVisibleTiles() = mRecords.size
    override fun getNumVisibleTiles() = tilesToShow

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        updateResources()
        postInvalidate()
    }

    override fun onFinishInflate() {
@@ -95,39 +101,58 @@ class DoubleLineTileLayout(context: Context) : ViewGroup(context), QSPanel.QSTil
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        var previousView: View = this
        var tiles = 0

        mRecords.forEach {
            val tileView = it.tileView
            if (tileView.visibility != View.GONE) {
                tileView.updateAccessibilityOrder(previousView)
                previousView = tileView
                tiles++
                tileView.measure(exactly(smallTileSize), exactly(smallTileSize))
            }
            it.tileView.measure(exactly(smallTileSize), exactly(smallTileSize))
        }

        val height = twoLineHeight
        val columns = tiles / 2
        val width = paddingStart + paddingEnd +
                columns * smallTileSize +
                (columns - 1) * cellMarginHorizontal
        setMeasuredDimension(width, height)
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height)
    }

    private fun calculateMaxColumns(availableWidth: Int): Int {
        if (smallTileSize + cellMarginHorizontal == 0) {
            return 0
        } else {
            return (availableWidth - smallTileSize) / (smallTileSize + cellMarginHorizontal) + 1
        }
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        val tiles = mRecords.filter { it.tileView.visibility != View.GONE }
        tiles.forEachIndexed {
            index, tile ->
            val column = index % (tiles.size / 2)
            val left = getLeftForColumn(column)
            val top = if (index < tiles.size / 2) 0 else getTopBottomRow()
            tile.tileView.layout(left, top, left + smallTileSize, top + smallTileSize)
        val availableWidth = r - l - paddingLeft - paddingRight
        val maxColumns = calculateMaxColumns(availableWidth)
        val actualColumns = Math.min(maxColumns, mRecords.size / NUM_LINES)
        if (actualColumns == 0) {
            // No tileSize or horizontal margin
            return
        }
        tilesToShow = actualColumns * NUM_LINES

        val interTileSpace = if (actualColumns <= 2) {
            // Extra "column" of padding to be distributed on each end
            (availableWidth - actualColumns * smallTileSize) / actualColumns
        } else {
            (availableWidth - actualColumns * smallTileSize) / (actualColumns - 1)
        }

        for (index in 0 until mRecords.size) {
            val tileView = mRecords[index].tileView
            if (index >= tilesToShow) {
                tileView.visibility = View.GONE
            } else {
                tileView.visibility = View.VISIBLE
                if (index > 0) tileView.updateAccessibilityOrder(mRecords[index - 1].tileView)
                val column = index % actualColumns
                val left = getLeftForColumn(column, interTileSpace, actualColumns <= 2)
                val top = if (index < actualColumns) 0 else getTopBottomRow()
                tileView.layout(left, top, left + smallTileSize, top + smallTileSize)
            }
        }
    }

    private fun getLeftForColumn(column: Int) = column * (smallTileSize + cellMarginHorizontal)
    private fun getLeftForColumn(column: Int, interSpace: Int, sideMargin: Boolean): Int {
        return (if (sideMargin) interSpace / 2 else 0) + column * (smallTileSize + interSpace)
    }

    private fun getTopBottomRow() = smallTileSize + cellMarginVertical
}
 No newline at end of file