1 /* <lambda>null2 * Copyright (C) 2024 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.qs.panels.ui.compose 18 19 import androidx.compose.foundation.layout.height 20 import androidx.compose.foundation.lazy.grid.GridCells 21 import androidx.compose.foundation.lazy.grid.GridItemSpan 22 import androidx.compose.runtime.Composable 23 import androidx.compose.runtime.DisposableEffect 24 import androidx.compose.runtime.getValue 25 import androidx.compose.ui.Modifier 26 import androidx.compose.ui.res.dimensionResource 27 import androidx.lifecycle.compose.collectAsStateWithLifecycle 28 import com.android.systemui.dagger.SysUISingleton 29 import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel 30 import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel 31 import com.android.systemui.qs.panels.ui.viewmodel.InfiniteGridSizeViewModel 32 import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel 33 import com.android.systemui.qs.pipeline.shared.TileSpec 34 import com.android.systemui.res.R 35 import javax.inject.Inject 36 37 @SysUISingleton 38 class InfiniteGridLayout 39 @Inject 40 constructor( 41 private val iconTilesViewModel: IconTilesViewModel, 42 private val gridSizeViewModel: InfiniteGridSizeViewModel, 43 ) : GridLayout { 44 45 @Composable 46 override fun TileGrid( 47 tiles: List<TileViewModel>, 48 modifier: Modifier, 49 ) { 50 DisposableEffect(tiles) { 51 val token = Any() 52 tiles.forEach { it.startListening(token) } 53 onDispose { tiles.forEach { it.stopListening(token) } } 54 } 55 val columns by gridSizeViewModel.columns.collectAsStateWithLifecycle() 56 57 TileLazyGrid(modifier = modifier, columns = GridCells.Fixed(columns)) { 58 items( 59 tiles.size, 60 span = { index -> 61 if (iconTilesViewModel.isIconTile(tiles[index].spec)) { 62 GridItemSpan(1) 63 } else { 64 GridItemSpan(2) 65 } 66 } 67 ) { index -> 68 Tile( 69 tile = tiles[index], 70 iconOnly = iconTilesViewModel.isIconTile(tiles[index].spec), 71 modifier = Modifier.height(dimensionResource(id = R.dimen.qs_tile_height)) 72 ) 73 } 74 } 75 } 76 77 @Composable 78 override fun EditTileGrid( 79 tiles: List<EditTileViewModel>, 80 modifier: Modifier, 81 onAddTile: (TileSpec, Int) -> Unit, 82 onRemoveTile: (TileSpec) -> Unit, 83 ) { 84 val columns by gridSizeViewModel.columns.collectAsStateWithLifecycle() 85 86 DefaultEditTileGrid( 87 tiles = tiles, 88 isIconOnly = iconTilesViewModel::isIconTile, 89 columns = GridCells.Fixed(columns), 90 modifier = modifier, 91 onAddTile = onAddTile, 92 onRemoveTile = onRemoveTile, 93 ) 94 } 95 } 96