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