Skip to content

Commit fc8494d

Browse files
committed
library: Set @NonRestartableComposable
1 parent a701ed1 commit fc8494d

32 files changed

+534
-282
lines changed

iosApp/iosApp/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<key>CFBundleShortVersionString</key>
1818
<string>1.0.7</string>
1919
<key>CFBundleVersion</key>
20-
<string>652</string>
20+
<string>654</string>
2121
<key>LSRequiresIPhoneOS</key>
2222
<true/>
2323
<key>CADisableMinimumFrameDurationOnPhone</key>

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/Button.kt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ import androidx.compose.foundation.layout.defaultMinSize
1111
import androidx.compose.foundation.layout.padding
1212
import androidx.compose.runtime.Composable
1313
import androidx.compose.runtime.Immutable
14+
import androidx.compose.runtime.NonRestartableComposable
15+
import androidx.compose.runtime.derivedStateOf
16+
import androidx.compose.runtime.getValue
1417
import androidx.compose.runtime.remember
18+
import androidx.compose.runtime.rememberUpdatedState
1519
import androidx.compose.ui.Alignment
1620
import androidx.compose.ui.Modifier
1721
import androidx.compose.ui.graphics.Color
@@ -37,6 +41,7 @@ import top.yukonga.miuix.kmp.theme.MiuixTheme
3741
* @param content The [Composable] content of the [Button].
3842
*/
3943
@Composable
44+
@NonRestartableComposable
4045
fun Button(
4146
onClick: () -> Unit,
4247
modifier: Modifier = Modifier,
@@ -48,10 +53,11 @@ fun Button(
4853
insideMargin: PaddingValues = ButtonDefaults.InsideMargin,
4954
content: @Composable RowScope.() -> Unit
5055
) {
56+
val currentOnClick by rememberUpdatedState(onClick)
5157
val shape = remember(cornerRadius) { ContinuousRoundedRectangle(cornerRadius) }
52-
val color = if (enabled) colors.color else colors.disabledColor
58+
val color by remember(enabled, colors) { derivedStateOf { if (enabled) colors.color else colors.disabledColor } }
5359
Surface(
54-
onClick = onClick,
60+
onClick = currentOnClick,
5561
enabled = enabled,
5662
modifier = modifier.semantics { role = Role.Button },
5763
shape = shape,
@@ -82,6 +88,7 @@ fun Button(
8288
* @param insideMargin The margin inside the [TextButton].
8389
*/
8490
@Composable
91+
@NonRestartableComposable
8592
fun TextButton(
8693
text: String,
8794
onClick: () -> Unit,
@@ -93,11 +100,12 @@ fun TextButton(
93100
minHeight: Dp = ButtonDefaults.MinHeight,
94101
insideMargin: PaddingValues = ButtonDefaults.InsideMargin
95102
) {
103+
val currentOnClick by rememberUpdatedState(onClick)
96104
val shape = remember(cornerRadius) { ContinuousRoundedRectangle(cornerRadius) }
97-
val color = if (enabled) colors.color else colors.disabledColor
98-
val textColor = if (enabled) colors.textColor else colors.disabledTextColor
105+
val color by remember(enabled, colors) { derivedStateOf { if (enabled) colors.color else colors.disabledColor } }
106+
val textColor by remember(enabled, colors) { derivedStateOf { if (enabled) colors.textColor else colors.disabledTextColor } }
99107
Surface(
100-
onClick = onClick,
108+
onClick = currentOnClick,
101109
enabled = enabled,
102110
modifier = modifier.semantics { role = Role.Button },
103111
shape = shape,
@@ -227,4 +235,4 @@ class TextButtonColors(
227235
textColor = textColor,
228236
disabledTextColor = disabledTextColor
229237
)
230-
}
238+
}

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/Card.kt

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import androidx.compose.foundation.layout.padding
1515
import androidx.compose.runtime.Composable
1616
import androidx.compose.runtime.CompositionLocalProvider
1717
import androidx.compose.runtime.Immutable
18+
import androidx.compose.runtime.derivedStateOf
19+
import androidx.compose.runtime.getValue
1820
import androidx.compose.runtime.remember
21+
import androidx.compose.runtime.rememberUpdatedState
1922
import androidx.compose.ui.Modifier
2023
import androidx.compose.ui.draw.clip
2124
import androidx.compose.ui.graphics.Color
@@ -94,6 +97,8 @@ fun Card(
9497
content: @Composable ColumnScope.() -> Unit,
9598
) {
9699
val interactionSource = remember { MutableInteractionSource() }
100+
val currentOnClick by rememberUpdatedState(onClick)
101+
val currentOnLongPress by rememberUpdatedState(onLongPress)
97102

98103
val pressFeedback = remember(pressFeedbackType) {
99104
when (pressFeedbackType) {
@@ -103,9 +108,17 @@ fun Card(
103108
}
104109
}
105110

111+
val usedInteractionSource by remember(pressFeedback) {
112+
derivedStateOf { if (pressFeedback != null) interactionSource else null }
113+
}
114+
val indicationLocal = LocalIndication.current
115+
val indicationToUse = remember(showIndication, indicationLocal) {
116+
if (showIndication == true) indicationLocal else null
117+
}
118+
106119
BasicCard(
107120
modifier = modifier.pressable(
108-
interactionSource = if (pressFeedback != null) interactionSource else null,
121+
interactionSource = usedInteractionSource,
109122
indication = pressFeedback,
110123
delay = null
111124
),
@@ -116,9 +129,9 @@ fun Card(
116129
modifier = Modifier
117130
.combinedClickable(
118131
interactionSource = interactionSource,
119-
indication = if (showIndication == true) LocalIndication.current else null,
120-
onClick = { onClick?.invoke() },
121-
onLongClick = onLongPress
132+
indication = indicationToUse,
133+
onClick = { currentOnClick?.invoke() },
134+
onLongClick = currentOnLongPress
122135
)
123136
.padding(insideMargin),
124137
content = content
@@ -200,4 +213,4 @@ class CardColors(
200213
color.takeOrElse { this.color },
201214
contentColor.takeOrElse { this.contentColor },
202215
)
203-
}
216+
}

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/Checkbox.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ import androidx.compose.runtime.Composable
1818
import androidx.compose.runtime.Immutable
1919
import androidx.compose.runtime.LaunchedEffect
2020
import androidx.compose.runtime.Stable
21+
import androidx.compose.runtime.derivedStateOf
2122
import androidx.compose.runtime.getValue
2223
import androidx.compose.runtime.remember
24+
import androidx.compose.runtime.rememberUpdatedState
2325
import androidx.compose.ui.Alignment
2426
import androidx.compose.ui.Modifier
2527
import androidx.compose.ui.draw.clip
@@ -57,25 +59,32 @@ fun Checkbox(
5759
colors: CheckboxColors = CheckboxDefaults.checkboxColors(),
5860
enabled: Boolean = true,
5961
) {
62+
val currentOnCheckedChange by rememberUpdatedState(onCheckedChange)
6063
val hapticFeedback = LocalHapticFeedback.current
6164

65+
val targetBackgroundColor by remember(checked, enabled, colors) {
66+
derivedStateOf { if (checked) colors.checkedBackgroundColor(enabled) else colors.uncheckedBackgroundColor(enabled) }
67+
}
6268
val backgroundColor by animateColorAsState(
63-
targetValue = if (checked) colors.checkedBackgroundColor(enabled) else colors.uncheckedBackgroundColor(enabled),
69+
targetValue = targetBackgroundColor,
6470
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
6571
)
6672

73+
val targetForegroundColor by remember(checked, enabled, colors) {
74+
derivedStateOf { if (checked) colors.checkedForegroundColor(enabled) else colors.uncheckedForegroundColor(enabled) }
75+
}
6776
val foregroundColor by animateColorAsState(
68-
targetValue = if (checked) colors.checkedForegroundColor(enabled) else colors.uncheckedForegroundColor(enabled),
77+
targetValue = targetForegroundColor,
6978
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
7079
)
7180

7281
val checkmarkAnim = rememberCheckmarkAnimationState(checked)
7382

74-
val finalModifier = if (onCheckedChange != null) {
83+
val finalModifier = if (currentOnCheckedChange != null) {
7584
Modifier.toggleable(
7685
value = checked,
7786
onValueChange = {
78-
onCheckedChange(it)
87+
currentOnCheckedChange!!(it)
7988
hapticFeedback.performHapticFeedback(
8089
if (it) HapticFeedbackType.ToggleOn else HapticFeedbackType.ToggleOff
8190
)
@@ -325,4 +334,4 @@ class CheckboxColors(
325334
@Stable
326335
internal fun uncheckedBackgroundColor(enabled: Boolean): Color =
327336
if (enabled) uncheckedBackgroundColor else disabledUncheckedBackgroundColor
328-
}
337+
}

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/ColorPalette.kt

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ package top.yukonga.miuix.kmp.basic
55

66
import androidx.compose.foundation.Canvas
77
import androidx.compose.foundation.background
8-
import androidx.compose.foundation.gestures.detectDragGestures
9-
import androidx.compose.foundation.gestures.detectTapGestures
8+
import androidx.compose.foundation.gestures.awaitEachGesture
9+
import androidx.compose.foundation.gestures.awaitFirstDown
1010
import androidx.compose.foundation.layout.Arrangement
1111
import androidx.compose.foundation.layout.Box
1212
import androidx.compose.foundation.layout.Column
@@ -17,6 +17,7 @@ import androidx.compose.foundation.layout.offset
1717
import androidx.compose.foundation.layout.size
1818
import androidx.compose.runtime.Composable
1919
import androidx.compose.runtime.LaunchedEffect
20+
import androidx.compose.runtime.derivedStateOf
2021
import androidx.compose.runtime.getValue
2122
import androidx.compose.runtime.mutableStateOf
2223
import androidx.compose.runtime.remember
@@ -127,6 +128,10 @@ fun ColorPalette(
127128
)
128129
}
129130

131+
val baseColor by remember(selectedRow, selectedCol, rows, hueColumns, includeGrayColumn) {
132+
derivedStateOf { cellColor(selectedCol, selectedRow, rowSV, grayV, hueColumns, includeGrayColumn) }
133+
}
134+
130135
PaletteCanvas(
131136
rows = rows,
132137
hueColumns = hueColumns,
@@ -138,16 +143,14 @@ fun ColorPalette(
138143
onSelect = { r, c ->
139144
selectedRow = r
140145
selectedCol = c
141-
val base = cellColor(c, r, rowSV, grayV, hueColumns, includeGrayColumn)
142-
val newColor = base.copy(alpha = alpha)
143-
lastAcceptedHSV = base.toHsv().let { Triple(it.h.toFloat(), (it.s / 100.0).toFloat(), (it.v / 100.0).toFloat()) }
146+
val newColor = cellColor(c, r, rowSV, grayV, hueColumns, includeGrayColumn).copy(alpha = alpha)
147+
lastAcceptedHSV = newColor.toHsv().let { Triple(it.h.toFloat(), (it.s / 100.0).toFloat(), (it.v / 100.0).toFloat()) }
144148
lastEmittedColor = newColor
145149
onColorChangedState.value(newColor)
146150
}
147151
)
148152

149-
val base = cellColor(selectedCol, selectedRow, rowSV, grayV, hueColumns, includeGrayColumn)
150-
val hsvBase = base.toHsv()
153+
val hsvBase = baseColor.toHsv()
151154
val h = hsvBase.h.toFloat()
152155
val s = (hsvBase.s / 100.0).toFloat()
153156
val v = (hsvBase.v / 100.0).toFloat()
@@ -159,9 +162,9 @@ fun ColorPalette(
159162
currentAlpha = alpha,
160163
onAlphaChanged = {
161164
alpha = it
162-
val newColor = base.copy(alpha = it)
165+
val newColor = baseColor.copy(alpha = it)
163166
lastAcceptedHSV =
164-
base.toHsv().let { Triple(it.h.toFloat(), (it.s / 100.0).toFloat(), (it.v / 100.0).toFloat()) }
167+
baseColor.toHsv().let { Triple(it.h.toFloat(), (it.s / 100.0).toFloat(), (it.v / 100.0).toFloat()) }
165168
lastEmittedColor = newColor
166169
onColorChangedState.value(newColor)
167170
}
@@ -193,17 +196,21 @@ private fun PaletteCanvas(
193196
.clip(shape)
194197
.onGloballyPositioned { sizePx = it.size }
195198
.pointerInput(rows, hueColumns, includeGrayColumn) {
196-
detectTapGestures { pos ->
197-
if (sizePx.width == 0 || sizePx.height == 0) return@detectTapGestures
198-
val (r, c) = pointToCell(pos, sizePx, rows, totalColumns)
199-
onSelectState.value(r, c)
200-
}
201-
}
202-
.pointerInput(rows, hueColumns, includeGrayColumn) {
203-
detectDragGestures { change, _ ->
204-
if (sizePx.width == 0 || sizePx.height == 0) return@detectDragGestures
205-
val (r, c) = pointToCell(change.position, sizePx, rows, totalColumns)
206-
onSelectState.value(r, c)
199+
awaitEachGesture {
200+
val down = awaitFirstDown()
201+
if (sizePx.width == 0 || sizePx.height == 0) return@awaitEachGesture
202+
val (r0, c0) = pointToCell(down.position, sizePx, rows, totalColumns)
203+
onSelectState.value(r0, c0)
204+
205+
val pointerId = down.id
206+
while (true) {
207+
val event = awaitPointerEvent()
208+
val change = event.changes.find { it.id == pointerId } ?: event.changes.firstOrNull() ?: break
209+
if (!change.pressed) break
210+
val (r, c) = pointToCell(change.position, sizePx, rows, totalColumns)
211+
onSelectState.value(r, c)
212+
change.consume()
213+
}
207214
}
208215
}
209216
.fillMaxWidth()
@@ -368,4 +375,4 @@ private fun <T> List<T>.indexOfMinBy(selector: (T) -> Float): Int {
368375
return idx
369376
}
370377

371-
private fun sq(v: Float) = v * v
378+
private fun sq(v: Float) = v * v

0 commit comments

Comments
 (0)