Konstantin
12 months ago
committed by
GitHub
58 changed files with 1054 additions and 224 deletions
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Binary file not shown.
@ -1,6 +1,48 @@ |
|||||||
package org.jetbrains.compose.resources |
package org.jetbrains.compose.resources |
||||||
|
|
||||||
internal typealias ResourceId = String |
import androidx.compose.runtime.Immutable |
||||||
|
|
||||||
@RequiresOptIn("This API is experimental and is likely to change in the future.") |
@RequiresOptIn("This API is experimental and is likely to change in the future.") |
||||||
annotation class ExperimentalResourceApi |
annotation class ExperimentalResourceApi |
||||||
|
|
||||||
|
/** |
||||||
|
* Represents a resource with an ID and a set of resource items. |
||||||
|
* |
||||||
|
* @property id The ID of the resource. |
||||||
|
* @property items The set of resource items associated with the resource. |
||||||
|
*/ |
||||||
|
@Immutable |
||||||
|
sealed class Resource( |
||||||
|
internal val id: String, |
||||||
|
internal val items: Set<ResourceItem> |
||||||
|
) { |
||||||
|
override fun equals(other: Any?): Boolean { |
||||||
|
if (this === other) return true |
||||||
|
if (other == null || this::class != other::class) return false |
||||||
|
|
||||||
|
other as Resource |
||||||
|
|
||||||
|
return id == other.id |
||||||
|
} |
||||||
|
|
||||||
|
override fun hashCode(): Int { |
||||||
|
return id.hashCode() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Represents a resource item with qualifiers and a path. |
||||||
|
* |
||||||
|
* @property qualifiers The qualifiers of the resource item. |
||||||
|
* @property path The path of the resource item. |
||||||
|
*/ |
||||||
|
@Immutable |
||||||
|
data class ResourceItem( |
||||||
|
internal val qualifiers: Set<String>, |
||||||
|
internal val path: String |
||||||
|
) |
||||||
|
|
||||||
|
internal fun Resource.getPathByEnvironment(): String { |
||||||
|
//TODO |
||||||
|
return items.first().path |
||||||
|
} |
@ -1,14 +0,0 @@ |
|||||||
package org.jetbrains.compose.resources |
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable |
|
||||||
import androidx.compose.runtime.State |
|
||||||
|
|
||||||
//TODO Here will be logic to map a static ID to a file path in resources dir |
|
||||||
//at the moment ID = file path |
|
||||||
internal suspend fun getPathById(id: ResourceId): String = id |
|
||||||
|
|
||||||
@Composable |
|
||||||
internal fun rememberFilePath(id: ResourceId): State<String> = |
|
||||||
rememberState(id, { "" }) { getPathById(id) } |
|
||||||
|
|
||||||
internal val ResourceId.stringKey get() = this |
|
@ -1,18 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2020-2023 JetBrains s.r.o. and respective authors and developers. |
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.jetbrains.compose.experimental.uikit.internal.utils |
|
||||||
|
|
||||||
import org.gradle.api.provider.Provider |
|
||||||
import org.gradle.api.provider.ProviderFactory |
|
||||||
import org.jetbrains.compose.internal.utils.valueOrNull |
|
||||||
import org.jetbrains.compose.internal.utils.toBooleanProvider |
|
||||||
|
|
||||||
internal object IosGradleProperties { |
|
||||||
const val SYNC_RESOURCES_PROPERTY = "compose.ios.resources.sync" |
|
||||||
|
|
||||||
fun syncResources(providers: ProviderFactory): Provider<Boolean> = |
|
||||||
providers.valueOrNull(SYNC_RESOURCES_PROPERTY).toBooleanProvider(true) |
|
||||||
} |
|
@ -0,0 +1,42 @@ |
|||||||
|
package org.jetbrains.compose.resources |
||||||
|
|
||||||
|
import com.android.build.api.variant.AndroidComponentsExtension |
||||||
|
import com.android.build.gradle.BaseExtension |
||||||
|
import com.android.build.gradle.tasks.MergeSourceSetFolders |
||||||
|
import org.gradle.api.Project |
||||||
|
import org.gradle.api.provider.Provider |
||||||
|
import org.gradle.api.tasks.Copy |
||||||
|
import org.gradle.api.tasks.SourceSet |
||||||
|
import org.jetbrains.compose.internal.utils.registerTask |
||||||
|
import java.io.File |
||||||
|
|
||||||
|
internal fun Project.configureAndroidResources( |
||||||
|
commonResourcesDir: Provider<File>, |
||||||
|
androidFontsDir: Provider<File>, |
||||||
|
onlyIfProvider: Provider<Boolean> |
||||||
|
) { |
||||||
|
val androidExtension = project.extensions.findByName("android") as? BaseExtension ?: return |
||||||
|
val androidComponents = project.extensions.findByType(AndroidComponentsExtension::class.java) ?: return |
||||||
|
|
||||||
|
val androidMainSourceSet = androidExtension.sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME) |
||||||
|
androidMainSourceSet.resources.srcDir(commonResourcesDir) |
||||||
|
androidMainSourceSet.assets.srcDir(androidFontsDir) |
||||||
|
|
||||||
|
val copyFonts = registerTask<Copy>("copyFontsToAndroidAssets") { |
||||||
|
includeEmptyDirs = false |
||||||
|
from(commonResourcesDir) |
||||||
|
include("**/fonts/*") |
||||||
|
into(androidFontsDir) |
||||||
|
onlyIf { onlyIfProvider.get() } |
||||||
|
} |
||||||
|
androidComponents.onVariants { variant -> |
||||||
|
variant.sources?.assets?.addGeneratedSourceDirectory( |
||||||
|
taskProvider = copyFonts, |
||||||
|
wiredWith = { |
||||||
|
objects.directoryProperty().fileProvider( |
||||||
|
copyFonts.map { t -> t.destinationDir } |
||||||
|
) |
||||||
|
} |
||||||
|
) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,98 @@ |
|||||||
|
package org.jetbrains.compose.resources |
||||||
|
|
||||||
|
import org.gradle.api.DefaultTask |
||||||
|
import org.gradle.api.file.DirectoryProperty |
||||||
|
import org.gradle.api.provider.Property |
||||||
|
import org.gradle.api.tasks.* |
||||||
|
import java.io.File |
||||||
|
import java.nio.file.Path |
||||||
|
import javax.xml.parsers.DocumentBuilderFactory |
||||||
|
import kotlin.io.path.relativeTo |
||||||
|
|
||||||
|
/** |
||||||
|
* This task should be FAST and SAFE! Because it is being run during IDE import. |
||||||
|
*/ |
||||||
|
abstract class GenerateResClassTask : DefaultTask() { |
||||||
|
@get:Input |
||||||
|
abstract val packageName: Property<String> |
||||||
|
|
||||||
|
@get:InputDirectory |
||||||
|
@get:PathSensitive(PathSensitivity.RELATIVE) |
||||||
|
abstract val resDir: DirectoryProperty |
||||||
|
|
||||||
|
@get:OutputDirectory |
||||||
|
abstract val codeDir: DirectoryProperty |
||||||
|
|
||||||
|
init { |
||||||
|
this.onlyIf { resDir.asFile.get().exists() } |
||||||
|
} |
||||||
|
|
||||||
|
@TaskAction |
||||||
|
fun generate() { |
||||||
|
try { |
||||||
|
val rootResDir = resDir.get().asFile |
||||||
|
logger.info("Generate resources for $rootResDir") |
||||||
|
|
||||||
|
//get first level dirs |
||||||
|
val dirs = rootResDir.listFiles { f -> f.isDirectory }.orEmpty() |
||||||
|
|
||||||
|
//type -> id -> resource item |
||||||
|
val resources: Map<ResourceType, Map<String, List<ResourceItem>>> = dirs |
||||||
|
.flatMap { dir -> |
||||||
|
dir.listFiles { f -> !f.isDirectory } |
||||||
|
.orEmpty() |
||||||
|
.mapNotNull { it.fileToResourceItems(rootResDir.parentFile.toPath()) } |
||||||
|
.flatten() |
||||||
|
} |
||||||
|
.groupBy { it.type } |
||||||
|
.mapValues { (_, items) -> items.groupBy { it.name } } |
||||||
|
|
||||||
|
val kotlinDir = codeDir.get().asFile |
||||||
|
kotlinDir.deleteRecursively() |
||||||
|
kotlinDir.mkdirs() |
||||||
|
getResFileSpec(resources, packageName.get()).writeTo(kotlinDir) |
||||||
|
} catch (e: Exception) { |
||||||
|
//message must contain two ':' symbols to be parsed by IDE UI! |
||||||
|
logger.error("e: GenerateResClassTask was failed:", e) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private fun File.fileToResourceItems( |
||||||
|
relativeTo: Path |
||||||
|
): List<ResourceItem>? { |
||||||
|
val file = this |
||||||
|
if (file.isDirectory) return null |
||||||
|
val dirName = file.parentFile.name ?: return null |
||||||
|
val typeAndQualifiers = dirName.lowercase().split("-") |
||||||
|
if (typeAndQualifiers.isEmpty()) return null |
||||||
|
|
||||||
|
val typeString = typeAndQualifiers.first().lowercase() |
||||||
|
val qualifiers = typeAndQualifiers.takeLast(typeAndQualifiers.size - 1).map { it.lowercase() }.toSet() |
||||||
|
val path = file.toPath().relativeTo(relativeTo) |
||||||
|
|
||||||
|
return if (typeString == "values" && file.name.equals("strings.xml", true)) { |
||||||
|
val stringIds = getStringIds(file) |
||||||
|
stringIds.map { strId -> |
||||||
|
ResourceItem(ResourceType.STRING, qualifiers, strId.lowercase(), path) |
||||||
|
} |
||||||
|
} else { |
||||||
|
val type = try { |
||||||
|
ResourceType.fromString(typeString) |
||||||
|
} catch (e: Exception) { |
||||||
|
logger.error("e: Error: $path", e) |
||||||
|
return null |
||||||
|
} |
||||||
|
listOf(ResourceItem(type, qualifiers, file.nameWithoutExtension.lowercase(), path)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private val stringTypeNames = listOf("string", "string-array") |
||||||
|
private fun getStringIds(stringsXml: File): Set<String> { |
||||||
|
val doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stringsXml) |
||||||
|
val items = doc.getElementsByTagName("resources").item(0).childNodes |
||||||
|
val ids = List(items.length) { items.item(it) } |
||||||
|
.filter { it.nodeName in stringTypeNames } |
||||||
|
.map { it.attributes.getNamedItem("name").nodeValue } |
||||||
|
return ids.toSet() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,77 @@ |
|||||||
|
package org.jetbrains.compose.resources |
||||||
|
|
||||||
|
import org.gradle.api.Project |
||||||
|
import org.gradle.api.provider.Provider |
||||||
|
import org.jetbrains.compose.ComposeExtension |
||||||
|
import org.jetbrains.compose.ComposePlugin |
||||||
|
import org.jetbrains.compose.ExperimentalComposeLibrary |
||||||
|
import org.jetbrains.compose.desktop.application.internal.ComposeProperties |
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension |
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet |
||||||
|
import java.io.File |
||||||
|
|
||||||
|
private const val COMPOSE_RESOURCES_DIR = "composeRes" |
||||||
|
private const val RES_GEN_DIR = "generated/compose/resourceGenerator" |
||||||
|
|
||||||
|
internal fun Project.configureResourceGenerator() { |
||||||
|
val kotlinExtension = project.extensions.getByType(KotlinProjectExtension::class.java) |
||||||
|
val commonSourceSet = kotlinExtension.sourceSets.findByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) ?: return |
||||||
|
val commonResourcesDir = provider { commonSourceSet.resources.sourceDirectories.first() } |
||||||
|
|
||||||
|
val packageName = provider { |
||||||
|
buildString { |
||||||
|
val group = project.group.toString() |
||||||
|
append(group) |
||||||
|
if (group.isNotEmpty()) append(".") |
||||||
|
append("generated.resources") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun buildDir(path: String) = layout.dir(layout.buildDirectory.map { File(it.asFile, path) }) |
||||||
|
|
||||||
|
val resDir = layout.dir(commonResourcesDir.map { it.resolve(COMPOSE_RESOURCES_DIR) }) |
||||||
|
|
||||||
|
//lazy check a dependency on the Resources library |
||||||
|
val shouldGenerateResourceAccessors: Provider<Boolean> = provider { |
||||||
|
if (ComposeProperties.alwaysGenerateResourceAccessors(providers).get()) { |
||||||
|
true |
||||||
|
} else { |
||||||
|
configurations |
||||||
|
.getByName(commonSourceSet.implementationConfigurationName) |
||||||
|
.allDependencies.any { dep -> |
||||||
|
val depStringNotation = dep.let { "${it.group}:${it.name}:${it.version}" } |
||||||
|
depStringNotation == ComposePlugin.CommonComponentsDependencies.resources |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val genTask = tasks.register( |
||||||
|
"generateComposeResClass", |
||||||
|
GenerateResClassTask::class.java |
||||||
|
) { |
||||||
|
it.packageName.set(packageName) |
||||||
|
it.resDir.set(resDir) |
||||||
|
it.codeDir.set(buildDir("$RES_GEN_DIR/kotlin")) |
||||||
|
it.onlyIf { shouldGenerateResourceAccessors.get() } |
||||||
|
} |
||||||
|
|
||||||
|
//register generated source set |
||||||
|
commonSourceSet.kotlin.srcDir(genTask.map { it.codeDir }) |
||||||
|
|
||||||
|
//setup task execution during IDE import |
||||||
|
tasks.configureEach { |
||||||
|
if (it.name == "prepareKotlinIdeaImport") { |
||||||
|
it.dependsOn(genTask) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val androidExtension = project.extensions.findByName("android") |
||||||
|
if (androidExtension != null) { |
||||||
|
configureAndroidResources( |
||||||
|
commonResourcesDir, |
||||||
|
buildDir("$RES_GEN_DIR/androidFonts").map { it.asFile }, |
||||||
|
shouldGenerateResourceAccessors |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,95 @@ |
|||||||
|
package org.jetbrains.compose.resources |
||||||
|
|
||||||
|
import com.squareup.kotlinpoet.ClassName |
||||||
|
import com.squareup.kotlinpoet.CodeBlock |
||||||
|
import com.squareup.kotlinpoet.FileSpec |
||||||
|
import com.squareup.kotlinpoet.KModifier |
||||||
|
import com.squareup.kotlinpoet.PropertySpec |
||||||
|
import com.squareup.kotlinpoet.TypeSpec |
||||||
|
import com.squareup.kotlinpoet.withIndent |
||||||
|
import java.nio.file.Path |
||||||
|
import kotlin.io.path.invariantSeparatorsPathString |
||||||
|
import kotlin.io.path.pathString |
||||||
|
|
||||||
|
internal enum class ResourceType(val typeName: String) { |
||||||
|
IMAGE("images"), |
||||||
|
STRING("strings"), |
||||||
|
FONT("fonts"); |
||||||
|
|
||||||
|
companion object { |
||||||
|
fun fromString(str: String) = when (str) { |
||||||
|
"images" -> ResourceType.IMAGE |
||||||
|
"strings" -> ResourceType.STRING |
||||||
|
"fonts" -> ResourceType.FONT |
||||||
|
else -> error("Unknown resource type: $str") |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal data class ResourceItem( |
||||||
|
val type: ResourceType, |
||||||
|
val qualifiers: Set<String>, |
||||||
|
val name: String, |
||||||
|
val path: Path |
||||||
|
) |
||||||
|
|
||||||
|
private fun ResourceItem.getClassName(): ClassName = when (type) { |
||||||
|
ResourceType.IMAGE -> ClassName("org.jetbrains.compose.resources", "ImageResource") |
||||||
|
ResourceType.STRING -> ClassName("org.jetbrains.compose.resources", "StringResource") |
||||||
|
ResourceType.FONT -> ClassName("org.jetbrains.compose.resources", "FontResource") |
||||||
|
} |
||||||
|
|
||||||
|
internal fun getResFileSpec( |
||||||
|
//type -> id -> items |
||||||
|
resources: Map<ResourceType, Map<String, List<ResourceItem>>>, |
||||||
|
packageName: String |
||||||
|
): FileSpec = FileSpec.builder(packageName, "Res").apply { |
||||||
|
addType(TypeSpec.objectBuilder("Res").apply { |
||||||
|
addModifiers(KModifier.INTERNAL) |
||||||
|
val types = resources.map { (type, idToResources) -> |
||||||
|
getResourceTypeObject(type, idToResources) |
||||||
|
}.sortedBy { it.name } |
||||||
|
addTypes(types) |
||||||
|
}.build()) |
||||||
|
}.build() |
||||||
|
|
||||||
|
private fun getResourceTypeObject(type: ResourceType, nameToResources: Map<String, List<ResourceItem>>) = |
||||||
|
TypeSpec.objectBuilder(type.typeName).apply { |
||||||
|
nameToResources.entries |
||||||
|
.sortedBy { it.key } |
||||||
|
.forEach { (name, items) -> |
||||||
|
addResourceProperty(name, items.sortedBy { it.path }) |
||||||
|
} |
||||||
|
}.build() |
||||||
|
|
||||||
|
private fun TypeSpec.Builder.addResourceProperty(name: String, items: List<ResourceItem>) { |
||||||
|
val resourceItemClass = ClassName("org.jetbrains.compose.resources", "ResourceItem") |
||||||
|
|
||||||
|
val first = items.first() |
||||||
|
val propertyClassName = first.getClassName() |
||||||
|
val resourceId = first.let { "${it.type}:${it.name}" } |
||||||
|
|
||||||
|
val initializer = CodeBlock.builder() |
||||||
|
.add("%T(\n", propertyClassName).withIndent { |
||||||
|
add("\"$resourceId\",\n") |
||||||
|
if (first.type == ResourceType.STRING) { |
||||||
|
add("\"${first.name}\",\n") |
||||||
|
} |
||||||
|
add("setOf(\n").withIndent { |
||||||
|
items.forEach { item -> |
||||||
|
val qualifiers = item.qualifiers.sorted().joinToString { "\"$it\"" } |
||||||
|
//file separator should be '/' on all platforms |
||||||
|
add("%T(setOf($qualifiers), \"${item.path.invariantSeparatorsPathString}\"),\n", resourceItemClass) |
||||||
|
} |
||||||
|
} |
||||||
|
add(")\n") |
||||||
|
} |
||||||
|
.add(")") |
||||||
|
.build() |
||||||
|
|
||||||
|
addProperty( |
||||||
|
PropertySpec.builder(name, propertyClassName) |
||||||
|
.initializer(initializer) |
||||||
|
.build() |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
package org.jetbrains.compose.test.tests.integration |
||||||
|
|
||||||
|
import org.jetbrains.compose.test.utils.GradlePluginTestBase |
||||||
|
import org.jetbrains.compose.test.utils.assertEqualTextFiles |
||||||
|
import org.jetbrains.compose.test.utils.assertNotEqualTextFiles |
||||||
|
import org.jetbrains.compose.test.utils.checks |
||||||
|
import org.junit.jupiter.api.Test |
||||||
|
import kotlin.io.path.Path |
||||||
|
|
||||||
|
class ResourcesTest : GradlePluginTestBase() { |
||||||
|
@Test |
||||||
|
fun testGeneratedAccessorsAndCopiedFonts() = with(testProject("misc/commonResources")) { |
||||||
|
//check generated resource's accessors |
||||||
|
gradle("generateComposeResClass").checks { |
||||||
|
assertEqualTextFiles( |
||||||
|
file("build/generated/compose/resourceGenerator/kotlin/generated/resources/Res.kt"), |
||||||
|
file("expected/Res.kt") |
||||||
|
) |
||||||
|
check.logContains(""" |
||||||
|
java.lang.IllegalStateException: Unknown resource type: ignored |
||||||
|
""".trimIndent()) |
||||||
|
} |
||||||
|
|
||||||
|
file("src/commonMain/resources/composeRes/images/vector_2.xml").renameTo( |
||||||
|
file("src/commonMain/resources/composeRes/images/vector_3.xml") |
||||||
|
) |
||||||
|
|
||||||
|
//check resource's accessors were regenerated |
||||||
|
gradle("generateComposeResClass").checks { |
||||||
|
assertNotEqualTextFiles( |
||||||
|
file("build/generated/compose/resourceGenerator/kotlin/generated/resources/Res.kt"), |
||||||
|
file("expected/Res.kt") |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
file("src/commonMain/resources/composeRes/images/vector_3.xml").renameTo( |
||||||
|
file("src/commonMain/resources/composeRes/images/vector_2.xml") |
||||||
|
) |
||||||
|
|
||||||
|
//TODO: check a real build after a release a new version of the resources library |
||||||
|
//because generated accessors depend on classes from the new version |
||||||
|
gradle("assembleDebug", "--dry-run").checks { |
||||||
|
check.taskSkipped("copyFontsToAndroidAssets") |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
plugins { |
||||||
|
kotlin("multiplatform") |
||||||
|
id("com.android.library") |
||||||
|
id("org.jetbrains.compose") |
||||||
|
} |
||||||
|
|
||||||
|
kotlin { |
||||||
|
androidTarget { |
||||||
|
compilations.all { |
||||||
|
kotlinOptions { |
||||||
|
jvmTarget = "11" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
jvm("desktop") |
||||||
|
|
||||||
|
sourceSets { |
||||||
|
commonMain { |
||||||
|
dependencies { |
||||||
|
implementation(compose.runtime) |
||||||
|
implementation(compose.material) |
||||||
|
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) |
||||||
|
implementation(compose.components.resources) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
android { |
||||||
|
compileSdk = 31 |
||||||
|
namespace = "org.jetbrains.compose.resources.test" |
||||||
|
defaultConfig { |
||||||
|
minSdk = 21 |
||||||
|
} |
||||||
|
compileOptions { |
||||||
|
sourceCompatibility = JavaVersion.VERSION_11 |
||||||
|
targetCompatibility = JavaVersion.VERSION_11 |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
package generated.resources |
||||||
|
|
||||||
|
import org.jetbrains.compose.resources.FontResource |
||||||
|
import org.jetbrains.compose.resources.ImageResource |
||||||
|
import org.jetbrains.compose.resources.ResourceItem |
||||||
|
import org.jetbrains.compose.resources.StringResource |
||||||
|
|
||||||
|
internal object Res { |
||||||
|
public object fonts { |
||||||
|
public val emptyfont: FontResource = FontResource( |
||||||
|
"FONT:emptyfont", |
||||||
|
setOf( |
||||||
|
ResourceItem(setOf(), "composeRes/fonts/emptyFont.otf"), |
||||||
|
) |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
public object images { |
||||||
|
public val vector: ImageResource = ImageResource( |
||||||
|
"IMAGE:vector", |
||||||
|
setOf( |
||||||
|
ResourceItem(setOf("q1", "q2"), "composeRes/images-q1-q2/vector.xml"), |
||||||
|
ResourceItem(setOf("q1"), "composeRes/images-q1/vector.xml"), |
||||||
|
ResourceItem(setOf("q2"), "composeRes/images-q2/vector.xml"), |
||||||
|
ResourceItem(setOf(), "composeRes/images/vector.xml"), |
||||||
|
) |
||||||
|
) |
||||||
|
|
||||||
|
public val vector_2: ImageResource = ImageResource( |
||||||
|
"IMAGE:vector_2", |
||||||
|
setOf( |
||||||
|
ResourceItem(setOf(), "composeRes/images/vector_2.xml"), |
||||||
|
) |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
public object strings { |
||||||
|
public val app_name: StringResource = StringResource( |
||||||
|
"STRING:app_name", |
||||||
|
"app_name", |
||||||
|
setOf( |
||||||
|
ResourceItem(setOf(), "composeRes/values/strings.xml"), |
||||||
|
) |
||||||
|
) |
||||||
|
|
||||||
|
public val hello: StringResource = StringResource( |
||||||
|
"STRING:hello", |
||||||
|
"hello", |
||||||
|
setOf( |
||||||
|
ResourceItem(setOf(), "composeRes/values/strings.xml"), |
||||||
|
) |
||||||
|
) |
||||||
|
|
||||||
|
public val multi_line: StringResource = StringResource( |
||||||
|
"STRING:multi_line", |
||||||
|
"multi_line", |
||||||
|
setOf( |
||||||
|
ResourceItem(setOf(), "composeRes/values/strings.xml"), |
||||||
|
) |
||||||
|
) |
||||||
|
|
||||||
|
public val str_arr: StringResource = StringResource( |
||||||
|
"STRING:str_arr", |
||||||
|
"str_arr", |
||||||
|
setOf( |
||||||
|
ResourceItem(setOf(), "composeRes/values/strings.xml"), |
||||||
|
) |
||||||
|
) |
||||||
|
|
||||||
|
public val str_template: StringResource = StringResource( |
||||||
|
"STRING:str_template", |
||||||
|
"str_template", |
||||||
|
setOf( |
||||||
|
ResourceItem(setOf(), "composeRes/values/strings.xml"), |
||||||
|
) |
||||||
|
) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
android.useAndroidX=true |
@ -0,0 +1,22 @@ |
|||||||
|
pluginManagement { |
||||||
|
repositories { |
||||||
|
mavenLocal() |
||||||
|
gradlePluginPortal() |
||||||
|
google() |
||||||
|
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") |
||||||
|
} |
||||||
|
plugins { |
||||||
|
id("com.android.library").version("AGP_VERSION_PLACEHOLDER") |
||||||
|
id("org.jetbrains.kotlin.multiplatform").version("KOTLIN_VERSION_PLACEHOLDER") |
||||||
|
id("org.jetbrains.compose").version("COMPOSE_GRADLE_PLUGIN_VERSION_PLACEHOLDER") |
||||||
|
} |
||||||
|
} |
||||||
|
dependencyResolutionManagement { |
||||||
|
repositories { |
||||||
|
mavenLocal() |
||||||
|
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") |
||||||
|
mavenCentral() |
||||||
|
gradlePluginPortal() |
||||||
|
google() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
import androidx.compose.foundation.layout.* |
||||||
|
import androidx.compose.material.Text |
||||||
|
import androidx.compose.runtime.Composable |
||||||
|
import androidx.compose.ui.text.font.FontFamily |
||||||
|
import generated.resources.Res |
||||||
|
import org.jetbrains.compose.resources.* |
||||||
|
|
||||||
|
@OptIn(ExperimentalResourceApi::class) |
||||||
|
@Composable |
||||||
|
fun App() { |
||||||
|
Column { |
||||||
|
Image( |
||||||
|
modifier = Modifier.size(100.dp), |
||||||
|
painter = painterResource(Res.images.vector), |
||||||
|
contentDescription = null |
||||||
|
) |
||||||
|
Text(getString(Res.strings.app_name)) |
||||||
|
val font = FontFamily(Font(Res.fonts.emptyfont)) |
||||||
|
} |
||||||
|
} |
Binary file not shown.
@ -0,0 +1,36 @@ |
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:width="600dp" |
||||||
|
android:height="600dp" |
||||||
|
android:viewportWidth="600" |
||||||
|
android:viewportHeight="600"> |
||||||
|
<path |
||||||
|
android:pathData="M301.21,418.53C300.97,418.54 300.73,418.56 300.49,418.56C297.09,418.59 293.74,417.72 290.79,416.05L222.6,377.54C220.63,376.43 219,374.82 217.85,372.88C216.7,370.94 216.09,368.73 216.07,366.47L216.07,288.16C216.06,287.32 216.09,286.49 216.17,285.67C216.38,283.54 216.91,281.5 217.71,279.6L199.29,268.27L177.74,256.19C175.72,260.43 174.73,265.23 174.78,270.22L174.79,387.05C174.85,393.89 178.57,400.2 184.53,403.56L286.26,461.02C290.67,463.51 295.66,464.8 300.73,464.76C300.91,464.76 301.09,464.74 301.27,464.74C301.24,449.84 301.22,439.23 301.22,439.23L301.21,418.53Z" |
||||||
|
android:fillColor="#041619" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M409.45,242.91L312.64,188.23C303.64,183.15 292.58,183.26 283.68,188.51L187.92,245C183.31,247.73 179.93,251.62 177.75,256.17L177.74,256.19L199.29,268.27L217.71,279.6C217.83,279.32 217.92,279.02 218.05,278.74C218.24,278.36 218.43,277.98 218.64,277.62C219.06,276.88 219.52,276.18 220.04,275.51C221.37,273.8 223.01,272.35 224.87,271.25L289.06,233.39C290.42,232.59 291.87,231.96 293.39,231.51C295.53,230.87 297.77,230.6 300,230.72C302.98,230.88 305.88,231.73 308.47,233.2L373.37,269.85C375.54,271.08 377.49,272.68 379.13,274.57C379.68,275.19 380.18,275.85 380.65,276.53C380.86,276.84 381.05,277.15 381.24,277.47L397.79,266.39L420.34,252.93L420.31,252.88C417.55,248.8 413.77,245.35 409.45,242.91Z" |
||||||
|
android:fillColor="#37BF6E" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M381.24,277.47C381.51,277.92 381.77,278.38 382.01,278.84C382.21,279.24 382.39,279.65 382.57,280.06C382.91,280.88 383.19,281.73 383.41,282.59C383.74,283.88 383.92,285.21 383.93,286.57L383.93,361.1C383.96,363.95 383.35,366.77 382.16,369.36C381.93,369.86 381.69,370.35 381.42,370.83C379.75,373.79 377.32,376.27 374.39,378L310.2,415.87C307.47,417.48 304.38,418.39 301.21,418.53L301.22,439.23C301.22,439.23 301.24,449.84 301.27,464.74C306.1,464.61 310.91,463.3 315.21,460.75L410.98,404.25C419.88,399 425.31,389.37 425.22,379.03L425.22,267.85C425.17,262.48 423.34,257.34 420.34,252.93L397.79,266.39L381.24,277.47Z" |
||||||
|
android:fillColor="#3870B2" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M177.75,256.17C179.93,251.62 183.31,247.73 187.92,245L283.68,188.51C292.58,183.26 303.64,183.15 312.64,188.23L409.45,242.91C413.77,245.35 417.55,248.8 420.31,252.88L420.34,252.93L498.59,206.19C494.03,199.46 487.79,193.78 480.67,189.75L320.86,99.49C306.01,91.1 287.75,91.27 273.07,99.95L114.99,193.2C107.39,197.69 101.81,204.11 98.21,211.63L177.74,256.19L177.75,256.17ZM301.27,464.74C301.09,464.74 300.91,464.76 300.73,464.76C295.66,464.8 290.67,463.51 286.26,461.02L184.53,403.56C178.57,400.2 174.85,393.89 174.79,387.05L174.78,270.22C174.73,265.23 175.72,260.43 177.74,256.19L98.21,211.63C94.86,218.63 93.23,226.58 93.31,234.82L93.31,427.67C93.42,438.97 99.54,449.37 109.4,454.92L277.31,549.77C284.6,553.88 292.84,556.01 301.2,555.94L301.2,555.8C301.39,543.78 301.33,495.26 301.27,464.74Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M498.59,206.19L420.34,252.93C423.34,257.34 425.17,262.48 425.22,267.85L425.22,379.03C425.31,389.37 419.88,399 410.98,404.25L315.21,460.75C310.91,463.3 306.1,464.61 301.27,464.74C301.33,495.26 301.39,543.78 301.2,555.8L301.2,555.94C309.48,555.87 317.74,553.68 325.11,549.32L483.18,456.06C497.87,447.39 506.85,431.49 506.69,414.43L506.69,230.91C506.6,222.02 503.57,213.5 498.59,206.19Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M301.2,555.94C292.84,556.01 284.6,553.88 277.31,549.76L109.4,454.92C99.54,449.37 93.42,438.97 93.31,427.67L93.31,234.82C93.23,226.58 94.86,218.63 98.21,211.63C101.81,204.11 107.39,197.69 114.99,193.2L273.07,99.95C287.75,91.27 306.01,91.1 320.86,99.49L480.67,189.75C487.79,193.78 494.03,199.46 498.59,206.19C503.57,213.5 506.6,222.02 506.69,230.91L506.69,414.43C506.85,431.49 497.87,447.39 483.18,456.06L325.11,549.32C317.74,553.68 309.48,555.87 301.2,555.94Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
</vector> |
@ -0,0 +1,36 @@ |
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:width="600dp" |
||||||
|
android:height="600dp" |
||||||
|
android:viewportWidth="600" |
||||||
|
android:viewportHeight="600"> |
||||||
|
<path |
||||||
|
android:pathData="M301.21,418.53C300.97,418.54 300.73,418.56 300.49,418.56C297.09,418.59 293.74,417.72 290.79,416.05L222.6,377.54C220.63,376.43 219,374.82 217.85,372.88C216.7,370.94 216.09,368.73 216.07,366.47L216.07,288.16C216.06,287.32 216.09,286.49 216.17,285.67C216.38,283.54 216.91,281.5 217.71,279.6L199.29,268.27L177.74,256.19C175.72,260.43 174.73,265.23 174.78,270.22L174.79,387.05C174.85,393.89 178.57,400.2 184.53,403.56L286.26,461.02C290.67,463.51 295.66,464.8 300.73,464.76C300.91,464.76 301.09,464.74 301.27,464.74C301.24,449.84 301.22,439.23 301.22,439.23L301.21,418.53Z" |
||||||
|
android:fillColor="#041619" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M409.45,242.91L312.64,188.23C303.64,183.15 292.58,183.26 283.68,188.51L187.92,245C183.31,247.73 179.93,251.62 177.75,256.17L177.74,256.19L199.29,268.27L217.71,279.6C217.83,279.32 217.92,279.02 218.05,278.74C218.24,278.36 218.43,277.98 218.64,277.62C219.06,276.88 219.52,276.18 220.04,275.51C221.37,273.8 223.01,272.35 224.87,271.25L289.06,233.39C290.42,232.59 291.87,231.96 293.39,231.51C295.53,230.87 297.77,230.6 300,230.72C302.98,230.88 305.88,231.73 308.47,233.2L373.37,269.85C375.54,271.08 377.49,272.68 379.13,274.57C379.68,275.19 380.18,275.85 380.65,276.53C380.86,276.84 381.05,277.15 381.24,277.47L397.79,266.39L420.34,252.93L420.31,252.88C417.55,248.8 413.77,245.35 409.45,242.91Z" |
||||||
|
android:fillColor="#37BF6E" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M381.24,277.47C381.51,277.92 381.77,278.38 382.01,278.84C382.21,279.24 382.39,279.65 382.57,280.06C382.91,280.88 383.19,281.73 383.41,282.59C383.74,283.88 383.92,285.21 383.93,286.57L383.93,361.1C383.96,363.95 383.35,366.77 382.16,369.36C381.93,369.86 381.69,370.35 381.42,370.83C379.75,373.79 377.32,376.27 374.39,378L310.2,415.87C307.47,417.48 304.38,418.39 301.21,418.53L301.22,439.23C301.22,439.23 301.24,449.84 301.27,464.74C306.1,464.61 310.91,463.3 315.21,460.75L410.98,404.25C419.88,399 425.31,389.37 425.22,379.03L425.22,267.85C425.17,262.48 423.34,257.34 420.34,252.93L397.79,266.39L381.24,277.47Z" |
||||||
|
android:fillColor="#3870B2" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M177.75,256.17C179.93,251.62 183.31,247.73 187.92,245L283.68,188.51C292.58,183.26 303.64,183.15 312.64,188.23L409.45,242.91C413.77,245.35 417.55,248.8 420.31,252.88L420.34,252.93L498.59,206.19C494.03,199.46 487.79,193.78 480.67,189.75L320.86,99.49C306.01,91.1 287.75,91.27 273.07,99.95L114.99,193.2C107.39,197.69 101.81,204.11 98.21,211.63L177.74,256.19L177.75,256.17ZM301.27,464.74C301.09,464.74 300.91,464.76 300.73,464.76C295.66,464.8 290.67,463.51 286.26,461.02L184.53,403.56C178.57,400.2 174.85,393.89 174.79,387.05L174.78,270.22C174.73,265.23 175.72,260.43 177.74,256.19L98.21,211.63C94.86,218.63 93.23,226.58 93.31,234.82L93.31,427.67C93.42,438.97 99.54,449.37 109.4,454.92L277.31,549.77C284.6,553.88 292.84,556.01 301.2,555.94L301.2,555.8C301.39,543.78 301.33,495.26 301.27,464.74Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M498.59,206.19L420.34,252.93C423.34,257.34 425.17,262.48 425.22,267.85L425.22,379.03C425.31,389.37 419.88,399 410.98,404.25L315.21,460.75C310.91,463.3 306.1,464.61 301.27,464.74C301.33,495.26 301.39,543.78 301.2,555.8L301.2,555.94C309.48,555.87 317.74,553.68 325.11,549.32L483.18,456.06C497.87,447.39 506.85,431.49 506.69,414.43L506.69,230.91C506.6,222.02 503.57,213.5 498.59,206.19Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M301.2,555.94C292.84,556.01 284.6,553.88 277.31,549.76L109.4,454.92C99.54,449.37 93.42,438.97 93.31,427.67L93.31,234.82C93.23,226.58 94.86,218.63 98.21,211.63C101.81,204.11 107.39,197.69 114.99,193.2L273.07,99.95C287.75,91.27 306.01,91.1 320.86,99.49L480.67,189.75C487.79,193.78 494.03,199.46 498.59,206.19C503.57,213.5 506.6,222.02 506.69,230.91L506.69,414.43C506.85,431.49 497.87,447.39 483.18,456.06L325.11,549.32C317.74,553.68 309.48,555.87 301.2,555.94Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
</vector> |
@ -0,0 +1,36 @@ |
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:width="600dp" |
||||||
|
android:height="600dp" |
||||||
|
android:viewportWidth="600" |
||||||
|
android:viewportHeight="600"> |
||||||
|
<path |
||||||
|
android:pathData="M301.21,418.53C300.97,418.54 300.73,418.56 300.49,418.56C297.09,418.59 293.74,417.72 290.79,416.05L222.6,377.54C220.63,376.43 219,374.82 217.85,372.88C216.7,370.94 216.09,368.73 216.07,366.47L216.07,288.16C216.06,287.32 216.09,286.49 216.17,285.67C216.38,283.54 216.91,281.5 217.71,279.6L199.29,268.27L177.74,256.19C175.72,260.43 174.73,265.23 174.78,270.22L174.79,387.05C174.85,393.89 178.57,400.2 184.53,403.56L286.26,461.02C290.67,463.51 295.66,464.8 300.73,464.76C300.91,464.76 301.09,464.74 301.27,464.74C301.24,449.84 301.22,439.23 301.22,439.23L301.21,418.53Z" |
||||||
|
android:fillColor="#041619" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M409.45,242.91L312.64,188.23C303.64,183.15 292.58,183.26 283.68,188.51L187.92,245C183.31,247.73 179.93,251.62 177.75,256.17L177.74,256.19L199.29,268.27L217.71,279.6C217.83,279.32 217.92,279.02 218.05,278.74C218.24,278.36 218.43,277.98 218.64,277.62C219.06,276.88 219.52,276.18 220.04,275.51C221.37,273.8 223.01,272.35 224.87,271.25L289.06,233.39C290.42,232.59 291.87,231.96 293.39,231.51C295.53,230.87 297.77,230.6 300,230.72C302.98,230.88 305.88,231.73 308.47,233.2L373.37,269.85C375.54,271.08 377.49,272.68 379.13,274.57C379.68,275.19 380.18,275.85 380.65,276.53C380.86,276.84 381.05,277.15 381.24,277.47L397.79,266.39L420.34,252.93L420.31,252.88C417.55,248.8 413.77,245.35 409.45,242.91Z" |
||||||
|
android:fillColor="#37BF6E" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M381.24,277.47C381.51,277.92 381.77,278.38 382.01,278.84C382.21,279.24 382.39,279.65 382.57,280.06C382.91,280.88 383.19,281.73 383.41,282.59C383.74,283.88 383.92,285.21 383.93,286.57L383.93,361.1C383.96,363.95 383.35,366.77 382.16,369.36C381.93,369.86 381.69,370.35 381.42,370.83C379.75,373.79 377.32,376.27 374.39,378L310.2,415.87C307.47,417.48 304.38,418.39 301.21,418.53L301.22,439.23C301.22,439.23 301.24,449.84 301.27,464.74C306.1,464.61 310.91,463.3 315.21,460.75L410.98,404.25C419.88,399 425.31,389.37 425.22,379.03L425.22,267.85C425.17,262.48 423.34,257.34 420.34,252.93L397.79,266.39L381.24,277.47Z" |
||||||
|
android:fillColor="#3870B2" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M177.75,256.17C179.93,251.62 183.31,247.73 187.92,245L283.68,188.51C292.58,183.26 303.64,183.15 312.64,188.23L409.45,242.91C413.77,245.35 417.55,248.8 420.31,252.88L420.34,252.93L498.59,206.19C494.03,199.46 487.79,193.78 480.67,189.75L320.86,99.49C306.01,91.1 287.75,91.27 273.07,99.95L114.99,193.2C107.39,197.69 101.81,204.11 98.21,211.63L177.74,256.19L177.75,256.17ZM301.27,464.74C301.09,464.74 300.91,464.76 300.73,464.76C295.66,464.8 290.67,463.51 286.26,461.02L184.53,403.56C178.57,400.2 174.85,393.89 174.79,387.05L174.78,270.22C174.73,265.23 175.72,260.43 177.74,256.19L98.21,211.63C94.86,218.63 93.23,226.58 93.31,234.82L93.31,427.67C93.42,438.97 99.54,449.37 109.4,454.92L277.31,549.77C284.6,553.88 292.84,556.01 301.2,555.94L301.2,555.8C301.39,543.78 301.33,495.26 301.27,464.74Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M498.59,206.19L420.34,252.93C423.34,257.34 425.17,262.48 425.22,267.85L425.22,379.03C425.31,389.37 419.88,399 410.98,404.25L315.21,460.75C310.91,463.3 306.1,464.61 301.27,464.74C301.33,495.26 301.39,543.78 301.2,555.8L301.2,555.94C309.48,555.87 317.74,553.68 325.11,549.32L483.18,456.06C497.87,447.39 506.85,431.49 506.69,414.43L506.69,230.91C506.6,222.02 503.57,213.5 498.59,206.19Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M301.2,555.94C292.84,556.01 284.6,553.88 277.31,549.76L109.4,454.92C99.54,449.37 93.42,438.97 93.31,427.67L93.31,234.82C93.23,226.58 94.86,218.63 98.21,211.63C101.81,204.11 107.39,197.69 114.99,193.2L273.07,99.95C287.75,91.27 306.01,91.1 320.86,99.49L480.67,189.75C487.79,193.78 494.03,199.46 498.59,206.19C503.57,213.5 506.6,222.02 506.69,230.91L506.69,414.43C506.85,431.49 497.87,447.39 483.18,456.06L325.11,549.32C317.74,553.68 309.48,555.87 301.2,555.94Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
</vector> |
@ -0,0 +1,36 @@ |
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:width="600dp" |
||||||
|
android:height="600dp" |
||||||
|
android:viewportWidth="600" |
||||||
|
android:viewportHeight="600"> |
||||||
|
<path |
||||||
|
android:pathData="M301.21,418.53C300.97,418.54 300.73,418.56 300.49,418.56C297.09,418.59 293.74,417.72 290.79,416.05L222.6,377.54C220.63,376.43 219,374.82 217.85,372.88C216.7,370.94 216.09,368.73 216.07,366.47L216.07,288.16C216.06,287.32 216.09,286.49 216.17,285.67C216.38,283.54 216.91,281.5 217.71,279.6L199.29,268.27L177.74,256.19C175.72,260.43 174.73,265.23 174.78,270.22L174.79,387.05C174.85,393.89 178.57,400.2 184.53,403.56L286.26,461.02C290.67,463.51 295.66,464.8 300.73,464.76C300.91,464.76 301.09,464.74 301.27,464.74C301.24,449.84 301.22,439.23 301.22,439.23L301.21,418.53Z" |
||||||
|
android:fillColor="#041619" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M409.45,242.91L312.64,188.23C303.64,183.15 292.58,183.26 283.68,188.51L187.92,245C183.31,247.73 179.93,251.62 177.75,256.17L177.74,256.19L199.29,268.27L217.71,279.6C217.83,279.32 217.92,279.02 218.05,278.74C218.24,278.36 218.43,277.98 218.64,277.62C219.06,276.88 219.52,276.18 220.04,275.51C221.37,273.8 223.01,272.35 224.87,271.25L289.06,233.39C290.42,232.59 291.87,231.96 293.39,231.51C295.53,230.87 297.77,230.6 300,230.72C302.98,230.88 305.88,231.73 308.47,233.2L373.37,269.85C375.54,271.08 377.49,272.68 379.13,274.57C379.68,275.19 380.18,275.85 380.65,276.53C380.86,276.84 381.05,277.15 381.24,277.47L397.79,266.39L420.34,252.93L420.31,252.88C417.55,248.8 413.77,245.35 409.45,242.91Z" |
||||||
|
android:fillColor="#37BF6E" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M381.24,277.47C381.51,277.92 381.77,278.38 382.01,278.84C382.21,279.24 382.39,279.65 382.57,280.06C382.91,280.88 383.19,281.73 383.41,282.59C383.74,283.88 383.92,285.21 383.93,286.57L383.93,361.1C383.96,363.95 383.35,366.77 382.16,369.36C381.93,369.86 381.69,370.35 381.42,370.83C379.75,373.79 377.32,376.27 374.39,378L310.2,415.87C307.47,417.48 304.38,418.39 301.21,418.53L301.22,439.23C301.22,439.23 301.24,449.84 301.27,464.74C306.1,464.61 310.91,463.3 315.21,460.75L410.98,404.25C419.88,399 425.31,389.37 425.22,379.03L425.22,267.85C425.17,262.48 423.34,257.34 420.34,252.93L397.79,266.39L381.24,277.47Z" |
||||||
|
android:fillColor="#3870B2" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M177.75,256.17C179.93,251.62 183.31,247.73 187.92,245L283.68,188.51C292.58,183.26 303.64,183.15 312.64,188.23L409.45,242.91C413.77,245.35 417.55,248.8 420.31,252.88L420.34,252.93L498.59,206.19C494.03,199.46 487.79,193.78 480.67,189.75L320.86,99.49C306.01,91.1 287.75,91.27 273.07,99.95L114.99,193.2C107.39,197.69 101.81,204.11 98.21,211.63L177.74,256.19L177.75,256.17ZM301.27,464.74C301.09,464.74 300.91,464.76 300.73,464.76C295.66,464.8 290.67,463.51 286.26,461.02L184.53,403.56C178.57,400.2 174.85,393.89 174.79,387.05L174.78,270.22C174.73,265.23 175.72,260.43 177.74,256.19L98.21,211.63C94.86,218.63 93.23,226.58 93.31,234.82L93.31,427.67C93.42,438.97 99.54,449.37 109.4,454.92L277.31,549.77C284.6,553.88 292.84,556.01 301.2,555.94L301.2,555.8C301.39,543.78 301.33,495.26 301.27,464.74Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M498.59,206.19L420.34,252.93C423.34,257.34 425.17,262.48 425.22,267.85L425.22,379.03C425.31,389.37 419.88,399 410.98,404.25L315.21,460.75C310.91,463.3 306.1,464.61 301.27,464.74C301.33,495.26 301.39,543.78 301.2,555.8L301.2,555.94C309.48,555.87 317.74,553.68 325.11,549.32L483.18,456.06C497.87,447.39 506.85,431.49 506.69,414.43L506.69,230.91C506.6,222.02 503.57,213.5 498.59,206.19Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M301.2,555.94C292.84,556.01 284.6,553.88 277.31,549.76L109.4,454.92C99.54,449.37 93.42,438.97 93.31,427.67L93.31,234.82C93.23,226.58 94.86,218.63 98.21,211.63C101.81,204.11 107.39,197.69 114.99,193.2L273.07,99.95C287.75,91.27 306.01,91.1 320.86,99.49L480.67,189.75C487.79,193.78 494.03,199.46 498.59,206.19C503.57,213.5 506.6,222.02 506.69,230.91L506.69,414.43C506.85,431.49 497.87,447.39 483.18,456.06L325.11,549.32C317.74,553.68 309.48,555.87 301.2,555.94Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
</vector> |
@ -0,0 +1,36 @@ |
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:width="600dp" |
||||||
|
android:height="600dp" |
||||||
|
android:viewportWidth="600" |
||||||
|
android:viewportHeight="600"> |
||||||
|
<path |
||||||
|
android:pathData="M301.21,418.53C300.97,418.54 300.73,418.56 300.49,418.56C297.09,418.59 293.74,417.72 290.79,416.05L222.6,377.54C220.63,376.43 219,374.82 217.85,372.88C216.7,370.94 216.09,368.73 216.07,366.47L216.07,288.16C216.06,287.32 216.09,286.49 216.17,285.67C216.38,283.54 216.91,281.5 217.71,279.6L199.29,268.27L177.74,256.19C175.72,260.43 174.73,265.23 174.78,270.22L174.79,387.05C174.85,393.89 178.57,400.2 184.53,403.56L286.26,461.02C290.67,463.51 295.66,464.8 300.73,464.76C300.91,464.76 301.09,464.74 301.27,464.74C301.24,449.84 301.22,439.23 301.22,439.23L301.21,418.53Z" |
||||||
|
android:fillColor="#041619" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M409.45,242.91L312.64,188.23C303.64,183.15 292.58,183.26 283.68,188.51L187.92,245C183.31,247.73 179.93,251.62 177.75,256.17L177.74,256.19L199.29,268.27L217.71,279.6C217.83,279.32 217.92,279.02 218.05,278.74C218.24,278.36 218.43,277.98 218.64,277.62C219.06,276.88 219.52,276.18 220.04,275.51C221.37,273.8 223.01,272.35 224.87,271.25L289.06,233.39C290.42,232.59 291.87,231.96 293.39,231.51C295.53,230.87 297.77,230.6 300,230.72C302.98,230.88 305.88,231.73 308.47,233.2L373.37,269.85C375.54,271.08 377.49,272.68 379.13,274.57C379.68,275.19 380.18,275.85 380.65,276.53C380.86,276.84 381.05,277.15 381.24,277.47L397.79,266.39L420.34,252.93L420.31,252.88C417.55,248.8 413.77,245.35 409.45,242.91Z" |
||||||
|
android:fillColor="#37BF6E" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M381.24,277.47C381.51,277.92 381.77,278.38 382.01,278.84C382.21,279.24 382.39,279.65 382.57,280.06C382.91,280.88 383.19,281.73 383.41,282.59C383.74,283.88 383.92,285.21 383.93,286.57L383.93,361.1C383.96,363.95 383.35,366.77 382.16,369.36C381.93,369.86 381.69,370.35 381.42,370.83C379.75,373.79 377.32,376.27 374.39,378L310.2,415.87C307.47,417.48 304.38,418.39 301.21,418.53L301.22,439.23C301.22,439.23 301.24,449.84 301.27,464.74C306.1,464.61 310.91,463.3 315.21,460.75L410.98,404.25C419.88,399 425.31,389.37 425.22,379.03L425.22,267.85C425.17,262.48 423.34,257.34 420.34,252.93L397.79,266.39L381.24,277.47Z" |
||||||
|
android:fillColor="#3870B2" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M177.75,256.17C179.93,251.62 183.31,247.73 187.92,245L283.68,188.51C292.58,183.26 303.64,183.15 312.64,188.23L409.45,242.91C413.77,245.35 417.55,248.8 420.31,252.88L420.34,252.93L498.59,206.19C494.03,199.46 487.79,193.78 480.67,189.75L320.86,99.49C306.01,91.1 287.75,91.27 273.07,99.95L114.99,193.2C107.39,197.69 101.81,204.11 98.21,211.63L177.74,256.19L177.75,256.17ZM301.27,464.74C301.09,464.74 300.91,464.76 300.73,464.76C295.66,464.8 290.67,463.51 286.26,461.02L184.53,403.56C178.57,400.2 174.85,393.89 174.79,387.05L174.78,270.22C174.73,265.23 175.72,260.43 177.74,256.19L98.21,211.63C94.86,218.63 93.23,226.58 93.31,234.82L93.31,427.67C93.42,438.97 99.54,449.37 109.4,454.92L277.31,549.77C284.6,553.88 292.84,556.01 301.2,555.94L301.2,555.8C301.39,543.78 301.33,495.26 301.27,464.74Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M498.59,206.19L420.34,252.93C423.34,257.34 425.17,262.48 425.22,267.85L425.22,379.03C425.31,389.37 419.88,399 410.98,404.25L315.21,460.75C310.91,463.3 306.1,464.61 301.27,464.74C301.33,495.26 301.39,543.78 301.2,555.8L301.2,555.94C309.48,555.87 317.74,553.68 325.11,549.32L483.18,456.06C497.87,447.39 506.85,431.49 506.69,414.43L506.69,230.91C506.6,222.02 503.57,213.5 498.59,206.19Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
<path |
||||||
|
android:pathData="M301.2,555.94C292.84,556.01 284.6,553.88 277.31,549.76L109.4,454.92C99.54,449.37 93.42,438.97 93.31,427.67L93.31,234.82C93.23,226.58 94.86,218.63 98.21,211.63C101.81,204.11 107.39,197.69 114.99,193.2L273.07,99.95C287.75,91.27 306.01,91.1 320.86,99.49L480.67,189.75C487.79,193.78 494.03,199.46 498.59,206.19C503.57,213.5 506.6,222.02 506.69,230.91L506.69,414.43C506.85,431.49 497.87,447.39 483.18,456.06L325.11,549.32C317.74,553.68 309.48,555.87 301.2,555.94Z" |
||||||
|
android:strokeWidth="10" |
||||||
|
android:fillColor="#00000000" |
||||||
|
android:strokeColor="#083042" |
||||||
|
android:fillType="nonZero"/> |
||||||
|
</vector> |
@ -0,0 +1,13 @@ |
|||||||
|
<resources> |
||||||
|
<string name="app_name">Compose Resources App</string> |
||||||
|
<string name="hello">😊 Hello world!</string> |
||||||
|
<string name="multi_line">Lorem ipsum dolor sit amet, |
||||||
|
consectetur adipiscing elit. |
||||||
|
Donec eget turpis ac sem ultricies consequat.</string> |
||||||
|
<string name="str_template">Hello, %1$s! You have %2$d new messages.</string> |
||||||
|
<string-array name="str_arr"> |
||||||
|
<item>item 1</item> |
||||||
|
<item>item 2</item> |
||||||
|
<item>item 3</item> |
||||||
|
</string-array> |
||||||
|
</resources> |
@ -1,12 +1,19 @@ |
|||||||
[versions] |
[versions] |
||||||
kotlin = "1.9.0" |
kotlin = "1.9.0" |
||||||
gradle-download-plugin = "5.5.0" |
gradle-download-plugin = "5.5.0" |
||||||
|
kotlin-poet = "1.14.2" |
||||||
|
plugin-android = "7.3.0" |
||||||
|
shadow-jar = "8.1.1" |
||||||
|
publish-plugin = "1.2.1" |
||||||
|
|
||||||
[libraries] |
[libraries] |
||||||
download-task = { module = "de.undercouch:gradle-download-task", version.ref = "gradle-download-plugin" } |
download-task = { module = "de.undercouch:gradle-download-task", version.ref = "gradle-download-plugin" } |
||||||
|
kotlin-poet = { module = "com.squareup:kotlinpoet", version.ref = "kotlin-poet" } |
||||||
|
plugin-android = { module = "com.android.tools.build:gradle", version.ref = "plugin-android" } |
||||||
|
plugin-android-api = { module = "com.android.tools.build:gradle-api", version.ref = "plugin-android" } |
||||||
|
|
||||||
[plugins] |
[plugins] |
||||||
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } |
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } |
||||||
shadow-jar = "com.github.johnrengelman.shadow:8.1.1" |
|
||||||
download = { id = "de.undercouch.download", version.ref = "gradle-download-plugin" } |
download = { id = "de.undercouch.download", version.ref = "gradle-download-plugin" } |
||||||
publish-plugin-portal = "com.gradle.plugin-publish:1.2.1" |
shadow-jar = { id = "com.github.johnrengelman.shadow", version.ref = "shadow-jar" } |
||||||
|
publish-plugin = { id = "com.gradle.plugin-publish", version.ref = "publish-plugin" } |
||||||
|
Loading…
Reference in new issue