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 androidx.annotation.Sampled
20 import androidx.compose.foundation.progressSemantics
21 import androidx.compose.runtime.Composable
22 import androidx.compose.runtime.getValue
23 import androidx.compose.runtime.mutableStateOf
24 import androidx.compose.runtime.remember
25 import androidx.compose.runtime.setValue
26 import androidx.compose.ui.Modifier
27 import androidx.compose.ui.semantics.disabled
28 import androidx.compose.ui.semantics.semantics
29 import androidx.compose.ui.semantics.setProgress
30 import androidx.compose.ui.util.lerp
31 import androidx.wear.compose.material.Icon
32 import androidx.wear.compose.material.Stepper
33 import androidx.wear.compose.material.StepperDefaults
34 import androidx.wear.compose.material.Text
35 import kotlin.math.roundToInt
36
37 @Sampled
38 @Composable
39 fun StepperSample() {
40 var value by remember { mutableStateOf(2f) }
41 Stepper(
42 value = value,
43 onValueChange = { value = it },
44 valueRange = 1f..4f,
45 increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
46 decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
47 steps = 7
48 ) {
49 Text("Value: $value")
50 }
51 }
52
53 @Sampled
54 @Composable
StepperWithIntegerSamplenull55 fun StepperWithIntegerSample() {
56 var value by remember { mutableStateOf(2) }
57 Stepper(
58 value = value,
59 onValueChange = { value = it },
60 increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
61 decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
62 valueProgression = 1..10
63 ) {
64 Text("Value: $value")
65 }
66 }
67
68 @Sampled
69 @Composable
StepperWithoutRangeSemanticsSamplenull70 fun StepperWithoutRangeSemanticsSample() {
71 var value by remember { mutableStateOf(2f) }
72 Stepper(
73 value = value,
74 onValueChange = { value = it },
75 valueRange = 1f..4f,
76 increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
77 decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
78 steps = 7,
79 enableRangeSemantics = false
80 ) {
81 Text("Value: $value")
82 }
83 }
84
85 @Sampled
86 @Composable
StepperWithCustomSemanticsSamplenull87 fun StepperWithCustomSemanticsSample() {
88 var value by remember { mutableStateOf(2f) }
89 val valueRange = 1f..4f
90 val onValueChange = { i: Float -> value = i }
91 val steps = 7
92
93 Stepper(
94 value = value,
95 onValueChange = onValueChange,
96 valueRange = valueRange,
97 modifier = Modifier.customSemantics(value, true, onValueChange, valueRange, steps),
98 increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
99 decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
100 steps = steps,
101 enableRangeSemantics = false
102 ) {
103 Text("Value: $value")
104 }
105 }
106
107 // Declaring the custom semantics for StepperWithCustomSemanticsSample
customSemanticsnull108 private fun Modifier.customSemantics(
109 value: Float,
110 enabled: Boolean,
111 onValueChange: (Float) -> Unit,
112 valueRange: ClosedFloatingPointRange<Float>,
113 steps: Int
114 ): Modifier =
115 semantics(mergeDescendants = true) {
116 if (!enabled) disabled()
117 setProgress(
118 action = { targetValue ->
119 val newStepIndex =
120 ((value - valueRange.start) / (valueRange.endInclusive - valueRange.start) *
121 (steps + 1))
122 .roundToInt()
123 .coerceIn(0, steps + 1)
124
125 if (value.toInt() == newStepIndex) {
126 false
127 } else {
128 onValueChange(targetValue)
129 true
130 }
131 }
132 )
133 }
134 .progressSemantics(
135 lerp(valueRange.start, valueRange.endInclusive, value / (steps + 1).toFloat())
136 .coerceIn(valueRange),
137 valueRange,
138 steps
139 )
140