• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2025 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 @file:OptIn(ExperimentalAnimatableApi::class)
18 
19 package com.android.mechanics.demo.presentation
20 
21 import androidx.compose.animation.core.ExperimentalAnimatableApi
22 import androidx.compose.foundation.background
23 import androidx.compose.foundation.layout.Arrangement
24 import androidx.compose.foundation.layout.Column
25 import androidx.compose.foundation.layout.ColumnScope
26 import androidx.compose.foundation.layout.Row
27 import androidx.compose.foundation.layout.Spacer
28 import androidx.compose.foundation.layout.fillMaxWidth
29 import androidx.compose.foundation.layout.height
30 import androidx.compose.foundation.layout.padding
31 import androidx.compose.foundation.rememberScrollState
32 import androidx.compose.foundation.verticalScroll
33 import androidx.compose.material.icons.Icons
34 import androidx.compose.material.icons.filled.AllInclusive
35 import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
36 import androidx.compose.material3.Icon
37 import androidx.compose.material3.LocalContentColor
38 import androidx.compose.material3.MaterialTheme
39 import androidx.compose.material3.MaterialTheme.typography
40 import androidx.compose.material3.Text
41 import androidx.compose.runtime.Composable
42 import androidx.compose.runtime.CompositionLocalProvider
43 import androidx.compose.runtime.getValue
44 import androidx.compose.runtime.mutableStateOf
45 import androidx.compose.runtime.remember
46 import androidx.compose.runtime.setValue
47 import androidx.compose.ui.Modifier
48 import androidx.compose.ui.unit.Dp
49 import androidx.compose.ui.unit.dp
50 import com.android.compose.animation.scene.ElementKey
51 import com.android.compose.modifiers.thenIf
52 import com.android.mechanics.demo.staging.behavior.reveal.fadeReveal
53 import com.android.mechanics.demo.staging.behavior.reveal.revealContainer
54 import com.android.mechanics.demo.tuneable.Demo
55 import com.android.mechanics.demo.tuneable.LabelledCheckbox
56 import com.android.mechanics.demo.util.ExpandableCard
57 
58 object PredefinedMotionDemo : Demo<PredefinedMotionDemo.Config> {
59     object Elements {
60         val ExpandableContent = ElementKey("ExpandableContent")
61     }
62 
63     data class Config(val showItemBackground: Boolean)
64 
65     @Composable
66     override fun DemoUi(config: Config, modifier: Modifier) {
67         val colors = MaterialTheme.colorScheme
68         ExpandableCard(
69             modifier = modifier.fillMaxWidth(),
70             header = { Text(text = "Contents", style = typography.titleMedium) },
71         ) { isExpanded ->
72             Column(
73                 verticalArrangement = Arrangement.spacedBy(8.dp),
74                 modifier =
75                     Modifier.fillMaxWidth()
76                         .element(Elements.ExpandableContent)
77                         .revealContainer(this@ExpandableCard)
78                         .verticalScroll(rememberScrollState())
79                         .padding(start = 16.dp, end = 16.dp, bottom = 16.dp),
80             ) {
81                 if (isExpanded) {
82                     Spacer(modifier = Modifier.height(24.dp))
83                     repeat(10) {
84                         Row(
85                             horizontalArrangement = Arrangement.spacedBy(8.dp),
86                             modifier =
87                                 Modifier.noResizeDuringTransitions()
88                                     .fadeReveal(debug = true)
89                                     .fillMaxWidth()
90                                     .thenIf(config.showItemBackground) {
91                                         Modifier.background(colors.primary)
92                                     },
93                         ) {
94                             CompositionLocalProvider(
95                                 LocalContentColor provides
96                                     if (config.showItemBackground) colors.onPrimary
97                                     else colors.onSurface
98                             ) {
99                                 Icon(Icons.Default.AllInclusive, null)
100                                 Text(text = "Item ${it + 1}", modifier = Modifier.height(20.dp))
101                             }
102                         }
103                     }
104                 }
105             }
106         }
107     }
108 
109     @OptIn(ExperimentalMaterial3ExpressiveApi::class)
110     @Composable
111     override fun rememberDefaultConfig(): Config {
112         return remember { Config(showItemBackground = false) }
113     }
114 
115     override var visualizationInputRange by mutableStateOf(0f..1000f)
116     override val collapsedGraphHeight: Dp = 20.dp
117 
118     @Composable
119     override fun ColumnScope.ConfigUi(config: Config, onConfigChanged: (Config) -> Unit) {
120         LabelledCheckbox(
121             "Show item background",
122             config.showItemBackground,
123             onCheckedChange = { onConfigChanged(config.copy(showItemBackground = it)) },
124             modifier = Modifier.fillMaxWidth(),
125         )
126     }
127 
128     override val identifier: String = "predefined_motion"
129 }
130