• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.settingslib.spa.widget.button
18 
19 import androidx.compose.foundation.background
20 import androidx.compose.foundation.interaction.MutableInteractionSource
21 import androidx.compose.foundation.layout.Box
22 import androidx.compose.foundation.layout.Column
23 import androidx.compose.foundation.layout.IntrinsicSize
24 import androidx.compose.foundation.layout.PaddingValues
25 import androidx.compose.foundation.layout.Row
26 import androidx.compose.foundation.layout.RowScope
27 import androidx.compose.foundation.layout.fillMaxHeight
28 import androidx.compose.foundation.layout.height
29 import androidx.compose.foundation.layout.padding
30 import androidx.compose.foundation.layout.size
31 import androidx.compose.foundation.layout.width
32 import androidx.compose.material.icons.Icons
33 import androidx.compose.material.icons.outlined.Delete
34 import androidx.compose.material.icons.outlined.Launch
35 import androidx.compose.material.icons.outlined.WarningAmber
36 import androidx.compose.material3.ButtonDefaults
37 import androidx.compose.material3.FilledTonalButton
38 import androidx.compose.material3.Icon
39 import androidx.compose.material3.MaterialTheme
40 import androidx.compose.material3.Text
41 import androidx.compose.runtime.Composable
42 import androidx.compose.runtime.remember
43 import androidx.compose.ui.Alignment
44 import androidx.compose.ui.Modifier
45 import androidx.compose.ui.draw.clip
46 import androidx.compose.ui.graphics.RectangleShape
47 import androidx.compose.ui.graphics.vector.ImageVector
48 import androidx.compose.ui.text.style.TextAlign
49 import androidx.compose.ui.tooling.preview.Preview
50 import androidx.compose.ui.unit.dp
51 import com.android.settingslib.spa.framework.theme.SettingsDimension
52 import com.android.settingslib.spa.framework.theme.SettingsShape
53 import com.android.settingslib.spa.framework.theme.SettingsTheme
54 import com.android.settingslib.spa.framework.theme.divider
55 
56 data class ActionButton(
57     val text: String,
58     val imageVector: ImageVector,
59     val enabled: Boolean = true,
60     val onClick: () -> Unit,
61 )
62 
63 @Composable
ActionButtonsnull64 fun ActionButtons(actionButtons: List<ActionButton>) {
65     Row(
66         Modifier
67             .padding(SettingsDimension.buttonPadding)
68             .clip(SettingsShape.CornerLarge)
69             .height(IntrinsicSize.Min)
70     ) {
71         for ((index, actionButton) in actionButtons.withIndex()) {
72             if (index > 0) ButtonDivider()
73             ActionButton(actionButton)
74         }
75     }
76 }
77 
78 @Composable
ActionButtonnull79 private fun RowScope.ActionButton(actionButton: ActionButton) {
80     FilledTonalButton(
81         onClick = actionButton.onClick,
82         modifier = Modifier
83             .weight(1f)
84             .fillMaxHeight(),
85         enabled = actionButton.enabled,
86         // Because buttons could appear, disappear or change positions, reset the interaction source
87         // to prevent highlight the wrong button.
88         interactionSource = remember(actionButton) { MutableInteractionSource() },
89         shape = RectangleShape,
90         colors = ButtonDefaults.filledTonalButtonColors(
91             containerColor = SettingsTheme.colorScheme.surface,
92             contentColor = SettingsTheme.colorScheme.categoryTitle,
93             disabledContainerColor = SettingsTheme.colorScheme.surface,
94         ),
95         contentPadding = PaddingValues(horizontal = 4.dp, vertical = 20.dp),
96     ) {
97         Column(horizontalAlignment = Alignment.CenterHorizontally) {
98             Icon(
99                 imageVector = actionButton.imageVector,
100                 contentDescription = null,
101                 modifier = Modifier.size(SettingsDimension.itemIconSize),
102             )
103             Box(
104                 modifier = Modifier.padding(top = 4.dp).fillMaxHeight(),
105                 contentAlignment = Alignment.Center,
106             ) {
107                 Text(
108                     text = actionButton.text,
109                     textAlign = TextAlign.Center,
110                     style = MaterialTheme.typography.labelMedium,
111                 )
112             }
113         }
114     }
115 }
116 
117 @Composable
ButtonDividernull118 private fun ButtonDivider() {
119     Box(
120         Modifier
121             .width(1.dp)
122             .background(color = MaterialTheme.colorScheme.divider)
123     )
124 }
125 
126 @Preview
127 @Composable
ActionButtonsPreviewnull128 private fun ActionButtonsPreview() {
129     SettingsTheme {
130         ActionButtons(
131             listOf(
132                 ActionButton(text = "Open", imageVector = Icons.Outlined.Launch) {},
133                 ActionButton(text = "Uninstall", imageVector = Icons.Outlined.Delete) {},
134                 ActionButton(text = "Force stop", imageVector = Icons.Outlined.WarningAmber) {},
135             )
136         )
137     }
138 }
139