Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 0 additions & 70 deletions docs/guide/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,73 +189,3 @@ The `PressFeedbackType` enum defines different types of visual feedback that can
| None | No visual feedback |
| Sink | Applies a sink effect, where the component scales down slightly when pressed |
| Tilt | Applies a tilt effect, where the component tilts slightly based on the touch position |

## Smooth Rounded Corners (G2RoundedCornerShape)

`G2RoundedCornerShape` provides visually smoother corners than the standard `RoundedCornerShape` by blending part of the circular arc with Bézier transitions. It supports: a single uniform corner size, per-corner sizes (Dp / px / percent), preset or custom smoothness via `CornerSmoothness`, and a ready-made `CapsuleShape()` helper.

> Source: https://github.com/Kyant0/Capsule (Apache-2.0 License).

```kotlin
G2RoundedCornerShape(size: Dp, cornerSmoothness: CornerSmoothness = CornerSmoothness.Default)
G2RoundedCornerShape(
topStart: Dp = 0.dp,
topEnd: Dp = 0.dp,
bottomEnd: Dp = 0.dp,
bottomStart: Dp = 0.dp,
cornerSmoothness: CornerSmoothness = CornerSmoothness.Default
)
G2RoundedCornerShape(percent: Int, cornerSmoothness: CornerSmoothness = CornerSmoothness.Default)
CapsuleShape(cornerSmoothness: CornerSmoothness = CornerSmoothness.Default)
```

`CornerSmoothness` parameters:
* `circleFraction`: 0f..1f portion of a quarter circle preserved (1f = normal rounded corner, no smoothing blend)
* `extendedFraction`: how much the control points extend horizontally/vertically to create a softer capsule-like shape

Presets:
* `CornerSmoothness.Default` – balanced smoothness (softened corners)
* `CornerSmoothness.None` – equivalent to a regular rounded corner (no extra smoothing)

### Basic Usage

```kotlin
Surface(shape = G2RoundedCornerShape(16.dp)) {
/* 内容 */
}
```

### Per-Corner Sizes

```kotlin
Surface(
shape = G2RoundedCornerShape(
topStart = 16.dp,
topEnd = 16.dp,
bottomStart = 8.dp,
bottomEnd = 8.dp,
cornerSmoothness = CornerSmoothness.Default
)
) { /* Content */ }
```

### Capsule Shape

```kotlin
Surface(shape = CapsuleShape()) { /* Content */ }
```

### Custom Smoothness

You can craft your own smoothness (smaller `circleFraction` & higher `extendedFraction` => softer / more elongated transition):

