Skip to content
Open
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
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,12 @@
.externalNativeBuild
.cxx
local.properties
.idea
.kotlin
*.xcodeproj/*
!*.xcodeproj/project.pbxproj
!*.xcodeproj/xcshareddata/
!*.xcodeproj/project.xcworkspace/
!*.xcworkspace/contents.xcworkspacedata
**/xcshareddata/WorkspaceSettings.xcsettings
node_modules/
68 changes: 62 additions & 6 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,51 @@
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl

plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.compose.multiplatform)
}

kotlin {
jvmToolchain(21)
androidTarget()
jvm()

listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "ComposeApp"
isStatic = true
}
}

js {
browser()
binaries.executable()
}

@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
binaries.executable()
}

sourceSets {
commonMain.dependencies {
implementation(project(":capsule"))
implementation(compose.foundation)
implementation(compose.ui)
implementation(compose.material3)
}
jvmMain.dependencies {
implementation(compose.desktop.currentOs)
}
}
}

android {
Expand All @@ -23,10 +67,14 @@ android {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
vcsInfo.include = false
}
}

buildFeatures {
compose = true
}
Expand Down Expand Up @@ -56,10 +104,6 @@ android {
}
}

kotlin {
jvmToolchain(21)
}

dependencies {
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.foundation)
Expand All @@ -68,3 +112,15 @@ dependencies {
implementation(libs.androidx.ui.graphics)
implementation(project(":capsule"))
}

compose.desktop {
application {
mainClass = "com.kyant.capsule.demo.MainKt"

nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "com.kyant.capsule"
packageVersion = "1.0.0"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge(
statusBarStyle = SystemBarStyle.light(Color.TRANSPARENT, Color.TRANSPARENT),
navigationBarStyle = SystemBarStyle.light(Color.TRANSPARENT, Color.TRANSPARENT)
statusBarStyle = SystemBarStyle.Companion.light(Color.TRANSPARENT, Color.TRANSPARENT),
navigationBarStyle = SystemBarStyle.Companion.light(Color.TRANSPARENT, Color.TRANSPARENT)
)

setContent {
MainContent()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ import com.kyant.capsule.ContinuousCapsule
import com.kyant.capsule.continuities.G2Continuity
import com.kyant.capsule.continuities.G2ContinuityProfile
import com.kyant.capsule.path.toPath
import kotlin.math.pow
import kotlin.math.roundToInt

@Composable
fun MainContent() {
Expand Down Expand Up @@ -295,13 +297,13 @@ fun MainContent() {
radiusDp,
0f..maxRadius.value,
"Corner radius",
{ "${"%.0f".format(it)}dp" },
{ "${it.roundToInt()}dp" },
)
Slider(
aspectRatio,
1f..3f,
"Aspect ratio",
{ "%.3f".format(it) },
{ it.toFixed(3) },
)

FlowRow(
Expand Down Expand Up @@ -354,25 +356,25 @@ fun MainContent() {
extendedFraction,
0f..1f,
"Extended fraction",
{ "%.3f".format(it * 100f) + "%" }
{ (it * 100f).toFixed(3) + "%" }
)
Slider(
arcFraction,
0f..0.8f,
"Arc fraction",
{ "%.3f".format(it * 100f) + "%" }
{ (it * 100f).toFixed(3) + "%" }
)
Slider(
bezierCurvatureScale,
0.5f..2f,
"Bezier curvature scale",
{ "%.3f".format(it * 100f) + "%" }
{ (it * 100f).toFixed(3) + "%" }
)
Slider(
arcCurvatureScale,
0.85f..1.5f,
"Arc curvature scale",
{ "%.3f".format(it * 100f) + "%" }
{ (it * 100f).toFixed(3) + "%" }
)
}

Expand All @@ -385,15 +387,19 @@ fun MainContent() {
capsuleExtendedFraction,
0f..1f,
"Extended fraction",
{ "%.3f".format(it * 100f) + "%" }
{ (it * 100f).toFixed(3) + "%" }
)
Slider(
capsuleArcFraction,
0f..1f,
"Arc fraction",
{ "%.3f".format(it * 100f) + "%" }
{ (it * 100f).toFixed(3) + "%" }
)
}
}
}
}

private fun Float.toFixed(digits: Int): String =
((this * 10f.pow(digits)).roundToInt() / 10f.pow(digits)).toString()

Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package com.kyant.capsule.demo

