16
16
17
17
package com.google.android.horologist.compose.material
18
18
19
+ import androidx.compose.foundation.layout.fillMaxWidth
19
20
import androidx.compose.runtime.Composable
21
+ import androidx.compose.runtime.remember
20
22
import androidx.compose.ui.Modifier
23
+ import androidx.compose.ui.platform.LocalConfiguration
24
+ import androidx.compose.ui.platform.LocalDensity
21
25
import androidx.compose.ui.res.stringResource
26
+ import androidx.compose.ui.text.rememberTextMeasurer
22
27
import androidx.compose.ui.text.style.TextAlign
23
28
import androidx.compose.ui.text.style.TextOverflow
29
+ import androidx.compose.ui.unit.Constraints
30
+ import androidx.compose.ui.unit.dp
31
+ import androidx.wear.compose.foundation.lazy.ScalingLazyListScope
32
+ import androidx.wear.compose.material.LocalTextStyle
24
33
import androidx.wear.compose.material.MaterialTheme
25
34
import androidx.wear.compose.material.Text
26
35
import androidx.wear.compose.material.dialog.Dialog
@@ -32,65 +41,112 @@ import com.google.android.horologist.compose.layout.rememberColumnState
32
41
/* *
33
42
* This component is an alternative to [AlertContent], providing the following:
34
43
* - a convenient way of passing a title and a message;
44
+ * - additional content can be specified between the message and the buttons
35
45
* - default positive and negative buttons;
36
46
* - wrapped in a [Dialog];
37
47
*/
38
48
@ExperimentalHorologistApi
39
49
@Composable
40
50
public fun AlertDialog (
41
- onCancelButtonClick : () -> Unit ,
42
- onOKButtonClick : () -> Unit ,
43
51
showDialog : Boolean ,
52
+ onCancel : () -> Unit ,
53
+ onOk : () -> Unit ,
44
54
modifier : Modifier = Modifier ,
45
55
icon : @Composable (() -> Unit )? = null,
46
56
title : String? = null,
47
57
message : String? = null,
48
58
okButtonContentDescription : String = stringResource(android.R .string.ok),
49
59
cancelButtonContentDescription : String = stringResource(android.R .string.cancel),
50
- columnState : ScalingLazyColumnState = rememberColumnState(
60
+ state : ScalingLazyColumnState = rememberColumnState(
51
61
ScalingLazyColumnDefaults .responsive(),
52
62
),
63
+ content : (ScalingLazyListScope .() -> Unit )? = null,
53
64
) {
54
65
Dialog (
55
66
showDialog = showDialog,
56
- onDismissRequest = onCancelButtonClick ,
67
+ onDismissRequest = onCancel ,
57
68
modifier = modifier,
58
- scrollState = columnState .state,
69
+ scrollState = state .state,
59
70
) {
60
71
AlertContent (
61
72
icon = icon,
62
73
title = title,
63
74
message = message,
64
- onCancelButtonClick = onCancelButtonClick,
65
- onOKButtonClick = onOKButtonClick,
75
+ content = content,
76
+ onCancel = onCancel,
77
+ onOk = onOk,
66
78
okButtonContentDescription = okButtonContentDescription,
67
79
cancelButtonContentDescription = cancelButtonContentDescription,
68
- columnState = columnState ,
80
+ state = state ,
69
81
showPositionIndicator = false ,
70
82
)
71
83
}
72
84
}
73
85
86
+ /* *
87
+ * This component is an alternative to [AlertContent], providing the following:
88
+ * - a convenient way of passing a title and a message;
89
+ * - slot for scrollable content (including stack of Chips for options);
90
+ * - wrapped in a [Dialog];
91
+ */
92
+ @ExperimentalHorologistApi
93
+ @Composable
94
+ public fun AlertDialog (
95
+ showDialog : Boolean ,
96
+ onDismiss : () -> Unit ,
97
+ modifier : Modifier = Modifier ,
98
+ icon : @Composable (() -> Unit )? = null,
99
+ title : String? = null,
100
+ message : String? = null,
101
+ state : ScalingLazyColumnState = rememberColumnState(
102
+ ScalingLazyColumnDefaults .responsive(),
103
+ ),
104
+ content : (ScalingLazyListScope .() -> Unit )? = null,
105
+ ) {
106
+ Dialog (
107
+ showDialog = showDialog,
108
+ onDismissRequest = onDismiss,
109
+ modifier = modifier,
110
+ scrollState = state.state,
111
+ ) {
112
+ AlertContent (
113
+ icon = icon,
114
+ title = title,
115
+ message = message,
116
+ content = content,
117
+ state = state,
118
+ showPositionIndicator = true ,
119
+ )
120
+ }
121
+ }
122
+
74
123
@ExperimentalHorologistApi
75
124
@Composable
76
125
public fun AlertContent (
77
- onCancelButtonClick : (() -> Unit )? ,
78
- onOKButtonClick : (() -> Unit )? ,
126
+ onCancel : (() -> Unit )? = null ,
127
+ onOk : (() -> Unit )? = null ,
79
128
icon : @Composable (() -> Unit )? = null,
80
129
title : String? = null,
81
130
message : String? = null,
82
131
okButtonContentDescription : String = stringResource(android.R .string.ok),
83
132
cancelButtonContentDescription : String = stringResource(android.R .string.cancel),
84
- columnState : ScalingLazyColumnState = rememberColumnState(
133
+ state : ScalingLazyColumnState = rememberColumnState(
85
134
ScalingLazyColumnDefaults .responsive(),
86
135
),
87
136
showPositionIndicator : Boolean = true,
137
+ content : (ScalingLazyListScope .() -> Unit )? = null,
88
138
) {
139
+ val density = LocalDensity .current
140
+ val maxScreenWidthPx = with (density) {
141
+ LocalConfiguration .current.screenWidthDp.dp.toPx()
142
+ }
143
+
89
144
ResponsiveDialogContent (
90
145
icon = icon,
91
146
title = title?.let {
92
147
{
93
148
Text (
149
+ modifier = Modifier .fillMaxWidth(),
94
150
text = it,
95
151
color = MaterialTheme .colors.onBackground,
96
152
textAlign = TextAlign .Center ,
@@ -101,19 +157,37 @@ public fun AlertContent(
101
157
},
102
158
message = message?.let {
103
159
{
160
+ // Should message be start or center aligned?
161
+ val textMeasurer = rememberTextMeasurer()
162
+ val textStyle = LocalTextStyle .current
163
+ val totalPaddingPercentage = globalHorizontalPadding + messageExtraHorizontalPadding
164
+ val lineCount = remember(it, density, textStyle, textMeasurer) {
165
+ textMeasurer.measure(
166
+ text = it,
167
+ style = textStyle,
168
+ constraints = Constraints (
169
+ // Available width is reduced by responsive dialog horizontal padding.
170
+ maxWidth = (
171
+ maxScreenWidthPx * (1f - totalPaddingPercentage * 2f / 100f )
172
+ ).toInt(),
173
+ ),
174
+ ).lineCount
175
+ }
176
+ val textAlign = if (lineCount <= 3 ) TextAlign .Center else TextAlign .Start
104
177
Text (
178
+ modifier = Modifier .fillMaxWidth(),
105
179
text = it,
106
180
color = MaterialTheme .colors.onBackground,
107
- textAlign = TextAlign .Center ,
108
- maxLines = 3 ,
181
+ textAlign = textAlign,
109
182
)
110
183
}
111
184
},
112
- onOkButtonClick = onOKButtonClick,
113
- onCancelButtonClick = onCancelButtonClick,
185
+ content = content,
186
+ onOk = onOk,
187
+ onCancel = onCancel,
114
188
okButtonContentDescription = okButtonContentDescription,
115
189
cancelButtonContentDescription = cancelButtonContentDescription,
116
- state = columnState ,
190
+ state = state ,
117
191
showPositionIndicator = showPositionIndicator,
118
192
)
119
193
}
0 commit comments