1 /*
<lambda>null2  * Copyright 2021 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 androidx.wear.compose.material.samples
18 
19 import android.view.MotionEvent
20 import androidx.annotation.Sampled
21 import androidx.compose.foundation.layout.Arrangement
22 import androidx.compose.foundation.layout.Box
23 import androidx.compose.foundation.layout.Row
24 import androidx.compose.foundation.layout.Spacer
25 import androidx.compose.foundation.layout.fillMaxSize
26 import androidx.compose.foundation.layout.padding
27 import androidx.compose.foundation.layout.size
28 import androidx.compose.foundation.layout.width
29 import androidx.compose.foundation.layout.wrapContentSize
30 import androidx.compose.runtime.Composable
31 import androidx.compose.runtime.derivedStateOf
32 import androidx.compose.runtime.getValue
33 import androidx.compose.runtime.mutableStateOf
34 import androidx.compose.runtime.remember
35 import androidx.compose.runtime.rememberCoroutineScope
36 import androidx.compose.runtime.setValue
37 import androidx.compose.ui.Alignment
38 import androidx.compose.ui.ExperimentalComposeUiApi
39 import androidx.compose.ui.Modifier
40 import androidx.compose.ui.input.pointer.pointerInteropFilter
41 import androidx.compose.ui.unit.dp
42 import androidx.wear.compose.material.Chip
43 import androidx.wear.compose.material.MaterialTheme
44 import androidx.wear.compose.material.Picker
45 import androidx.wear.compose.material.Text
46 import androidx.wear.compose.material.rememberPickerState
47 import kotlinx.coroutines.launch
48 
49 @Sampled
50 @Composable
51 fun SimplePicker() {
52     val items = listOf("One", "Two", "Three", "Four", "Five")
53     val state = rememberPickerState(items.size)
54     val contentDescription by remember { derivedStateOf { "${state.selectedOption + 1}" } }
55     Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
56         Text(
57             modifier = Modifier.align(Alignment.TopCenter).padding(top = 10.dp),
58             text = "Selected: ${items[state.selectedOption]}"
59         )
60         Picker(
61             modifier = Modifier.size(100.dp, 100.dp),
62             state = state,
63             contentDescription = contentDescription,
64         ) {
65             Text(items[it])
66         }
67     }
68 }
69 
70 @Sampled
71 @Composable
OptionChangePickernull72 fun OptionChangePicker() {
73     val coroutineScope = rememberCoroutineScope()
74     val state = rememberPickerState(initialNumberOfOptions = 10)
75     val contentDescription by remember { derivedStateOf { "${state.selectedOption + 1}" } }
76     Picker(
77         state = state,
78         separation = 4.dp,
79         contentDescription = contentDescription,
80     ) {
81         Chip(
82             onClick = { coroutineScope.launch { state.scrollToOption(it) } },
83             label = { Text("$it") }
84         )
85     }
86 }
87 
88 @Sampled
89 @Composable
AnimateOptionChangePickernull90 fun AnimateOptionChangePicker() {
91     val coroutineScope = rememberCoroutineScope()
92     val state = rememberPickerState(initialNumberOfOptions = 10)
93     val contentDescription by remember { derivedStateOf { "${state.selectedOption + 1}" } }
94 
95     Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
96         Picker(
97             state = state,
98             separation = 4.dp,
99             contentDescription = contentDescription,
100         ) {
101             Chip(
102                 onClick = { coroutineScope.launch { state.animateScrollToOption(it) } },
103                 label = { Text("$it") }
104             )
105         }
106     }
107 }
108 
109 @OptIn(ExperimentalComposeUiApi::class)
110 @Sampled
111 @Composable
DualPickernull112 fun DualPicker() {
113     var selectedColumn by remember { mutableStateOf(0) }
114     val textStyle = MaterialTheme.typography.display1
115 
116     @Composable
117     fun Option(column: Int, text: String) =
118         Box(modifier = Modifier.fillMaxSize()) {
119             Text(
120                 text = text,
121                 style = textStyle,
122                 color =
123                     if (selectedColumn == column) MaterialTheme.colors.secondary
124                     else MaterialTheme.colors.onBackground,
125                 modifier =
126                     Modifier.align(Alignment.Center).wrapContentSize().pointerInteropFilter {
127                         if (it.action == MotionEvent.ACTION_DOWN) selectedColumn = column
128                         true
129                     }
130             )
131         }
132 
133     Row(
134         modifier = Modifier.fillMaxSize(),
135         verticalAlignment = Alignment.CenterVertically,
136         horizontalArrangement = Arrangement.Center,
137     ) {
138         val hourState =
139             rememberPickerState(initialNumberOfOptions = 12, initiallySelectedOption = 5)
140         val hourContentDescription by remember {
141             derivedStateOf { "${hourState.selectedOption + 1 } hours" }
142         }
143         Picker(
144             readOnly = selectedColumn != 0,
145             state = hourState,
146             modifier = Modifier.size(64.dp, 100.dp),
147             contentDescription = hourContentDescription,
148             option = { hour: Int -> Option(0, "%2d".format(hour + 1)) }
149         )
150         Spacer(Modifier.width(8.dp))
151         Text(text = ":", style = textStyle, color = MaterialTheme.colors.onBackground)
152         Spacer(Modifier.width(8.dp))
153         val minuteState =
154             rememberPickerState(initialNumberOfOptions = 60, initiallySelectedOption = 0)
155         val minuteContentDescription by remember {
156             derivedStateOf { "${minuteState.selectedOption} minutes" }
157         }
158         Picker(
159             readOnly = selectedColumn != 1,
160             state = minuteState,
161             modifier = Modifier.size(64.dp, 100.dp),
162             contentDescription = minuteContentDescription,
163             option = { minute: Int -> Option(1, "%02d".format(minute)) }
164         )
165     }
166 }
167