diff --git a/composeApp/src/wasmJsMain/kotlin/App.kt b/composeApp/src/wasmJsMain/kotlin/App.kt index 4f4b5cd..621da9c 100644 --- a/composeApp/src/wasmJsMain/kotlin/App.kt +++ b/composeApp/src/wasmJsMain/kotlin/App.kt @@ -1,6 +1,7 @@ import LangType.* import androidx.compose.foundation.* import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.ClickableText import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ContentCopy @@ -9,9 +10,13 @@ import androidx.compose.material.icons.filled.LightMode import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalUriHandler +import androidx.compose.ui.state.ToggleableState +import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.em import kotlinx.browser.localStorage @@ -21,6 +26,7 @@ import org.jetbrains.compose.resources.Font import org.jetbrains.compose.resources.FontResource const val SNAPSHOT_REPO = "https://s01.oss.sonatype.org/content/repositories/snapshots/" +const val WIKI_ARCH_LINK = "https://github.com/Over-Run/overrungl/wiki/Installing-Natives#supported-architectures" @Composable fun App() { @@ -65,42 +71,55 @@ private fun Customizer() { val JetBrainsMono = FontFamily( Font(FontResource("jetbrainsmono_regular.ttf"), weight = FontWeight.Normal) ) - val (langType, setLangType) = remember { + var langType by remember { mutableStateOf( langTypeFromString(localStorage.getItem("langType")) ?: GRADLE_KOTLIN ) } val selectedModules = remember { - mutableStateListOf().also { + mutableStateMapOf().also { val item = localStorage.getItem("selectedModules") - if (item != null) { - item.let { s -> + val initModules = + item?.let { s -> s.split(',').mapNotNull { m -> bindingFromString(m) } - }.let(it::addAll) - } else { - it.add(Binding.CORE) - } + } ?: emptyList() + Binding.entries.forEach { m -> it[m] = initModules.contains(m) } + it[Binding.CORE] = true + } + } + val selectedNatives = remember { + mutableStateListOf().also { + localStorage.getItem("selectedNatives")?.let { s -> + s.split(',').mapNotNull { n -> nativeFromString(n) } + }?.let(it::addAll) } } val release by remember { mutableStateOf(false) } var joml by remember { mutableStateOf(localStorage.getItem("joml").toBoolean()) } var noVariable by remember { mutableStateOf(localStorage.getItem("noVariable").toBoolean()) } + fun storeSelectedNatives() { + localStorage.setItem( + "selectedNatives", + selectedNatives.joinToString(separator = ",") { m -> m.name }) + } + fun generateCode(): String = generatedCode( langType = langType, release = release, modules = selectedModules, joml = joml, noVariable = noVariable, - version = "$V_LATEST_SNAPSHOT-SNAPSHOT" + version = "$V_LATEST_SNAPSHOT-SNAPSHOT", + natives = selectedNatives ) Column(modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) { // disclaimer - Text( + /*Text( "Disclaimer: this customizer uses experimental features and might occur errors when any key is pressed", fontWeight = FontWeight.Bold - ) + )*/ // select the build type Row { @@ -120,7 +139,10 @@ private fun Customizer() { border = BorderStroke(width = 2.dp, color = MaterialTheme.colors.onSurface) ) { Column { - Row(modifier = Modifier.fillMaxWidth().padding(all = 16.dp)) { + Row( + modifier = Modifier.fillMaxWidth() + .padding(start = 16.dp, top = 16.dp, end = 16.dp, bottom = 8.dp) + ) { @Composable inline fun optionTitle(text: String) { Text( @@ -144,9 +166,64 @@ private fun Customizer() { // natives optionTitle("Natives") + Row(verticalAlignment = Alignment.CenterVertically) { + TriStateCheckbox( + state = if (selectedNatives.isEmpty()) ToggleableState.Off + else if (selectedNatives.size == Native.entries.size) ToggleableState.On + else ToggleableState.Indeterminate, + onClick = { + val size = selectedNatives.size + selectedNatives.clear() + if (size != Native.entries.size) { + selectedNatives.addAll(Native.entries) + } + storeSelectedNatives() + }) + Text("Select/unselect all") + } + Native.entries.forEach { native -> + Row(verticalAlignment = Alignment.CenterVertically) { + Checkbox( + checked = selectedNatives.contains(native), + onCheckedChange = { + if (it) { + selectedNatives.add(native) + } else { + selectedNatives.remove(native) + } + storeSelectedNatives() + } + ) + if (native.macos) { + Icon(Icons.Filled.Apple, contentDescription = null) + } else if (native.linux) { + Icon(Icons.Filled.Linux, contentDescription = null) + } else if (native.windows) { + Icon(Icons.Filled.Microsoft, contentDescription = null) + } + Text(native.description) + } + } + val uriHandler = LocalUriHandler.current + ClickableText( + AnnotatedString( + "Check supported architecture for each module here", + spanStyle = MaterialTheme.typography.button.toSpanStyle() + .copy(textDecoration = TextDecoration.Underline) + ), onClick = { + uriHandler.openUri(WIKI_ARCH_LINK) + } + ) } Column(modifier = Modifier.padding(horizontal = 80.dp)) { + // presets + optionTitle("Presets") + Row(verticalAlignment = Alignment.CenterVertically) { + RadioButton(selected = true, onClick = null, modifier = Modifier.padding(start = 14.dp)) + Text("Custom") + } + // addons optionTitle("Addons") Row(verticalAlignment = Alignment.CenterVertically) { @@ -167,17 +244,13 @@ private fun Customizer() { Binding.entries.forEach { module -> Row(verticalAlignment = Alignment.CenterVertically) { Checkbox( - checked = if (module.nonSelectable) true else selectedModules.contains(module), + checked = if (module.nonSelectable) true else selectedModules[module] ?: false, enabled = !module.nonSelectable, onCheckedChange = { - if (it) { - selectedModules.add(module) - } else { - selectedModules.remove(module) - } + selectedModules[module] = it localStorage.setItem( "selectedModules", - selectedModules.joinToString(separator = ",") { m -> m.name }) + selectedModules.filterValues { b -> b }.keys.joinToString(separator = ",") { m -> m.name }) }) Text(module.moduleName) } @@ -186,48 +259,57 @@ private fun Customizer() { } // generated code - Column(modifier = Modifier.padding(all = 16.dp)) { + Column(modifier = Modifier.padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 16.dp)) { Row { - langTypeButton(GRADLE_KOTLIN, setLangType) - langTypeButton(GRADLE_GROOVY, setLangType) - langTypeButton(GRADLE_CATALOG, setLangType) - langTypeButton(MAVEN, setLangType) - langTypeButton(VM_OPTION, setLangType) - langTypeButton(MANIFEST_ATTRIB, setLangType) - } - Column { - when (langType) { - GRADLE_CATALOG -> { - Text( - "The Gradle version catalog does NOT support classifier. You have to add the native libraries by yourself.", - fontWeight = FontWeight.Bold - ) + @Composable + fun langTypeButton(buttonLangType: LangType) { + OutlinedButton( + onClick = { + langType = buttonLangType + localStorage.setItem("langType", buttonLangType.name) + }, + modifier = if (buttonLangType == langType) Modifier.offset(y = 8.dp) else Modifier + ) { + Text(buttonLangType.typeName) } - - VM_OPTION -> { - Text("Add this VM option to allow OverrunGL to call restricted methods. You might need to add the module name of your application to it.") - } - - MANIFEST_ATTRIB -> { - Text("Add this attribute to META-INF/MANIFEST.MF to allow code in executable JAR files to call restricted methods.") - } - - else -> {} } - - Surface( - modifier = Modifier.fillMaxWidth(), - border = ButtonDefaults.outlinedBorder - ) { + langTypeButton(GRADLE_KOTLIN) + langTypeButton(GRADLE_GROOVY) + langTypeButton(GRADLE_CATALOG) + langTypeButton(MAVEN) + langTypeButton(VM_OPTION) + langTypeButton(MANIFEST_ATTRIB) + } + Surface( + modifier = Modifier.fillMaxWidth(), + border = ButtonDefaults.outlinedBorder + ) { // SelectionContainer { + Text( + generateCode(), + modifier = Modifier.padding(4.dp), + fontFamily = JetBrainsMono + ) +// } + } + when (langType) { + GRADLE_CATALOG -> { Text( - generateCode(), - modifier = Modifier.padding(2.dp), - fontFamily = JetBrainsMono + "The Gradle version catalog does NOT support classifier. You have to add the native libraries by yourself.", + fontWeight = FontWeight.Bold ) -// } } + + VM_OPTION -> { + Text("Add this VM option to allow OverrunGL to call restricted methods. You might need to add the module name of your application to it.") + } + + MANIFEST_ATTRIB -> { + Text("Add this attribute to META-INF/MANIFEST.MF to allow code in executable JAR files to call restricted methods.") + } + + else -> {} } Button(onClick = { window.navigator.clipboard.writeText(generateCode()) @@ -245,38 +327,114 @@ private fun Customizer() { fun generatedCode( langType: LangType, release: Boolean, - modules: List, + modules: Map, joml: Boolean, noVariable: Boolean, - version: String + version: String, + natives: List ): String = buildString { + val selectedModules = Binding.entries.filter { modules[it] ?: false } + val linuxList = natives.filter { it.linux } + val macosList = natives.filter { it.macos } + val windowsList = natives.filter { it.windows } + fun StringBuilder.gradleDependencies() { appendLine("dependencies {") - appendLine(" implementation(platform(\"io.github.over-run:overrungl-bom:${if (noVariable) version else "\$overrunglVersion"}\"))") - modules.forEach { - appendLine(" implementation(\"io.github.over-run:${it.artifactName}\")") + appendLine(""" implementation(platform("io.github.over-run:overrungl-bom:${if (noVariable) version else "\$overrunglVersion"}"))""") + selectedModules.forEach { + appendLine(""" implementation("io.github.over-run:${it.artifactName}")""") + } + selectedModules.filter { it.requireNative }.forEach { + appendLine( + """ runtimeOnly("io.github.over-run:${it.artifactName}::${ + if (!noVariable || natives.size > 1) "\$overrunglNatives" + else if (natives.isNotEmpty()) natives[0].classifierName + else "" + }")""" + ) } if (joml) { - appendLine(" implementation(\"io.github.over-run:overrungl-joml\")") - appendLine(" implementation(\"org.joml:joml:${if (noVariable) V_JOML else "\$jomlVersion"}\")") + appendLine(""" implementation("io.github.over-run:overrungl-joml")""") + appendLine(""" implementation("org.joml:joml:${if (noVariable) V_JOML else "\$jomlVersion"}")""") } append("}") } when (langType) { GRADLE_GROOVY -> { + if (natives.size > 1) { + appendLine("import org.gradle.internal.os.OperatingSystem") + appendLine() + } + if (!noVariable) { - appendLine("project.ext.overrunglVersion = \"$version\"") - if (joml) { - appendLine("project.ext.jomlVersion = \"$V_JOML\"") + appendLine("""project.ext.overrunglVersion = "$version"""") + } + + if (!noVariable && natives.size == 1) { + appendLine("""project.ext.overrunglNatives = "${natives[0].classifierName}"""") + } else if (natives.size > 1) { + appendLine("switch (OperatingSystem.current()) {") + if (linuxList.isNotEmpty()) { + appendLine(" case OperatingSystem.LINUX:") + if (linuxList.size == 1) { + appendLine(""" project.ext.overrunglNatives = "${linuxList[0].classifierName}"""") + } else { + appendLine( + """ + | def osArch = System.getProperty("os.arch") + | project.ext.overrunglNatives = osArch.startsWith("arm") || osArch.startsWith("aarch64") + | ? ((osArch.contains("64") || osArch.startsWith("armv8")) + | ? "${Native.LINUX_ARM64.classifierName}" + | : "${Native.LINUX_ARM32.classifierName}") + | : "${Native.LINUX_X64.classifierName}" + """.trimMargin() + ) + } + appendLine(" break") + } + if (macosList.isNotEmpty()) { + appendLine(" case OperatingSystem.MAC_OS:") + if (macosList.size == 1) { + appendLine(""" project.ext.overrunglNatives = "${macosList[0].classifierName}"""") + } else { + appendLine( + """ + | project.ext.overrunglNatives = System.getProperty("os.arch").startsWith("aarch64") ? "${Native.MACOS_ARM64.classifierName}" : "${Native.MACOS_X64.classifierName}" + """.trimMargin() + ) + } + appendLine(" break") + } + if (windowsList.isNotEmpty()) { + appendLine(" case OperatingSystem.WINDOWS:") + if (windowsList.size == 1) { + appendLine(""" project.ext.overrunglNatives = "${windowsList[0].classifierName}"""") + } else { + appendLine( + """ + | def osArch = System.getProperty("os.arch") + | if (osArch.contains("64")) + | project.ext.overrunglNatives = osArch.startsWith("aarch64") ? "${Native.WINDOWS_ARM64.classifierName}" : "${Native.WINDOWS_X64.classifierName}" + """.trimMargin() + ) + } + appendLine(" break") } + appendLine("}") + } + + if (!noVariable && joml) { + appendLine("""project.ext.jomlVersion = "$V_JOML"""") + } + if (!noVariable || natives.size > 1) { appendLine() } appendLine("repositories {") appendLine(" mavenCentral()") if (!release) { - appendLine(" maven { url \"$SNAPSHOT_REPO\" }") + appendLine(""" maven { url "$SNAPSHOT_REPO" }""") } appendLine("}") appendLine() @@ -286,17 +444,77 @@ fun generatedCode( GRADLE_KOTLIN -> { if (!noVariable) { - appendLine("val overrunglVersion = \"$version\"") - if (joml) { - appendLine("val jomlVersion = \"$V_JOML\"") + appendLine("""val overrunglVersion = "$version"""") + } + + if (!noVariable && natives.size == 1) { + appendLine("""val overrunglNatives = "${natives[0].classifierName}"""") + } else if (natives.size > 1) { + appendLine( + """ + val overrunglNatives = Pair( + System.getProperty("os.name")!!, + System.getProperty("os.arch")!! + ).let { (name, arch) -> + when { + """.trimIndent() + ) + if (linuxList.isNotEmpty()) { + appendLine(""" arrayOf("Linux", "FreeBSD", "SunOS", "Unit").any { name.startsWith(it) } ->""") + if (linuxList.size == 1) { + appendLine(""" "${linuxList[0].classifierName}"""") + } else { + appendLine( + """ + | if (arrayOf("arm", "aarch64").any { arch.startsWith(it) }) + | if (arch.contains("64") || arch.startsWith("armv8")) "${Native.LINUX_ARM64.classifierName}" else "${Native.LINUX_ARM32.classifierName}" + | else "${Native.LINUX_X64.classifierName}" + """.trimMargin() + ) + } } + if (macosList.isNotEmpty()) { + appendLine(""" arrayOf("Mac OS X", "Darwin").any { name.startsWith(it) } ->""") + if (macosList.size == 1) { + appendLine(""" "${macosList[0].classifierName}"""") + } else { + appendLine(""" if (arch.startsWith("aarch64")) "${Native.MACOS_ARM64.classifierName}" else "${Native.MACOS_X64.classifierName}"""") + } + } + if (windowsList.isNotEmpty()) { + appendLine(""" arrayOf("Windows").any { name.startsWith(it) } ->""") + if (windowsList.size == 1) { + appendLine(""" "${windowsList[0].classifierName}"""") + } else { + appendLine( + """ + | if (arch.contains("64")) + | if (arch.startsWith("aarch64")) "${Native.WINDOWS_ARM64.classifierName}" else "${Native.WINDOWS_X64.classifierName}" + | else throw Error("Unrecognized or unsupported architecture. Please set \"overrunglNatives\" manually") + """.trimMargin() + ) + } + } + appendLine( + """ + | else -> throw Error("Unrecognized or unsupported platform. Please set \"overrunglNatives\" manually") + | } + |} + """.trimMargin() + ) + } + + if (!noVariable && joml) { + appendLine("""val jomlVersion = "$V_JOML"""") + } + if (!noVariable || natives.size > 1) { appendLine() } appendLine("repositories {") appendLine(" mavenCentral()") if (!release) { - appendLine(" maven(\"$SNAPSHOT_REPO\")") + appendLine(""" maven("$SNAPSHOT_REPO")""") } appendLine("}") appendLine() @@ -306,19 +524,19 @@ fun generatedCode( GRADLE_CATALOG -> { appendLine("[versions]") - appendLine("overrungl = \"$version\"") + appendLine("""overrungl = "$version"""") if (joml && !noVariable) { - appendLine("joml = \"$V_JOML\"") + appendLine("""joml = "$V_JOML"""") } appendLine() appendLine("[libraries]") - modules.forEach { - appendLine("${it.catalogName} = { module = \"io.github.over-run:${it.artifactName}\", version.ref = \"overrungl\" }") + selectedModules.forEach { + appendLine("""${it.catalogName} = { module = "io.github.over-run:${it.artifactName}", version.ref = "overrungl" }""") } if (joml) { - appendLine("overrungl-joml = { module = \"io.github.over-run:overrungl-joml\", version.ref = \"overrungl\" }") - appendLine("joml = { module = \"org.joml:joml\", version${if (noVariable) " = \"$V_JOML\"" else ".ref = \"joml\""} }") + appendLine("""overrungl-joml = { module = "io.github.over-run:overrungl-joml", version.ref = "overrungl" }""") + appendLine("""joml = { module = "org.joml:joml", version${if (noVariable) """ = "$V_JOML"""" else """.ref = "joml""""} }""") } appendLine() @@ -326,9 +544,9 @@ fun generatedCode( append( "overrungl = [${ buildString { - append(modules.joinToString { "\"${it.catalogName}\"" }) + append(selectedModules.joinToString { """"${it.catalogName}"""" }) if (joml) { - append(", \"overrungl-joml\", \"joml\"") + append(""", "overrungl-joml", "joml"""") } } }]" @@ -382,7 +600,7 @@ fun generatedCode( ) appendLine("") - modules.forEach { + selectedModules.forEach { appendLine( """ | @@ -408,7 +626,7 @@ fun generatedCode( VM_OPTION -> { append("--enable-native-access=io.github.overrun.marshal") - append(modules.joinToString(separator = ",", prefix = ",") { it.javaModuleName }) + append(selectedModules.joinToString(separator = ",", prefix = ",") { it.javaModuleName }) } MANIFEST_ATTRIB -> { @@ -416,13 +634,3 @@ fun generatedCode( } } } - -@Composable -fun langTypeButton(langType: LangType, setLangType: (LangType) -> Unit) { - OutlinedButton(onClick = { - setLangType(langType) - localStorage.setItem("langType", langType.name) - }) { - Text(langType.typeName) - } -} diff --git a/composeApp/src/wasmJsMain/kotlin/Binding.kt b/composeApp/src/wasmJsMain/kotlin/Binding.kt index 446129c..c329173 100644 --- a/composeApp/src/wasmJsMain/kotlin/Binding.kt +++ b/composeApp/src/wasmJsMain/kotlin/Binding.kt @@ -7,13 +7,14 @@ enum class Binding( val artifactName: String, val javaModuleName: String, val catalogName: String, - val nonSelectable: Boolean = false + val nonSelectable: Boolean = false, + val requireNative: Boolean = false ) { CORE("OverrunGL Core", "overrungl", "overrungl.core", "overrungl-core", nonSelectable = true), - GLFW("GLFW", "overrungl-glfw", "overrungl.glfw", "overrungl-glfw"), - NFD("Native File Dialog", "overrungl-nfd", "overrungl.nfd", "overrungl-nfd"), + GLFW("GLFW", "overrungl-glfw", "overrungl.glfw", "overrungl-glfw", requireNative = true), + NFD("Native File Dialog", "overrungl-nfd", "overrungl.nfd", "overrungl-nfd", requireNative = true), OPENGL("OpenGL", "overrungl-opengl", "overrungl.opengl", "overrungl-opengl"), - STB("stb", "overrungl-stb", "overrungl.stb", "overrungl-stb"), + STB("stb", "overrungl-stb", "overrungl.stb", "overrungl-stb", requireNative = true), } fun bindingFromString(name: String?): Binding? = name?.let { diff --git a/composeApp/src/wasmJsMain/kotlin/MyIcons.kt b/composeApp/src/wasmJsMain/kotlin/MyIcons.kt new file mode 100644 index 0000000..94f5d9c --- /dev/null +++ b/composeApp/src/wasmJsMain/kotlin/MyIcons.kt @@ -0,0 +1,294 @@ +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.materialIcon +import androidx.compose.material.icons.materialPath +import androidx.compose.ui.graphics.vector.ImageVector + +const val LINUX_ICON_WIDTH = 24f / 448.0f +const val LINUX_ICON_HEIGHT = 24f / 512.0f + +val Icons.Filled.Apple: ImageVector + get() { + if (_apple != null) { + return _apple!! + } + _apple = materialIcon(name = "Filled.Apple") { + materialPath { + moveTo(18.71f, 19.5f) + curveToRelative(-.83f, 1.24f, -1.71f, 2.45f, -3.05f, 2.47f) + curveToRelative(-1.34f, .03f, -1.77f, -.79f, -3.29f, -.79f) + curveToRelative(-1.53f, 0f, -2f, .77f, -3.27f, .82f) + curveToRelative(-1.31f, .05f, -2.3f, -1.32f, -3.14f, -2.53f) + curveTo(4.25f, 17f, 2.94f, 12.45f, 4.7f, 9.39f) + curveToRelative(.87f, -1.52f, 2.43f, -2.48f, 4.12f, -2.51f) + curveToRelative(1.28f, -.02f, 2.5f, .87f, 3.29f, .87f) + curveToRelative(.78f, 0f, 2.26f, -1.07f, 3.81f, -.91f) + curveToRelative(.65f, .03f, 2.47f, .26f, 3.64f, 1.98f) + curveToRelative(-.09f, .06f, -2.17f, 1.28f, -2.15f, 3.81f) + curveToRelative(.03f, 3.02f, 2.65f, 4.03f, 2.68f, 4.04f) + curveToRelative(-.03f, .07f, -.42f, 1.44f, -1.38f, 2.83f) + moveTo(13f, 3.5f) + curveToRelative(.73f, -.83f, 1.94f, -1.46f, 2.94f, -1.5f) + curveToRelative(.13f, 1.17f, -.34f, 2.35f, -1.04f, 3.19f) + curveToRelative(-.69f, .85f, -1.83f, 1.51f, -2.95f, 1.42f) + curveToRelative(-.15f, -1.15f, .41f, -2.35f, 1.05f, -3.11f) + close() + } + } + return _apple!! + } + +val Icons.Filled.Linux: ImageVector + get() { + if (_linux != null) { + return _linux!! + } + _linux = materialIcon(name = "Filled.Linux") { + materialPath { + fun moveTo(x: Float, y: Float) { + this.moveTo(x * LINUX_ICON_WIDTH, y * LINUX_ICON_HEIGHT) + } + + fun moveToRelative(dx: Float, dy: Float) { + this.moveToRelative(dx * LINUX_ICON_WIDTH, dy * LINUX_ICON_HEIGHT) + } + + fun curveTo(x1: Float, y1: Float, x2: Float, y2: Float, x3: Float, y3: Float) { + this.curveTo( + x1 * LINUX_ICON_WIDTH, + y1 * LINUX_ICON_HEIGHT, + x2 * LINUX_ICON_WIDTH, + y2 * LINUX_ICON_HEIGHT, + x3 * LINUX_ICON_WIDTH, + y3 * LINUX_ICON_HEIGHT + ) + } + + fun curveToRelative(dx1: Float, dy1: Float, dx2: Float, dy2: Float, dx3: Float, dy3: Float) { + this.curveToRelative( + dx1 * LINUX_ICON_WIDTH, + dy1 * LINUX_ICON_HEIGHT, + dx2 * LINUX_ICON_WIDTH, + dy2 * LINUX_ICON_HEIGHT, + dx3 * LINUX_ICON_WIDTH, + dy3 * LINUX_ICON_HEIGHT + ) + } + + fun reflectiveCurveToRelative(dx1: Float, dy1: Float, dx2: Float, dy2: Float) { + this.reflectiveCurveToRelative( + dx1 * LINUX_ICON_WIDTH, + dy1 * LINUX_ICON_HEIGHT, + dx2 * LINUX_ICON_WIDTH, + dy2 * LINUX_ICON_HEIGHT + ) + } + + fun verticalLineToRelative(dy: Float) { + this.verticalLineToRelative(dy * LINUX_ICON_HEIGHT) + } + + fun lineToRelative(dx: Float, dy: Float) { + this.lineToRelative(dx * LINUX_ICON_HEIGHT, dy * LINUX_ICON_WIDTH) + } + + + //M220.8 123.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm-21.9 1.7c1.2 0 2-1.2 3-1.7 1.1-.6 3.1-.4 3.5-1.6.2-.4-.2-.9-.6-1.1-1.6-.9-3.8-.6-5.5.1-1.3.6-3.4 1.5-3.2 2.9.1 1 1.8 1.5 2.8 1.4zM420 403.8c-3.6-4-5.3-11.6-7.2-19.7-1.8-8.1-3.9-16.8-10.5-22.4-1.3-1.1-2.6-2.1-4-2.9-1.3-.8-2.7-1.5-4.1-2 9.2-27.3 5.6-54.5-3.7-79.1-11.4-30.1-31.3-56.4-46.5-74.4-17.1-21.5-33.7-41.9-33.4-72C311.1 85.4 315.7.1 234.8 0 132.4-.2 158 103.4 156.9 135.2c-1.7 23.4-6.4 41.8-22.5 64.7-18.9 22.5-45.5 58.8-58.1 96.7-6 17.9-8.8 36.1-6.2 53.3-6.5 5.8-11.4 14.7-16.6 20.2-4.2 4.3-10.3 5.9-17 8.3s-14 6-18.5 14.5c-2.1 3.9-2.8 8.1-2.8 12.4 0 3.9.6 7.9 1.2 11.8 1.2 8.1 2.5 15.7.8 20.8-5.2 14.4-5.9 24.4-2.2 31.7 3.8 7.3 11.4 10.5 20.1 12.3 17.3 3.6 40.8 2.7 59.3 12.5 19.8 10.4 39.9 14.1 55.9 10.4 11.6-2.6 21.1-9.6 25.9-20.2 12.5-.1 26.3-5.4 48.3-6.6 14.9-1.2 33.6 5.3 55.1 4.1.6 2.3 1.4 4.6 2.5 6.7v.1c8.3 16.7 23.8 24.3 40.3 23 16.6-1.3 34.1-11 48.3-27.9 13.6-16.4 36-23.2 50.9-32.2 7.4-4.5 13.4-10.1 13.9-18.3.4-8.2-4.4-17.3-15.5-29.7zM223.7 87.3c9.8-22.2 34.2-21.8 44-.4 6.5 14.2 3.6 30.9-4.3 40.4-1.6-.8-5.9-2.6-12.6-4.9 1.1-1.2 3.1-2.7 3.9-4.6 4.8-11.8-.2-27-9.1-27.3-7.3-.5-13.9 10.8-11.8 23-4.1-2-9.4-3.5-13-4.4-1-6.9-.3-14.6 2.9-21.8zM183 75.8c10.1 0 20.8 14.2 19.1 33.5-3.5 1-7.1 2.5-10.2 4.6 1.2-8.9-3.3-20.1-9.6-19.6-8.4.7-9.8 21.2-1.8 28.1 1 .8 1.9-.2-5.9 5.5-15.6-14.6-10.5-52.1 8.4-52.1zm-13.6 60.7c6.2-4.6 13.6-10 14.1-10.5 4.7-4.4 13.5-14.2 27.9-14.2 7.1 0 15.6 2.3 25.9 8.9 6.3 4.1 11.3 4.4 22.6 9.3 8.4 3.5 13.7 9.7 10.5 18.2-2.6 7.1-11 14.4-22.7 18.1-11.1 3.6-19.8 16-38.2 14.9-3.9-.2-7-1-9.6-2.1-8-3.5-12.2-10.4-20-15-8.6-4.8-13.2-10.4-14.7-15.3-1.4-4.9 0-9 4.2-12.3zm3.3 334c-2.7 35.1-43.9 34.4-75.3 18-29.9-15.8-68.6-6.5-76.5-21.9-2.4-4.7-2.4-12.7 2.6-26.4v-.2c2.4-7.6.6-16-.6-23.9-1.2-7.8-1.8-15 .9-20 3.5-6.7 8.5-9.1 14.8-11.3 10.3-3.7 11.8-3.4 19.6-9.9 5.5-5.7 9.5-12.9 14.3-18 5.1-5.5 10-8.1 17.7-6.9 8.1 1.2 15.1 6.8 21.9 16l19.6 35.6c9.5 19.9 43.1 48.4 41 68.9zm-1.4-25.9c-4.1-6.6-9.6-13.6-14.4-19.6 7.1 0 14.2-2.2 16.7-8.9 2.3-6.2 0-14.9-7.4-24.9-13.5-18.2-38.3-32.5-38.3-32.5-13.5-8.4-21.1-18.7-24.6-29.9s-3-23.3-.3-35.2c5.2-22.9 18.6-45.2 27.2-59.2 2.3-1.7.8 3.2-8.7 20.8-8.5 16.1-24.4 53.3-2.6 82.4.6-20.7 5.5-41.8 13.8-61.5 12-27.4 37.3-74.9 39.3-112.7 1.1.8 4.6 3.2 6.2 4.1 4.6 2.7 8.1 6.7 12.6 10.3 12.4 10 28.5 9.2 42.4 1.2 6.2-3.5 11.2-7.5 15.9-9 9.9-3.1 17.8-8.6 22.3-15 7.7 30.4 25.7 74.3 37.2 95.7 6.1 11.4 18.3 35.5 23.6 64.6 3.3-.1 7 .4 10.9 1.4 13.8-35.7-11.7-74.2-23.3-84.9-4.7-4.6-4.9-6.6-2.6-6.5 12.6 11.2 29.2 33.7 35.2 59 2.8 11.6 3.3 23.7.4 35.7 16.4 6.8 35.9 17.9 30.7 34.8-2.2-.1-3.2 0-4.2 0 3.2-10.1-3.9-17.6-22.8-26.1-19.6-8.6-36-8.6-38.3 12.5-12.1 4.2-18.3 14.7-21.4 27.3-2.8 11.2-3.6 24.7-4.4 39.9-.5 7.7-3.6 18-6.8 29-32.1 22.9-76.7 32.9-114.3 7.2zm257.4-11.5c-.9 16.8-41.2 19.9-63.2 46.5-13.2 15.7-29.4 24.4-43.6 25.5s-26.5-4.8-33.7-19.3c-4.7-11.1-2.4-23.1 1.1-36.3 3.7-14.2 9.2-28.8 9.9-40.6.8-15.2 1.7-28.5 4.2-38.7 2.6-10.3 6.6-17.2 13.7-21.1.3-.2.7-.3 1-.5.8 13.2 7.3 26.6 18.8 29.5 12.6 3.3 30.7-7.5 38.4-16.3 9-.3 15.7-.9 22.6 5.1 9.9 8.5 7.1 30.3 17.1 41.6 10.6 11.6 14 19.5 13.7 24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4s5.9-6.3 3.1-6.6-2.6 2.6-6 5.1c-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2s-18.7-4.8-24.9-9.7c-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z + moveTo(220.8f, 123.3f) + curveToRelative(1f, .5f, 1.8f, 1.7f, 3f, 1.7f) + curveToRelative(1.1f, 0f, 2.8f, -.4f, 2.9f, -1.5f) + curveToRelative(.2f, -1.4f, -1.9f, -2.3f, -3.2f, -2.9f) + curveToRelative(-1.7f, -.7f, -3.9f, -1f, -5.5f, -.1f) + curveToRelative(-.4f, .2f, -.8f, .7f, -.6f, 1.1f) + curveToRelative(.3f, 1.3f, 2.3f, 1.1f, 3.4f, 1.7f) + close() + moveToRelative(-21.9f, 1.7f) + curveToRelative(1.2f, 0f, 2f, -1.2f, 3f, -1.7f) + curveToRelative(1.1f, -.6f, 3.1f, -.4f, 3.5f, -1.6f) + curveToRelative(.2f, -.4f, -.2f, -.9f, -.6f, -1.1f) + curveToRelative(-1.6f, -.9f, -3.8f, -.6f, -5.5f, .1f) + curveToRelative(-1.3f, .6f, -3.4f, 1.5f, -3.2f, 2.9f) + curveToRelative(.1f, 1f, 1.8f, 1.5f, 2.8f, 1.4f) + close() + moveTo(420f, 403.8f) + curveToRelative(-3.6f, -4f, -5.3f, -11.6f, -7.2f, -19.7f) + curveToRelative(-1.8f, -8.1f, -3.9f, -16.8f, -10.5f, -22.4f) + curveToRelative(-1.3f, -1.1f, -2.6f, -2.1f, -4f, -2.9f) + curveToRelative(-1.3f, -.8f, -2.7f, -1.5f, -4.1f, -2f) + curveToRelative(9.2f, -27.3f, 5.6f, -54.5f, -3.7f, -79.1f) + curveToRelative(-11.4f, -30.1f, -31.3f, -56.4f, -46.5f, -74.4f) + curveToRelative(-17.1f, -21.5f, -33.7f, -41.9f, -33.4f, -72f) + curveTo(311.1f, 85.4f, 315.7f, .1f, 234.8f, 0f) + curveTo(132.4f, -.2f, 158f, 103.4f, 156.9f, 135.2f) + curveToRelative(-1.7f, 23.4f, -6.4f, 41.8f, -22.5f, 64.7f) + curveToRelative(-18.9f, 22.5f, -45.5f, 58.8f, -58.1f, 96.7f) + curveToRelative(-6f, 17.9f, -8.8f, 36.1f, -6.2f, 53.3f) + curveToRelative(-6.5f, 5.8f, -11.4f, 14.7f, -16.6f, 20.2f) + curveToRelative(-4.2f, 4.3f, -10.3f, 5.9f, -17f, 8.3f) + reflectiveCurveToRelative(-14f, 6f, -18.5f, 14.5f) + curveToRelative(-2.1f, 3.9f, -2.8f, 8.1f, -2.8f, 12.4f) + curveToRelative(0f, 3.9f, .6f, 7.9f, 1.2f, 11.8f) + curveToRelative(1.2f, 8.1f, 2.5f, 15.7f, .8f, 20.8f) + curveToRelative(-5.2f, 14.4f, -5.9f, 24.4f, -2.2f, 31.7f) + curveToRelative(3.8f, 7.3f, 11.4f, 10.5f, 20.1f, 12.3f) + curveToRelative(17.3f, 3.6f, 40.8f, 2.7f, 59.3f, 12.5f) + curveToRelative(19.8f, 10.4f, 39.9f, 14.1f, 55.9f, 10.4f) + curveToRelative(11.6f, -2.6f, 21.1f, -9.6f, 25.9f, -20.2f) + curveToRelative(12.5f, -.1f, 26.3f, -5.4f, 48.3f, -6.6f) + curveToRelative(14.9f, -1.2f, 33.6f, 5.3f, 55.1f, 4.1f) + curveToRelative(.6f, 2.3f, 1.4f, 4.6f, 2.5f, 6.7f) + verticalLineToRelative(.1f) + curveToRelative(8.3f, 16.7f, 23.8f, 24.3f, 40.3f, 23f) + curveToRelative(16.6f, -1.3f, 34.1f, -11f, 48.3f, -27.9f) + curveToRelative(13.6f, -16.4f, 36f, -23.2f, 50.9f, -32.2f) + curveToRelative(7.4f, -4.5f, 13.4f, -10.1f, 13.9f, -18.3f) + curveToRelative(.4f, -8.2f, -4.4f, -17.3f, -15.5f, -29.7f) + close() + moveTo(223.7f, 87.3f) + curveToRelative(9.8f, -22.2f, 34.2f, -21.8f, 44f, -.4f) + curveToRelative(6.5f, 14.2f, 3.6f, 30.9f, -4.3f, 40.4f) + curveToRelative(-1.6f, -.8f, -5.9f, -2.6f, -12.6f, -4.9f) + curveToRelative(1.1f, -1.2f, 3.1f, -2.7f, 3.9f, -4.6f) + curveToRelative(4.8f, -11.8f, -.2f, -27f, -9.1f, -27.3f) + curveToRelative(-7.3f, -.5f, -13.9f, 10.8f, -11.8f, 23f) + curveToRelative(-4.1f, -2f, -9.4f, -3.5f, -13f, -4.4f) + curveToRelative(-1f, -6.9f, -.3f, -14.6f, 2.9f, -21.8f) + close() + moveTo(183f, 75.8f) + curveToRelative(10.1f, 0f, 20.8f, 14.2f, 19.1f, 33.5f) + curveToRelative(-3.5f, 1f, -7.1f, 2.5f, -10.2f, 4.6f) + curveToRelative(1.2f, -8.9f, -3.3f, -20.1f, -9.6f, -19.6f) + curveToRelative(-8.4f, .7f, -9.8f, 21.2f, -1.8f, 28.1f) + curveToRelative(1f, .8f, 1.9f, -.2f, -5.9f, 5.5f) + curveToRelative(-15.6f, -14.6f, -10.5f, -52.1f, 8.4f, -52.1f) + close() + moveToRelative(-13.6f, 60.7f) + curveToRelative(6.2f, -4.6f, 13.6f, -10f, 14.1f, -10.5f) + curveToRelative(4.7f, -4.4f, 13.5f, -14.2f, 27.9f, -14.2f) + curveToRelative(7.1f, 0f, 15.6f, 2.3f, 25.9f, 8.9f) + curveToRelative(6.3f, 4.1f, 11.3f, 4.4f, 22.6f, 9.3f) + curveToRelative(8.4f, 3.5f, 13.7f, 9.7f, 10.5f, 18.2f) + curveToRelative(-2.6f, 7.1f, -11f, 14.4f, -22.7f, 18.1f) + curveToRelative(-11.1f, 3.6f, -19.8f, 16f, -38.2f, 14.9f) + curveToRelative(-3.9f, -.2f, -7f, -1f, -9.6f, -2.1f) + curveToRelative(-8f, -3.5f, -12.2f, -10.4f, -20f, -15f) + curveToRelative(-8.6f, -4.8f, -13.2f, -10.4f, -14.7f, -15.3f) + curveToRelative(-1.4f, -4.9f, 0f, -9f, 4.2f, -12.3f) + close() + moveToRelative(3.3f, 334f) + curveToRelative(-2.7f, 35.1f, -43.9f, 34.4f, -75.3f, 18f) + curveToRelative(-29.9f, -15.8f, -68.6f, -6.5f, -76.5f, -21.9f) + curveToRelative(-2.4f, -4.7f, -2.4f, -12.7f, 2.6f, -26.4f) + verticalLineToRelative(-.2f) + curveToRelative(2.4f, -7.6f, .6f, -16f, -.6f, -23.9f) + curveToRelative(-1.2f, -7.8f, -1.8f, -15f, .9f, -20f) + curveToRelative(3.5f, -6.7f, 8.5f, -9.1f, 14.8f, -11.3f) + curveToRelative(10.3f, -3.7f, 11.8f, -3.4f, 19.6f, -9.9f) + curveToRelative(5.5f, -5.7f, 9.5f, -12.9f, 14.3f, -18f) + curveToRelative(5.1f, -5.5f, 10f, -8.1f, 17.7f, -6.9f) + curveToRelative(8.1f, 1.2f, 15.1f, 6.8f, 21.9f, 16f) + lineToRelative(19.6f, 35.6f) + curveToRelative(9.5f, 19.9f, 43.1f, 48.4f, 41f, 68.9f) + close() + moveToRelative(-1.4f, -25.9f) + curveToRelative(-4.1f, -6.6f, -9.6f, -13.6f, -14.4f, -19.6f) + curveToRelative(7.1f, 0f, 14.2f, -2.2f, 16.7f, -8.9f) + curveToRelative(2.3f, -6.2f, 0f, -14.9f, -7.4f, -24.9f) + curveToRelative(-13.5f, -18.2f, -38.3f, -32.5f, -38.3f, -32.5f) + curveToRelative(-13.5f, -8.4f, -21.1f, -18.7f, -24.6f, -29.9f) + reflectiveCurveToRelative(-3f, -23.3f, -.3f, -35.2f) + curveToRelative(5.2f, -22.9f, 18.6f, -45.2f, 27.2f, -59.2f) + curveToRelative(2.3f, -1.7f, .8f, 3.2f, -8.7f, 20.8f) + curveToRelative(-8.5f, 16.1f, -24.4f, 53.3f, -2.6f, 82.4f) + curveToRelative(.6f, -20.7f, 5.5f, -41.8f, 13.8f, -61.5f) + curveToRelative(12f, -27.4f, 37.3f, -74.9f, 39.3f, -112.7f) + curveToRelative(1.1f, .8f, 4.6f, 3.2f, 6.2f, 4.1f) + curveToRelative(4.6f, 2.7f, 8.1f, 6.7f, 12.6f, 10.3f) + curveToRelative(12.4f, 10f, 28.5f, 9.2f, 42.4f, 1.2f) + curveToRelative(6.2f, -3.5f, 11.2f, -7.5f, 15.9f, -9f) + curveToRelative(9.9f, -3.1f, 17.8f, -8.6f, 22.3f, -15f) + curveToRelative(7.7f, 30.4f, 25.7f, 74.3f, 37.2f, 95.7f) + curveToRelative(6.1f, 11.4f, 18.3f, 35.5f, 23.6f, 64.6f) + curveToRelative(3.3f, -.1f, 7f, .4f, 10.9f, 1.4f) + curveToRelative(13.8f, -35.7f, -11.7f, -74.2f, -23.3f, -84.9f) + curveToRelative(-4.7f, -4.6f, -4.9f, -6.6f, -2.6f, -6.5f) + curveToRelative(12.6f, 11.2f, 29.2f, 33.7f, 35.2f, 59f) + curveToRelative(2.8f, 11.6f, 3.3f, 23.7f, .4f, 35.7f) + curveToRelative(16.4f, 6.8f, 35.9f, 17.9f, 30.7f, 34.8f) + curveToRelative(-2.2f, -.1f, -3.2f, 0f, -4.2f, 0f) + curveToRelative(3.2f, -10.1f, -3.9f, -17.6f, -22.8f, -26.1f) + curveToRelative(-19.6f, -8.6f, -36f, -8.6f, -38.3f, 12.5f) + curveToRelative(-12.1f, 4.2f, -18.3f, 14.7f, -21.4f, 27.3f) + curveToRelative(-2.8f, 11.2f, -3.6f, 24.7f, -4.4f, 39.9f) + curveToRelative(-.5f, 7.7f, -3.6f, 18f, -6.8f, 29f) + curveToRelative(-32.1f, 22.9f, -76.7f, 32.9f, -114.3f, 7.2f) + close() + moveToRelative(257.4f, -11.5f) + curveToRelative(-.9f, 16.8f, -41.2f, 19.9f, -63.2f, 46.5f) + curveToRelative(-13.2f, 15.7f, -29.4f, 24.4f, -43.6f, 25.5f) + reflectiveCurveToRelative(-26.5f, -4.8f, -33.7f, -19.3f) + curveToRelative(-4.7f, -11.1f, -2.4f, -23.1f, 1.1f, -36.3f) + curveToRelative(3.7f, -14.2f, 9.2f, -28.8f, 9.9f, -40.6f) + curveToRelative(.8f, -15.2f, 1.7f, -28.5f, 4.2f, -38.7f) + curveToRelative(2.6f, -10.3f, 6.6f, -17.2f, 13.7f, -21.1f) + curveToRelative(.3f, -.2f, .7f, -.3f, 1f, -.5f) + curveToRelative(.8f, 13.2f, 7.3f, 26.6f, 18.8f, 29.5f) + curveToRelative(12.6f, 3.3f, 30.7f, -7.5f, 38.4f, -16.3f) + curveToRelative(9f, -.3f, 15.7f, -.9f, 22.6f, 5.1f) + curveToRelative(9.9f, 8.5f, 7.1f, 30.3f, 17.1f, 41.6f) + curveToRelative(10.6f, 11.6f, 14f, 19.5f, 13.7f, 24.6f) + close() + moveTo(173.3f, 148.7f) + curveToRelative(2f, 1.9f, 4.7f, 4.5f, 8f, 7.1f) + curveToRelative(6.6f, 5.2f, 15.8f, 10.6f, 27.3f, 10.6f) + curveToRelative(11.6f, 0f, 22.5f, -5.9f, 31.8f, -10.8f) + curveToRelative(4.9f, -2.6f, 10.9f, -7f, 14.8f, -10.4f) + reflectiveCurveToRelative(5.9f, -6.3f, 3.1f, -6.6f) + reflectiveCurveToRelative(-2.6f, 2.6f, -6f, 5.1f) + curveToRelative(-4.4f, 3.2f, -9.7f, 7.4f, -13.9f, 9.8f) + curveToRelative(-7.4f, 4.2f, -19.5f, 10.2f, -29.9f, 10.2f) + reflectiveCurveToRelative(-18.7f, -4.8f, -24.9f, -9.7f) + curveToRelative(-3.1f, -2.5f, -5.7f, -5f, -7.7f, -6.9f) + curveToRelative(-1.5f, -1.4f, -1.9f, -4.6f, -4.3f, -4.9f) + curveToRelative(-1.4f, -.1f, -1.8f, 3.7f, 1.7f, 6.5f) + close() + } + } + return _linux!! + } + +val Icons.Filled.Microsoft: ImageVector + get() { + if (_microsoft != null) { + return _microsoft!! + } + _microsoft = materialIcon(name = "Filled.Microsoft") { + materialPath { + moveTo(2.0f, 3.0f) + horizontalLineToRelative(9.0f) + verticalLineToRelative(9.0f) + horizontalLineTo(2.0f) + verticalLineTo(3.0f) + moveToRelative(9.0f, 19.0f) + horizontalLineTo(2.0f) + verticalLineToRelative(-9.0f) + horizontalLineToRelative(9.0f) + verticalLineToRelative(9.0f) + moveTo(21.0f, 3.0f) + verticalLineToRelative(9.0f) + horizontalLineToRelative(-9.0f) + verticalLineTo(3.0f) + horizontalLineToRelative(9.0f) + moveToRelative(0.0f, 19.0f) + horizontalLineToRelative(-9.0f) + verticalLineToRelative(-9.0f) + horizontalLineToRelative(9.0f) + verticalLineToRelative(9.0f) + close() + } + } + return _microsoft!! + } + +private var _apple: ImageVector? = null +private var _linux: ImageVector? = null +private var _microsoft: ImageVector? = null diff --git a/composeApp/src/wasmJsMain/kotlin/Native.kt b/composeApp/src/wasmJsMain/kotlin/Native.kt new file mode 100644 index 0000000..d1f5f1d --- /dev/null +++ b/composeApp/src/wasmJsMain/kotlin/Native.kt @@ -0,0 +1,27 @@ +/** + * @author squid233 + * @since 0.3.0 + */ +enum class Native( + val description: String, + val classifierName: String, + val linux: Boolean = false, + val macos: Boolean = false, + val windows: Boolean = false +) { + LINUX_X64("Linux x64", "natives-linux", linux = true), + LINUX_ARM64("Linux arm64", "natives-linux-arm64", linux = true), + LINUX_ARM32("Linux arm32", "natives-linux-arm32", linux = true), + MACOS_X64("macOS x64", "natives-macos", macos = true), + MACOS_ARM64("macOS arm64", "natives-macos-arm64", macos = true), + WINDOWS_X64("Windows x64", "natives-windows", windows = true), + WINDOWS_ARM64("Windows arm64", "natives-windows-arm64", windows = true), +} + +fun nativeFromString(name: String?): Native? = name?.let { + try { + Native.valueOf(it) + } catch (e: Exception) { + null + } +}