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

Commit 2bcc05e5 authored by Lucas Silva's avatar Lucas Silva Committed by Android (Google) Code Review
Browse files

Merge "Fix responsive grid in edit mode and content padding." into main

parents c1ca8871 7bbc29a7
Loading
Loading
Loading
Loading
+39 −33
Original line number Original line Diff line number Diff line
@@ -218,6 +218,7 @@ fun CommunalHub(
    var removeButtonCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
    var removeButtonCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
    var toolbarSize: IntSize? by remember { mutableStateOf(null) }
    var toolbarSize: IntSize? by remember { mutableStateOf(null) }
    var gridCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
    var gridCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
    var contentOffset: Offset by remember { mutableStateOf(Offset.Zero) }


    val gridState =
    val gridState =
        rememberLazyGridState(viewModel.savedFirstScrollIndex, viewModel.savedFirstScrollOffset)
        rememberLazyGridState(viewModel.savedFirstScrollIndex, viewModel.savedFirstScrollOffset)
@@ -240,9 +241,7 @@ fun CommunalHub(
            initialValue = !viewModel.isEditMode
            initialValue = !viewModel.isEditMode
        )
        )


    val contentPadding = gridContentPadding(viewModel.isEditMode, toolbarSize)
    val minContentPadding = gridContentPadding(viewModel.isEditMode, toolbarSize)
    val contentOffset = beforeContentPadding(contentPadding).toOffset()

    ObserveScrollEffect(gridState, viewModel)
    ObserveScrollEffect(gridState, viewModel)


    val context = LocalContext.current
    val context = LocalContext.current
