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

Commit 0eb9d3f7 authored by Darrell Shi's avatar Darrell Shi Committed by Android (Google) Code Review
Browse files

Merge "Move CommunalLayoutLib to AOSP" into main

parents 3c2b78b9 acfbe67e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ systemui_compose_java_defaults {
            // except for SystemUI-core.
            // Copied from compose/features/Android.bp.
            static_libs: [
                "CommunalLayoutLib",
                "PlatformComposeCore",

                "androidx.compose.runtime_runtime",
+35 −0
Original line number Diff line number Diff line
// Copyright (C) 2023 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package {
    default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"],
}

android_library {
    name: "CommunalLayoutLib",
    srcs: [
        "src/**/*.kt",
    ],
    static_libs: [
        "androidx.arch.core_core-runtime",
        "androidx.compose.animation_animation-graphics",
        "androidx.compose.runtime_runtime",
        "androidx.compose.material3_material3",
        "jsr330",
        "kotlinx-coroutines-android",
        "kotlinx-coroutines-core",
    ],
    manifest: "AndroidManifest.xml",
    kotlincflags: ["-Xjvm-default=all"],
}
+18 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>

<!-- Copyright (C) 2023 The Android Open Source Project

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
-->

<manifest package="com.android.systemui.communal.layout" />
+66 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.communal.layout

import com.android.systemui.communal.layout.ui.compose.config.CommunalGridLayoutCard

/** Computes the arrangement of cards. */
class CommunalLayoutEngine {
    companion object {
        /**
         * Determines the size that each card should be rendered in, and distributes the cards into
         * columns.
         *
         * Returns a nested list where the outer list contains columns, and the inner list contains
         * cards in each column.
         *
         * Currently treats the first supported size as the size to be rendered in, ignoring other
         * supported sizes.
         */
        fun distributeCardsIntoColumns(
            cards: List<CommunalGridLayoutCard>,
        ): List<List<CommunalGridLayoutCardInfo>> {
            val result = ArrayList<ArrayList<CommunalGridLayoutCardInfo>>()

            var capacityOfLastColumn = 0
            for (card in cards) {
                val cardSize = card.supportedSizes.first()
                if (capacityOfLastColumn >= cardSize.value) {
                    // Card fits in last column
                    capacityOfLastColumn -= cardSize.value
                } else {
                    // Create a new column
                    result.add(arrayListOf())
                    capacityOfLastColumn = CommunalGridLayoutCard.Size.FULL.value - cardSize.value
                }

                result.last().add(CommunalGridLayoutCardInfo(card, cardSize))
            }

            return result
        }
    }

    /**
     * A data class that wraps around a [CommunalGridLayoutCard] and also contains the size that the
     * card should be rendered in.
     */
    data class CommunalGridLayoutCardInfo(
        val card: CommunalGridLayoutCard,
        val size: CommunalGridLayoutCard.Size,
    )
}
+64 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.communal.layout.ui.compose

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.android.systemui.communal.layout.CommunalLayoutEngine
import com.android.systemui.communal.layout.ui.compose.config.CommunalGridLayoutCard
import com.android.systemui.communal.layout.ui.compose.config.CommunalGridLayoutConfig

/**
 * An arrangement of cards with a horizontal scroll, where each card is displayed in the right size
 * and follows a specific order based on its priority, ensuring a seamless layout without any gaps.
 */
@Composable
fun CommunalGridLayout(
    modifier: Modifier,
    layoutConfig: CommunalGridLayoutConfig,
    communalCards: List<CommunalGridLayoutCard>,
) {
    val columns = CommunalLayoutEngine.distributeCardsIntoColumns(communalCards)
    LazyRow(
        modifier = modifier.height(layoutConfig.gridHeight),
        horizontalArrangement = Arrangement.spacedBy(layoutConfig.gridGutter),
    ) {
        for (column in columns) {
            item {
                Column(
                    modifier = Modifier.width(layoutConfig.cardWidth),
                    verticalArrangement = Arrangement.spacedBy(layoutConfig.gridGutter),
                ) {
                    for (cardInfo in column) {
                        Row(
                            modifier = Modifier.height(layoutConfig.cardHeight(cardInfo.size)),
                        ) {
                            cardInfo.card.Content(Modifier.fillMaxSize())
                        }
                    }
                }
            }
        }
    }
}
Loading