import android.app.Activity
import android.content.Intent
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
Expand Down Expand Up @@ -34,7 +30,6 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
Expand All @@ -43,7 +38,6 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.util.fastCoerceIn
import androidx.compose.ui.window.Dialog
import androidx.core.content.FileProvider
import com.kyant.capsule.Continuity
import com.kyant.capsule.ContinuousCapsule
import com.kyant.capsule.ContinuousRoundedRectangle
Expand All @@ -52,7 +46,6 @@ import com.kyant.capsule.path.toPath
import com.kyant.capsule.path.toSvg
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import java.io.File
import kotlin.math.max
import kotlin.math.min

Expand All @@ -61,7 +54,7 @@ fun SvgExportDialog(
onDismissRequest: () -> Unit,
continuity: () -> Continuity
) {
Dialog(onDismissRequest) {
Dialog(onDismissRequest = onDismissRequest) {
val color = Color(0xFF0088FF)
val contentColor = { Color.White }

Expand Down Expand Up @@ -209,41 +202,42 @@ fun SvgExportDialog(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
val context = LocalContext.current
val createFileLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val uri = result.data?.data
if (uri != null) {
context.contentResolver.openOutputStream(uri)?.use { outputStream ->
val svg = currentPathSegments.toSvg(asDocument = true)
outputStream.write(svg.toByteArray())
}
}
}
}
// val context = LocalContext.current
// val createFileLauncher = rememberLauncherForActivityResult(
// contract = ActivityResultContracts.StartActivityForResult()
// ) { result ->
// if (result.resultCode == Activity.RESULT_OK) {
// val uri = result.data?.data
// if (uri != null) {
// context.contentResolver.openOutputStream(uri)?.use { outputStream ->
// val svg = currentPathSegments.toSvg(asDocument = true)
// outputStream.write(svg.toByteArray())
// }
// }
// }
// }

Box(
Modifier
.clip(ContinuousCapsule)
.background(color)
.clickable {
val svg = currentPathSegments.toSvg(asDocument = true)
val tempFile = File(context.cacheDir, "continuous_rounded_rect.svg").apply {
writeBytes(svg.toByteArray())
}
val uri = FileProvider.getUriForFile(
context,
"${context.packageName}.provider",
tempFile
)
val shareIntent = Intent(Intent.ACTION_SEND).apply {
type = "image/svg+xml"
putExtra(Intent.EXTRA_STREAM, uri)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
context.startActivity(Intent.createChooser(shareIntent, "Share SVG"))
// val svg = currentPathSegments.toSvg(asDocument = true)
// val tempFile =
// File(context.cacheDir, "continuous_rounded_rect.svg").apply {
// writeBytes(svg.toByteArray())
// }
// val uri = FileProvider.getUriForFile(
// context,
// "${context.packageName}.provider",
// tempFile
// )
// val shareIntent = Intent(Intent.ACTION_SEND).apply {
// type = "image/svg+xml"
// putExtra(Intent.EXTRA_STREAM, uri)
// addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
// }
// context.startActivity(Intent.createChooser(shareIntent, "Share SVG"))
}
.height(48.dp)
.weight(1f)
Expand All @@ -261,12 +255,12 @@ fun SvgExportDialog(
.clip(ContinuousCapsule)
.background(color)
.clickable {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "image/svg+xml"
putExtra(Intent.EXTRA_TITLE, "continuous_rounded_rect.svg")
}
createFileLauncher.launch(intent)
// val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
// addCategory(Intent.CATEGORY_OPENABLE)
// type = "image/svg+xml"
// putExtra(Intent.EXTRA_TITLE, "continuous_rounded_rect.svg")
// }
// createFileLauncher.launch(intent)
}
.height(48.dp)
.weight(1f)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.kyant.capsule.demo

import androidx.compose.ui.window.ComposeUIViewController

fun MainViewController() = ComposeUIViewController { MainContent() }
13 changes: 13 additions & 0 deletions app/src/jvmMain/kotlin/com/kyant/capsule/demo/main.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.kyant.capsule.demo

import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application

fun main() = application {
Window(
onCloseRequest = ::exitApplication,
title = "MyApplication",
) {
MainContent()
}
}
11 changes: 11 additions & 0 deletions app/src/webMain/kotlin/com/kyant/capsule/demo/main.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.kyant.capsule.demo

import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.window.ComposeViewport

@OptIn(ExperimentalComposeUiApi::class)
fun main() {
ComposeViewport {
MainContent()
}
}
12 changes: 12 additions & 0 deletions app/src/webMain/resources/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KotlinProject</title>
<link type="text/css" rel="stylesheet" href="styles.css">
<script type="application/javascript" src="app.js"></script>
</head>
<body>
</body>
</html>
7 changes: 7 additions & 0 deletions app/src/webMain/resources/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
Loading