[expressive design] Update AlertDialog layout.
Test: visual
Bug: 360916599
Flag: EXEMPT bug fix
Change-Id: I950c4164cb8f62aa598163d57e8ddc4710f2472b
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialog.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialog.kt
index 022dded..265864e 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialog.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialog.kt
@@ -17,11 +17,16 @@
package com.android.settingslib.spa.widget.dialog
import android.content.res.Configuration
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
+import androidx.compose.material3.Button
+import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
@@ -32,9 +37,11 @@
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
+import com.android.settingslib.spa.framework.theme.isSpaExpressiveEnabled
data class AlertDialogButton(
val text: String,
@@ -85,27 +92,41 @@
AlertDialog(
onDismissRequest = ::close,
modifier = Modifier.width(getDialogWidth()),
- confirmButton = { confirmButton?.let { Button(it) } },
- dismissButton = dismissButton?.let { { Button(it) } },
- title = title?.let { { Text(it) } },
- text = text?.let {
- {
- Column(Modifier.verticalScroll(rememberScrollState())) {
- text()
- }
- }
+ confirmButton = {
+ confirmButton?.let { if (isSpaExpressiveEnabled) ConfirmButton(it) else Button(it) }
},
+ dismissButton =
+ dismissButton?.let {
+ { if (isSpaExpressiveEnabled) DismissButton(it) else Button(it) }
+ },
+ title = title?.let { { CenterRow { Text(it) } } },
+ text =
+ text?.let {
+ { CenterRow { Column(Modifier.verticalScroll(rememberScrollState())) { text() } } }
+ },
properties = DialogProperties(usePlatformDefaultWidth = false),
)
}
@Composable
+internal fun CenterRow(content: @Composable (() -> Unit)) {
+ if (isSpaExpressiveEnabled) {
+ Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
+ content()
+ }
+ } else {
+ content()
+ }
+}
+
+@Composable
fun getDialogWidth(): Dp {
val configuration = LocalConfiguration.current
- return configuration.screenWidthDp.dp * when (configuration.orientation) {
- Configuration.ORIENTATION_LANDSCAPE -> 0.65f
- else -> 0.85f
- }
+ return configuration.screenWidthDp.dp *
+ when (configuration.orientation) {
+ Configuration.ORIENTATION_LANDSCAPE -> 0.65f
+ else -> 0.85f
+ }
}
@Composable
@@ -120,3 +141,47 @@
Text(button.text)
}
}
+
+@Composable
+private fun AlertDialogPresenter.DismissButton(button: AlertDialogButton) {
+ OutlinedButton(
+ onClick = {
+ close()
+ button.onClick()
+ },
+ enabled = button.enabled,
+ ) {
+ Text(button.text)
+ }
+}
+
+@Composable
+private fun AlertDialogPresenter.ConfirmButton(button: AlertDialogButton) {
+ Button(
+ onClick = {
+ close()
+ button.onClick()
+ },
+ enabled = button.enabled,
+ ) {
+ Text(button.text)
+ }
+}
+
+@Preview
+@Composable
+private fun AlertDialogPreview() {
+ val alertDialogPresenter = remember {
+ object : AlertDialogPresenter {
+ override fun open() {}
+
+ override fun close() {}
+ }
+ }
+ alertDialogPresenter.SettingsAlertDialog(
+ confirmButton = AlertDialogButton("Ok"),
+ dismissButton = AlertDialogButton("Cancel"),
+ title = "Title",
+ text = { Text("Text") },
+ )
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialogWithIcon.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialogWithIcon.kt
index 030522d..58a83fa 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialogWithIcon.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlertDialogWithIcon.kt
@@ -40,10 +40,7 @@
dismissButton: AlertDialogButton?,
title: String?,
icon: @Composable (() -> Unit)? = {
- Icon(
- Icons.Default.WarningAmber,
- contentDescription = null
- )
+ Icon(Icons.Default.WarningAmber, contentDescription = null)
},
text: @Composable (() -> Unit)?,
) {
@@ -52,43 +49,22 @@
icon = icon,
modifier = Modifier.width(getDialogWidth()),
confirmButton = {
- confirmButton?.let {
- Button(
- onClick = {
- it.onClick()
- },
- ) {
- Text(it.text)
+ confirmButton?.let { Button(onClick = { it.onClick() }) { Text(it.text) } }
+ },
+ dismissButton =
+ dismissButton?.let { { OutlinedButton(onClick = { it.onClick() }) { Text(it.text) } } },
+ title =
+ title?.let {
+ {
+ CenterRow {
+ Text(it, modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center)
+ }
}
- }
- },
- dismissButton = dismissButton?.let {
- {
- OutlinedButton(
- onClick = {
- it.onClick()
- },
- ) {
- Text(it.text)
- }
- }
- },
- title = title?.let {
- {
- Text(
- it,
- modifier = Modifier.fillMaxWidth(),
- textAlign = TextAlign.Center
- )
- }
- },
- text = text?.let {
- {
- Column(Modifier.verticalScroll(rememberScrollState())) {
- text()
- }
- }
- },
+ },
+ text =
+ text?.let {
+ { CenterRow { Column(Modifier.verticalScroll(rememberScrollState())) { text() } } }
+ },
properties = DialogProperties(usePlatformDefaultWidth = false),
)
-}
\ No newline at end of file
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlterDialogContent.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlterDialogContent.kt
index bef0bca..9f2210d 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlterDialogContent.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlterDialogContent.kt
@@ -58,10 +58,7 @@
dismissButton: AlertDialogButton?,
title: String?,
icon: @Composable (() -> Unit)? = {
- Icon(
- Icons.Default.WarningAmber,
- contentDescription = null
- )
+ Icon(Icons.Default.WarningAmber, contentDescription = null)
},
text: @Composable (() -> Unit)?,
) {
@@ -69,42 +66,22 @@
buttons = {
AlertDialogFlowRow(
mainAxisSpacing = ButtonsMainAxisSpacing,
- crossAxisSpacing = ButtonsCrossAxisSpacing
+ crossAxisSpacing = ButtonsCrossAxisSpacing,
) {
- dismissButton?.let {
- OutlinedButton(onClick = it.onClick) {
- Text(it.text)
- }
- }
- confirmButton?.let {
- Button(
- onClick = {
- it.onClick()
- },
- ) {
- Text(it.text)
- }
- }
+ dismissButton?.let { OutlinedButton(onClick = it.onClick) { Text(it.text) } }
+ confirmButton?.let { Button(onClick = { it.onClick() }) { Text(it.text) } }
}
},
icon = icon,
modifier = Modifier.width(getDialogWidth()),
- title = title?.let {
- {
- Text(
- it,
- modifier = Modifier.fillMaxWidth(),
- textAlign = TextAlign.Center
- )
- }
- },
- text = text?.let {
- {
- Column(Modifier.verticalScroll(rememberScrollState())) {
- text()
- }
- }
- },
+ title =
+ title?.let {
+ { Text(it, modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center) }
+ },
+ text =
+ text?.let {
+ { CenterRow { Column(Modifier.verticalScroll(rememberScrollState())) { text() } } }
+ },
)
}
@@ -121,18 +98,12 @@
shape = SettingsShape.CornerExtraLarge,
color = MaterialTheme.colorScheme.surfaceContainerHigh,
) {
- Column(
- modifier = Modifier.padding(DialogPadding)
- ) {
+ Column(modifier = Modifier.padding(DialogPadding)) {
icon?.let {
CompositionLocalProvider(
- LocalContentColor provides AlertDialogDefaults.iconContentColor,
+ LocalContentColor provides AlertDialogDefaults.iconContentColor
) {
- Box(
- Modifier
- .padding(IconPadding)
- .align(Alignment.CenterHorizontally)
- ) {
+ Box(Modifier.padding(IconPadding).align(Alignment.CenterHorizontally)) {
icon()
}
}
@@ -144,8 +115,7 @@
) {
Box(
// Align the title to the center when an icon is present.
- Modifier
- .padding(TitlePadding)
+ Modifier.padding(TitlePadding)
.align(
if (icon == null) {
Alignment.Start
@@ -161,11 +131,10 @@
text?.let {
ProvideContentColorTextStyle(
contentColor = AlertDialogDefaults.textContentColor,
- textStyle = MaterialTheme.typography.bodyMedium
+ textStyle = MaterialTheme.typography.bodyMedium,
) {
Box(
- Modifier
- .weight(weight = 1f, fill = false)
+ Modifier.weight(weight = 1f, fill = false)
.padding(TextPadding)
.align(Alignment.Start)
) {
@@ -177,7 +146,7 @@
ProvideContentColorTextStyle(
contentColor = MaterialTheme.colorScheme.primary,
textStyle = MaterialTheme.typography.labelLarge,
- content = buttons
+ content = buttons,
)
}
}
@@ -188,7 +157,7 @@
internal fun AlertDialogFlowRow(
mainAxisSpacing: Dp,
crossAxisSpacing: Dp,
- content: @Composable () -> Unit
+ content: @Composable () -> Unit,
) {
Layout(content) { measurables, constraints ->
val sequences = mutableListOf<List<Placeable>>()
@@ -204,8 +173,9 @@
// Return whether the placeable can be added to the current sequence.
fun canAddToCurrentSequence(placeable: Placeable) =
- currentSequence.isEmpty() || currentMainAxisSize + mainAxisSpacing.roundToPx() +
- placeable.width <= constraints.maxWidth
+ currentSequence.isEmpty() ||
+ currentMainAxisSize + mainAxisSpacing.roundToPx() + placeable.width <=
+ constraints.maxWidth
// Store current sequence information and start a new sequence.
fun startNewSequence() {
@@ -213,8 +183,7 @@
crossAxisSpace += crossAxisSpacing.roundToPx()
}
// Ensures that confirming actions appear above dismissive actions.
- @Suppress("ListIterator")
- sequences.add(0, currentSequence.toList())
+ @Suppress("ListIterator") sequences.add(0, currentSequence.toList())
crossAxisSizes += currentCrossAxisSize
crossAxisPositions += crossAxisSpace
@@ -254,23 +223,23 @@
layout(layoutWidth, layoutHeight) {
sequences.fastForEachIndexed { i, placeables ->
- val childrenMainAxisSizes = IntArray(placeables.size) { j ->
- placeables[j].width +
- if (j < placeables.lastIndex) mainAxisSpacing.roundToPx() else 0
- }
+ val childrenMainAxisSizes =
+ IntArray(placeables.size) { j ->
+ placeables[j].width +
+ if (j < placeables.lastIndex) mainAxisSpacing.roundToPx() else 0
+ }
val arrangement = Arrangement.End
val mainAxisPositions = IntArray(childrenMainAxisSizes.size) { 0 }
with(arrangement) {
arrange(
- mainAxisLayoutSize, childrenMainAxisSizes,
- layoutDirection, mainAxisPositions
+ mainAxisLayoutSize,
+ childrenMainAxisSizes,
+ layoutDirection,
+ mainAxisPositions,
)
}
placeables.fastForEachIndexed { j, placeable ->
- placeable.place(
- x = mainAxisPositions[j],
- y = crossAxisPositions[i]
- )
+ placeable.place(x = mainAxisPositions[j], y = crossAxisPositions[i])
}
}
}
@@ -289,8 +258,8 @@
/**
* ProvideContentColorTextStyle
*
- * A convenience method to provide values to both LocalContentColor and LocalTextStyle in
- * one call. This is less expensive than nesting calls to CompositionLocalProvider.
+ * A convenience method to provide values to both LocalContentColor and LocalTextStyle in one call.
+ * This is less expensive than nesting calls to CompositionLocalProvider.
*
* Text styles will be merged with the current value of LocalTextStyle.
*/
@@ -298,12 +267,12 @@
private fun ProvideContentColorTextStyle(
contentColor: Color,
textStyle: TextStyle,
- content: @Composable () -> Unit
+ content: @Composable () -> Unit,
) {
val mergedStyle = LocalTextStyle.current.merge(textStyle)
CompositionLocalProvider(
LocalContentColor provides contentColor,
LocalTextStyle provides mergedStyle,
- content = content
+ content = content,
)
}