@@ -368,7 +367,7 @@ fun CommunalHub(
    ) {
    ) {
        AccessibilityContainer(viewModel) {
        AccessibilityContainer(viewModel) {
            if (!viewModel.isEditMode && isEmptyState) {
            if (!viewModel.isEditMode && isEmptyState) {
                EmptyStateCta(contentPadding = contentPadding, viewModel = viewModel)
                EmptyStateCta(contentPadding = minContentPadding, viewModel = viewModel)
            } else {
            } else {
                val slideOffsetInPx =
                val slideOffsetInPx =
                    with(LocalDensity.current) { Dimensions.SlideOffsetY.toPx().toInt() }
                    with(LocalDensity.current) { Dimensions.SlideOffsetY.toPx().toInt() }
@@ -397,10 +396,11 @@ fun CommunalHub(
                        CommunalHubLazyGrid(
                        CommunalHubLazyGrid(
                            communalContent = communalContent,
                            communalContent = communalContent,
                            viewModel = viewModel,
                            viewModel = viewModel,
                            contentPadding = contentPadding,
                            minContentPadding = minContentPadding,
                            contentOffset = contentOffset,
                            contentOffset = contentOffset,
                            screenWidth = screenWidth,
                            screenWidth = screenWidth,
                            setGridCoordinates = { gridCoordinates = it },
                            setGridCoordinates = { gridCoordinates = it },
                            setContentOffset = { contentOffset = it },
                            updateDragPositionForRemove = { boundingBox ->
                            updateDragPositionForRemove = { boundingBox ->
                                val gridOffset = gridCoordinates?.positionInWindow()
                                val gridOffset = gridCoordinates?.positionInWindow()
                                val removeButtonCenter =
                                val removeButtonCenter =
@@ -742,8 +742,9 @@ fun calculateWidgetSize(


@Composable
@Composable
private fun HorizontalGridWrapper(
private fun HorizontalGridWrapper(
    contentPadding: PaddingValues,
    minContentPadding: PaddingValues,
    gridState: LazyGridState,
    gridState: LazyGridState,
    setContentOffset: (offset: Offset) -> Unit,
    modifier: Modifier = Modifier,
    modifier: Modifier = Modifier,
    content: LazyGridScope.(sizeInfo: SizeInfo?) -> Unit,
    content: LazyGridScope.(sizeInfo: SizeInfo?) -> Unit,
) {
) {
@@ -752,17 +753,26 @@ private fun HorizontalGridWrapper(
            cellAspectRatio = 1.5f,
            cellAspectRatio = 1.5f,
            modifier = modifier,
            modifier = modifier,
            state = gridState,
            state = gridState,
            minContentPadding = contentPadding,
            minContentPadding = minContentPadding,
            minHorizontalArrangement = Dimensions.ItemSpacing,
            minHorizontalArrangement = Dimensions.ItemSpacing,
            minVerticalArrangement = Dimensions.ItemSpacing,
            minVerticalArrangement = Dimensions.ItemSpacing,
            setContentOffset = setContentOffset,
            content = content,
            content = content,
        )
        )
    } else {
    } else {
        val layoutDirection = LocalLayoutDirection.current
        val density = LocalDensity.current

        val minStartPadding = minContentPadding.calculateStartPadding(layoutDirection)
        val minTopPadding = minContentPadding.calculateTopPadding()

        with(density) { setContentOffset(Offset(minStartPadding.toPx(), minTopPadding.toPx())) }

        LazyHorizontalGrid(
        LazyHorizontalGrid(
            modifier = modifier,
            modifier = modifier,
            state = gridState,
            state = gridState,
            rows = GridCells.Fixed(CommunalContentSize.FixedSize.FULL.span),
            rows = GridCells.Fixed(CommunalContentSize.FixedSize.FULL.span),
            contentPadding = contentPadding,
            contentPadding = minContentPadding,
            horizontalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing),
            horizontalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing),
            verticalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing),
            verticalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing),
        ) {
        ) {
@@ -776,13 +786,14 @@ private fun HorizontalGridWrapper(
private fun BoxScope.CommunalHubLazyGrid(
private fun BoxScope.CommunalHubLazyGrid(
    communalContent: List<CommunalContentModel>,
    communalContent: List<CommunalContentModel>,
    viewModel: BaseCommunalViewModel,
    viewModel: BaseCommunalViewModel,
    contentPadding: PaddingValues,
    minContentPadding: PaddingValues,
    selectedKey: State<String?>,
    selectedKey: State<String?>,
    screenWidth: Int,
    screenWidth: Int,
    contentOffset: Offset,
    contentOffset: Offset,
    gridState: LazyGridState,
    gridState: LazyGridState,
    contentListState: ContentListState,
    contentListState: ContentListState,
    setGridCoordinates: (coordinates: LayoutCoordinates) -> Unit,
    setGridCoordinates: (coordinates: LayoutCoordinates) -> Unit,
    setContentOffset: (offset: Offset) -> Unit,
    updateDragPositionForRemove: (boundingBox: IntRect) -> Boolean,
    updateDragPositionForRemove: (boundingBox: IntRect) -> Boolean,
    widgetConfigurator: WidgetConfigurator?,
    widgetConfigurator: WidgetConfigurator?,
    interactionHandler: RemoteViews.InteractionHandler?,
    interactionHandler: RemoteViews.InteractionHandler?,
@@ -833,7 +844,8 @@ private fun BoxScope.CommunalHubLazyGrid(
    HorizontalGridWrapper(
    HorizontalGridWrapper(
        modifier = gridModifier,
        modifier = gridModifier,
        gridState = gridState,
        gridState = gridState,
        contentPadding = contentPadding,
        minContentPadding = minContentPadding,
        setContentOffset = setContentOffset,
    ) { sizeInfo ->
    ) { sizeInfo ->
        /** Override spans based on the responsive grid size */
        /** Override spans based on the responsive grid size */
        val finalizedList =
        val finalizedList =
@@ -892,7 +904,7 @@ private fun BoxScope.CommunalHubLazyGrid(
                    key = item.key,
                    key = item.key,
                    currentSpan = GridItemSpan(currentItemSpan),
                    currentSpan = GridItemSpan(currentItemSpan),
                    gridState = gridState,
                    gridState = gridState,
                    gridContentPadding = contentPadding,
                    gridContentPadding = sizeInfo?.contentPadding ?: minContentPadding,
                    verticalArrangement =
                    verticalArrangement =
                        Arrangement.spacedBy(
                        Arrangement.spacedBy(
                            sizeInfo?.verticalArrangement ?: Dimensions.ItemSpacing
                            sizeInfo?.verticalArrangement ?: Dimensions.ItemSpacing
@@ -1733,26 +1745,24 @@ private fun gridContentPadding(isEditMode: Boolean, toolbarSize: IntSize?): Padd
    val windowMetrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
    val windowMetrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
    val screenHeight = with(density) { windowMetrics.bounds.height().toDp() }
    val screenHeight = with(density) { windowMetrics.bounds.height().toDp() }
    val toolbarHeight = with(density) { Dimensions.ToolbarPaddingTop + toolbarSize.height.toDp() }
    val toolbarHeight = with(density) { Dimensions.ToolbarPaddingTop + toolbarSize.height.toDp() }
    return if (communalResponsiveGrid()) {
        PaddingValues(
            start = Dimensions.ToolbarPaddingHorizontal,
            end = Dimensions.ToolbarPaddingHorizontal,
            top = hubDimensions.GridTopSpacing,
        )
    } else {
        val verticalPadding =
        val verticalPadding =
        ((screenHeight - toolbarHeight - hubDimensions.GridHeight + hubDimensions.GridTopSpacing) /
            ((screenHeight - toolbarHeight - hubDimensions.GridHeight +
                2)
                    hubDimensions.GridTopSpacing) / 2)
                .coerceAtLeast(Dimensions.Spacing)
                .coerceAtLeast(Dimensions.Spacing)
    return PaddingValues(
        PaddingValues(
            start = Dimensions.ToolbarPaddingHorizontal,
            start = Dimensions.ToolbarPaddingHorizontal,
            end = Dimensions.ToolbarPaddingHorizontal,
            end = Dimensions.ToolbarPaddingHorizontal,
            top = verticalPadding + toolbarHeight,
            top = verticalPadding + toolbarHeight,
            bottom = verticalPadding,
            bottom = verticalPadding,
        )
        )
    }
    }

@Composable
private fun beforeContentPadding(paddingValues: PaddingValues): ContentPaddingInPx {
    return with(LocalDensity.current) {
        ContentPaddingInPx(
            start = paddingValues.calculateStartPadding(LocalLayoutDirection.current).toPx(),
            top = paddingValues.calculateTopPadding().toPx(),
        )
    }
}
}


private fun CommunalContentSize.FixedSize.dp(): Dp {
private fun CommunalContentSize.FixedSize.dp(): Dp {
@@ -1770,10 +1780,6 @@ private fun firstIndexAtOffset(gridState: LazyGridState, offset: Offset): Int? =
private fun keyAtIndexIfEditable(list: List<CommunalContentModel>, index: Int): String? =
private fun keyAtIndexIfEditable(list: List<CommunalContentModel>, index: Int): String? =
    if (index in list.indices && list[index].isWidgetContent()) list[index].key else null
    if (index in list.indices && list[index].isWidgetContent()) list[index].key else null


data class ContentPaddingInPx(val start: Float, val top: Float) {
    fun toOffset(): Offset = Offset(start, top)
}

class Dimensions(val context: Context, val config: Configuration) {
class Dimensions(val context: Context, val config: Configuration) {
    val GridTopSpacing: Dp
    val GridTopSpacing: Dp
        get() {
        get() {
+13 −3
Original line number Original line Diff line number Diff line
@@ -35,7 +35,9 @@ import androidx.compose.foundation.rememberOverscrollEffect
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.DpSize
@@ -54,6 +56,7 @@ fun ResponsiveLazyHorizontalGrid(
    cellAspectRatio: Float,
    cellAspectRatio: Float,
    modifier: Modifier = Modifier,
    modifier: Modifier = Modifier,
    state: LazyGridState = rememberLazyGridState(),
    state: LazyGridState = rememberLazyGridState(),
    setContentOffset: (offset: Offset) -> Unit = {},
    minContentPadding: PaddingValues = PaddingValues(0.dp),
    minContentPadding: PaddingValues = PaddingValues(0.dp),
    minHorizontalArrangement: Dp = 0.dp,
    minHorizontalArrangement: Dp = 0.dp,
    minVerticalArrangement: Dp = 0.dp,
    minVerticalArrangement: Dp = 0.dp,
@@ -70,6 +73,7 @@ fun ResponsiveLazyHorizontalGrid(
    BoxWithConstraints(modifier) {
    BoxWithConstraints(modifier) {
        val gridSize = rememberGridSize(maxWidth = maxWidth, maxHeight = maxHeight)
        val gridSize = rememberGridSize(maxWidth = maxWidth, maxHeight = maxHeight)
        val layoutDirection = LocalLayoutDirection.current
        val layoutDirection = LocalLayoutDirection.current
        val density = LocalDensity.current


        val minStartPadding = minContentPadding.calculateStartPadding(layoutDirection)
        val minStartPadding = minContentPadding.calculateStartPadding(layoutDirection)
        val minEndPadding = minContentPadding.calculateEndPadding(layoutDirection)
        val minEndPadding = minContentPadding.calculateEndPadding(layoutDirection)
@@ -124,14 +128,19 @@ fun ResponsiveLazyHorizontalGrid(
        val extraWidth = maxWidth - usedWidth
        val extraWidth = maxWidth - usedWidth
        val extraHeight = maxHeight - usedHeight
        val extraHeight = maxHeight - usedHeight


        val finalStartPadding = minStartPadding + extraWidth / 2
        val finalTopPadding = minTopPadding + extraHeight / 2

        val finalContentPadding =
        val finalContentPadding =
            PaddingValues(
            PaddingValues(
                start = minStartPadding + extraWidth / 2,
                start = finalStartPadding,
                end = minEndPadding + extraWidth / 2,
                end = minEndPadding + extraWidth / 2,
                top = minTopPadding + extraHeight / 2,
                top = finalTopPadding,
                bottom = minBottomPadding + extraHeight / 2,
                bottom = minBottomPadding + extraHeight / 2,
            )
            )


        with(density) { setContentOffset(Offset(finalStartPadding.toPx(), finalTopPadding.toPx())) }

        LazyHorizontalGrid(
        LazyHorizontalGrid(
            rows = GridCells.Fixed(gridSize.height),
            rows = GridCells.Fixed(gridSize.height),
            modifier = Modifier.fillMaxSize(),
            modifier = Modifier.fillMaxSize(),
@@ -179,12 +188,13 @@ private fun calculateClosestSize(maxWidth: Dp, maxHeight: Dp, aspectRatio: Float
 * @property verticalArrangement The space between rows in the grid.
 * @property verticalArrangement The space between rows in the grid.
 * @property gridSize The size of the grid, in cell units.
 * @property gridSize The size of the grid, in cell units.
 * @property availableHeight The maximum height an item in the grid may occupy.
 * @property availableHeight The maximum height an item in the grid may occupy.
 * @property contentPadding The padding around the content of the grid.
 */
 */
data class SizeInfo(
data class SizeInfo(
    val cellSize: DpSize,
    val cellSize: DpSize,
    val verticalArrangement: Dp,
    val verticalArrangement: Dp,
    val gridSize: IntSize,
    val gridSize: IntSize,
    private val contentPadding: PaddingValues,
    val contentPadding: PaddingValues,
    private val maxHeight: Dp,
    private val maxHeight: Dp,
) {
) {
    val availableHeight: Dp
    val availableHeight: Dp