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