```kotlin
val ExtraSmooth = CornerSmoothness(
circleFraction = 0.55f, // retain 55% of the arc; lower -> more smoothing
extendedFraction = 0.90f // push Bézier handles further for a pill-like feel
)

Surface(shape = G2RoundedCornerShape(24.dp, cornerSmoothness = ExtraSmooth)) {
// Content
}
```
70 changes: 0 additions & 70 deletions docs/zh_CN/guide/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,73 +189,3 @@ Box(
| None | 无视觉反馈 |
| Sink | 应用下沉效果,组件在按下时轻微缩小 |
| Tilt | 应用倾斜效果,组件根据触摸位置轻微倾斜 |

## 平滑圆角 (G2RoundedCornerShape)

`G2RoundedCornerShape` 通过在标准圆角圆弧与 Bézier 过渡之间混合,实现比 `RoundedCornerShape` 更柔和、视觉更自然的圆角。它支持:统一圆角值、分别设置四个角(支持 Dp / px / 百分比)、通过 `CornerSmoothness` 预设或自定义平滑度,以及快捷的 `CapsuleShape()` 胶囊形状。

> 来源: https://github.com/Kyant0/Capsule (Apache-2.0 License)。

```kotlin
G2RoundedCornerShape(size: Dp, cornerSmoothness: CornerSmoothness = CornerSmoothness.Default)
G2RoundedCornerShape(
topStart: Dp = 0.dp,
topEnd: Dp = 0.dp,
bottomEnd: Dp = 0.dp,
bottomStart: Dp = 0.dp,
cornerSmoothness: CornerSmoothness = CornerSmoothness.Default
)
G2RoundedCornerShape(percent: Int, cornerSmoothness: CornerSmoothness = CornerSmoothness.Default)
CapsuleShape(cornerSmoothness: CornerSmoothness = CornerSmoothness.Default)
```

`CornerSmoothness` 参数说明:
* `circleFraction`: 0f..1f,表示保留四分之一圆弧的比例(1f = 传统圆角,不做平滑混合)
* `extendedFraction`: 控制 Bézier 控制点向外延伸的程度,越大越接近椭圆/胶囊视觉

预设:
* `CornerSmoothness.Default` – 默认柔滑(推荐常规使用)
* `CornerSmoothness.None` – 与普通圆角等效(无额外平滑)

### 基本使用

```kotlin
Surface(shape = G2RoundedCornerShape(16.dp)) {
/* 内容 */
}
```

### 分别指定四个角

```kotlin
Surface(
shape = G2RoundedCornerShape(
topStart = 16.dp,
topEnd = 16.dp,
bottomStart = 8.dp,
bottomEnd = 8.dp,
cornerSmoothness = CornerSmoothness.Default
)
) { /* 内容 */ }
```

### 胶囊形状

```kotlin
Surface(shape = CapsuleShape()) { /* 内容 */ }
```

### 自定义平滑度

(降低 `circleFraction` + 提高 `extendedFraction` => 更软、更延展)

```kotlin
val ExtraSmooth = CornerSmoothness(
circleFraction = 0.55f, // 保留 55% 圆弧,越低越“圆润”
extendedFraction = 0.90f // 控制点更外扩,接近胶囊
)

Surface(shape = G2RoundedCornerShape(24.dp, cornerSmoothness = ExtraSmooth)) {
// 内容
}
```
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
android-gradle-plugin = "8.13.0"
androidx-activity = "1.11.0"
androidx-window = "1.5.0"
capsule = "2.1.1-patch2"
jetbrains-compose = "1.9.1"
jetbrains-compose-hotReload = "1.0.0-rc02"
jetbrains-androidx-navigation = "2.9.1"
Expand All @@ -16,6 +17,7 @@ androidx-window = { group = "androidx.window", name = "window", version.ref = "a
jetbrains-androidx-navigation = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "jetbrains-androidx-navigation" }
jetbrains-compose-ui-backhandler = { module = "org.jetbrains.compose.ui:ui-backhandler", version.ref = "jetbrains-compose" }
jetbrains-compose-window-size = { module = "org.jetbrains.compose.material3:material3-window-size-class", version.ref = "jetbrains-compose-window-size" }
gaze-capsule = { module = "com.mocharealm.gaze:capsule", version.ref = "capsule" }

[plugins]
android-application = { id = "com.android.application", version.ref = "android-gradle-plugin" }
Expand Down
2 changes: 2 additions & 0 deletions miuix/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ kotlin {

implementation(libs.jetbrains.compose.ui.backhandler)
implementation(libs.jetbrains.compose.window.size)

implementation(libs.gaze.capsule) // Capsule for Multiplatform
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.mocharealm.gaze.capsule.ContinuousRoundedRectangle
import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.utils.G2RoundedCornerShape

/**
* A [Button] component with Miuix style.
Expand All @@ -48,7 +48,7 @@ fun Button(
insideMargin: PaddingValues = ButtonDefaults.InsideMargin,
content: @Composable RowScope.() -> Unit
) {
val shape = remember(cornerRadius) { G2RoundedCornerShape(cornerRadius) }
val shape = remember(cornerRadius) { ContinuousRoundedRectangle(cornerRadius) }
val color = if (enabled) colors.color else colors.disabledColor
Surface(
onClick = onClick,
Expand Down Expand Up @@ -93,7 +93,7 @@ fun TextButton(
minHeight: Dp = ButtonDefaults.MinHeight,
insideMargin: PaddingValues = ButtonDefaults.InsideMargin
) {
val shape = remember(cornerRadius) { G2RoundedCornerShape(cornerRadius) }
val shape = remember(cornerRadius) { ContinuousRoundedRectangle(cornerRadius) }
val color = if (enabled) colors.color else colors.disabledColor
val textColor = if (enabled) colors.textColor else colors.disabledTextColor
Surface(
Expand Down
10 changes: 5 additions & 5 deletions miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/Card.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import androidx.compose.ui.semantics.isTraversalGroup
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.mocharealm.gaze.capsule.ContinuousRoundedRectangle
import com.mocharealm.gaze.capsule.continuities.G1Continuity
import top.yukonga.miuix.kmp.theme.LocalContentColor
import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.utils.CornerSmoothness
import top.yukonga.miuix.kmp.utils.G2RoundedCornerShape
import top.yukonga.miuix.kmp.utils.PressFeedbackType
import top.yukonga.miuix.kmp.utils.SinkFeedback
import top.yukonga.miuix.kmp.utils.TiltFeedback
Expand Down Expand Up @@ -141,8 +141,8 @@ private fun BasicCard(
cornerRadius: Dp = CardDefaults.CornerRadius,
content: @Composable () -> Unit,
) {
val shape = remember(cornerRadius) { G2RoundedCornerShape(cornerRadius) }
val clipShape = remember(cornerRadius) { G2RoundedCornerShape(cornerRadius, CornerSmoothness.None) }
val shape = remember(cornerRadius) { ContinuousRoundedRectangle(cornerRadius) }
val clipShape = remember(cornerRadius) { ContinuousRoundedRectangle(cornerRadius, G1Continuity) }

CompositionLocalProvider(
LocalContentColor provides colors.contentColor,
Expand All @@ -152,7 +152,7 @@ private fun BasicCard(
.semantics(mergeDescendants = false) {
isTraversalGroup = true
}
.clip(clipShape) // For touch feedback, there is a problem when using G2RoundedCornerShape.
.clip(clipShape) // For touch feedback, there is a problem when using G2Continuity.
.background(color = colors.color, shape = shape),
propagateMinConstraints = true,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import com.mocharealm.gaze.capsule.ContinuousCapsule
import kotlinx.coroutines.launch
import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.utils.CapsuleShape
import top.yukonga.miuix.kmp.utils.pressable

/**
Expand Down Expand Up @@ -94,7 +94,7 @@ fun Checkbox(
.wrapContentSize(Alignment.Center)
.requiredSize(25.5.dp)
.pressable(enabled = enabled, delay = null)
.clip(CapsuleShape)
.clip(ContinuousCapsule)
.drawBehind {
drawCircle(backgroundColor)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.lerp
import top.yukonga.miuix.kmp.utils.CapsuleShape
import top.yukonga.miuix.kmp.utils.G2RoundedCornerShape
import com.mocharealm.gaze.capsule.ContinuousCapsule
import com.mocharealm.gaze.capsule.ContinuousRoundedRectangle
import top.yukonga.miuix.kmp.utils.Hsv
import top.yukonga.miuix.kmp.utils.toHsv
import kotlin.math.abs
Expand Down Expand Up @@ -120,7 +120,7 @@ fun ColorPalette(
modifier = Modifier
.fillMaxWidth()
.height(26.dp)
.clip(CapsuleShape())
.clip(ContinuousCapsule)
.background(lastEmittedColor ?: initialColor)
)
}
Expand Down Expand Up @@ -159,7 +159,7 @@ fun ColorPalette(
alpha = it
val newColor = base.copy(alpha = it)
lastAcceptedHSV =
base.toHsv().let { it -> Triple(it.h.toFloat(), (it.s / 100.0).toFloat(), (it.v / 100.0).toFloat()) }
base.toHsv().let { Triple(it.h.toFloat(), (it.s / 100.0).toFloat(), (it.v / 100.0).toFloat()) }
lastEmittedColor = newColor
onColorChangedState.value(newColor)
}
Expand All @@ -182,7 +182,7 @@ private fun PaletteCanvas(
val totalColumns = hueColumns + if (includeGrayColumn) 1 else 0
val rowSV = remember(rows) { buildRowSV(rows) }
val grayV = remember(rows) { buildGrayV(rows) }
val shape = G2RoundedCornerShape(cornerRadius)
val shape = ContinuousRoundedRectangle(cornerRadius)

var sizePx by remember { mutableStateOf(IntSize.Zero) }

Expand Down Expand Up @@ -253,9 +253,9 @@ private fun PaletteCanvas(
y = with(density) { cyPx.toDp() - indicatorSize / 2 }
)
.size(indicatorSize)
.clip(CapsuleShape())
.border(6.dp, Color.White, CapsuleShape())
.background(Color.Transparent, CapsuleShape())
.clip(ContinuousCapsule)
.border(6.dp, Color.White, ContinuousCapsule)
.background(Color.Transparent, ContinuousCapsule)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import top.yukonga.miuix.kmp.utils.CapsuleShape
import com.mocharealm.gaze.capsule.ContinuousCapsule
import top.yukonga.miuix.kmp.utils.ColorUtils
import top.yukonga.miuix.kmp.utils.Hsv
import top.yukonga.miuix.kmp.utils.OkLab
Expand Down Expand Up @@ -154,7 +154,7 @@ fun HsvColorPicker(
modifier = Modifier
.fillMaxWidth()
.height(26.dp)
.clip(CapsuleShape())
.clip(ContinuousCapsule)
.background(selectedColor)
)
}
Expand Down Expand Up @@ -371,7 +371,7 @@ fun OkHsvColorPicker(
modifier = Modifier
.fillMaxWidth()
.height(26.dp)
.clip(CapsuleShape())
.clip(ContinuousCapsule)
.background(selectedColor)
)
}
Expand Down Expand Up @@ -596,7 +596,7 @@ fun OkLabColorPicker(
modifier = Modifier
.fillMaxWidth()
.height(26.dp)
.clip(CapsuleShape())
.clip(ContinuousCapsule)
.background(selectedColor)
)
}
Expand Down Expand Up @@ -840,7 +840,7 @@ private fun ColorSlider(

Box(
modifier = Modifier
.clip(CapsuleShape())
.clip(ContinuousCapsule)
.then(modifier)
.height(sliderHeightDp)
.onGloballyPositioned { coordinates ->
Expand Down Expand Up @@ -903,8 +903,8 @@ private fun SliderIndicator(
modifier = modifier
.offset(x = indicatorOffsetXDp)
.size(indicatorSize)
.border(6.dp, Color.White, CapsuleShape())
.background(Color.Transparent, CapsuleShape())
.border(6.dp, Color.White, ContinuousCapsule)
.background(Color.Transparent, ContinuousCapsule)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.mocharealm.gaze.capsule.ContinuousCapsule
import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.utils.CapsuleShape

/**
* A [FloatingActionButton] component with Miuix style.
Expand All @@ -43,7 +43,7 @@ import top.yukonga.miuix.kmp.utils.CapsuleShape
fun FloatingActionButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
shape: Shape = CapsuleShape(),
shape: Shape = ContinuousCapsule,
containerColor: Color = MiuixTheme.colorScheme.primary,
shadowElevation: Dp = 4.dp,
minWidth: Dp = 60.dp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.mocharealm.gaze.capsule.ContinuousRoundedRectangle
import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.utils.G2RoundedCornerShape

/**
* A [FloatingToolbar] that renders its content in a Card, arranged either horizontally or vertically.
Expand All @@ -54,7 +54,7 @@ fun FloatingToolbar(
content: @Composable () -> Unit
) {
val density = LocalDensity.current
val roundedCornerShape = remember(cornerRadius) { G2RoundedCornerShape(cornerRadius) }
val roundedCornerShape = remember(cornerRadius) { ContinuousRoundedRectangle(cornerRadius) }
val dividerColor = MiuixTheme.colorScheme.dividerLine

Box(
Expand Down
Loading
Loading