diff --git a/buildSrc/src/main/kotlin/IdeaConfiguration.kt b/buildSrc/src/main/kotlin/IdeaConfiguration.kt index 45ee2b07c7..6236618bae 100644 --- a/buildSrc/src/main/kotlin/IdeaConfiguration.kt +++ b/buildSrc/src/main/kotlin/IdeaConfiguration.kt @@ -1,47 +1,46 @@ -import java.util.concurrent.atomic.AtomicBoolean import org.gradle.api.Project import org.gradle.api.provider.Property import org.gradle.jvm.toolchain.JavaLanguageVersion +import java.util.concurrent.atomic.AtomicBoolean enum class SupportedIJVersion { - IJ_232, - IJ_233 + IJ_232, + IJ_233 } private var warned = AtomicBoolean(false) fun Project.supportedIJVersion(): SupportedIJVersion { - val prop = - kotlin - .runCatching { - rootProject.findProperty("supported.ij.version")?.toString() - ?: localProperty("supported.ij.version") - } - .getOrNull() + val prop = + kotlin + .runCatching { + rootProject.findProperty("supported.ij.version")?.toString() + ?: localProperty("supported.ij.version") + } + .getOrNull() - if (prop == null) { - if (!warned.getAndSet(true)) { - logger.warn( - """ - No 'supported.ij.version' property provided. Falling back to IJ 233. - It is recommended to provide it using local.properties file or -Psupported.ij.version to avoid unexpected behavior. + if (prop == null) { + if (!warned.getAndSet(true)) { + logger.warn( """ - .trimIndent() - ) + No 'supported.ij.version' property provided. Falling back to IJ 233. + It is recommended to provide it using local.properties file or -Psupported.ij.version to + avoid unexpected behavior. + """.trimIndent() + ) + } + return SupportedIJVersion.IJ_233 } - return SupportedIJVersion.IJ_233 - } - return when (prop) { - "232" -> SupportedIJVersion.IJ_232 - "233" -> SupportedIJVersion.IJ_233 - else -> - error( - "Invalid 'supported.ij.version' with value '$prop' is provided. " + - "It should be in set of these values: ('232', '233')" - ) - } + return when (prop) { + "232" -> SupportedIJVersion.IJ_232 + "233" -> SupportedIJVersion.IJ_233 + else -> + error( + "Invalid 'supported.ij.version' with value '$prop' is provided. " + + "It should be one of these values: ('232', '233')" + ) + } } -fun Property.assign(version: Int) = - set(JavaLanguageVersion.of(version)) +fun Property.assign(version: Int) = set(JavaLanguageVersion.of(version)) diff --git a/buildSrc/src/main/kotlin/LocalProperties.kt b/buildSrc/src/main/kotlin/LocalProperties.kt index 4480a839f1..260845cb26 100644 --- a/buildSrc/src/main/kotlin/LocalProperties.kt +++ b/buildSrc/src/main/kotlin/LocalProperties.kt @@ -1,12 +1,12 @@ -import java.util.Properties import org.gradle.api.Project +import java.util.Properties internal fun Project.localProperty(propertyName: String): String? { - val localPropertiesFile = rootProject.file("local.properties") - if (!localPropertiesFile.exists()) { - return null - } - val properties = Properties() - localPropertiesFile.inputStream().use { properties.load(it) } - return properties.getProperty(propertyName) + val localPropertiesFile = rootProject.file("local.properties") + if (!localPropertiesFile.exists()) { + return null + } + val properties = Properties() + localPropertiesFile.inputStream().use { properties.load(it) } + return properties.getProperty(propertyName) } diff --git a/buildSrc/src/main/kotlin/MergeSarifTask.kt b/buildSrc/src/main/kotlin/MergeSarifTask.kt index 72abdfbf8c..996796fa55 100644 --- a/buildSrc/src/main/kotlin/MergeSarifTask.kt +++ b/buildSrc/src/main/kotlin/MergeSarifTask.kt @@ -9,48 +9,54 @@ import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.SourceTask import org.gradle.api.tasks.TaskAction +private const val SARIF_SCHEMA = + "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json" + @CacheableTask open class MergeSarifTask : SourceTask() { - init { - group = "verification" - } - - @get:OutputFile - val mergedSarifPath: RegularFileProperty = - project.objects - .fileProperty() - .convention(project.layout.buildDirectory.file("reports/static-analysis.sarif")) - - @TaskAction - fun merge() { - val json = Json { prettyPrint = true } - - logger.lifecycle("Merging ${source.files.size} SARIF file(s)...") - logger.lifecycle( - source.files.joinToString("\n") { " * ~${it.path.removePrefix(project.rootDir.path)}" } - ) - - val merged = - SarifSchema210( - schema = - "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", - version = Version.The210, - runs = - source.files - .asSequence() - .filter { it.extension == "sarif" } - .map { file -> file.inputStream().use { json.decodeFromStream(it) } } - .flatMap { report -> report.runs } - .groupBy { run -> run.tool.driver.guid ?: run.tool.driver.name } - .values - .asSequence() - .filter { it.isNotEmpty() } - .map { run -> run.first().copy(results = run.flatMap { it.results ?: emptyList() }) } - .toList() - ) - logger.lifecycle("Merged SARIF file contains ${merged.runs.size} run(s)") - logger.info("Writing merged SARIF file to $mergedSarifPath...") - mergedSarifPath.asFile.get().outputStream().use { json.encodeToStream(merged, it) } - } + init { + group = "verification" + } + + @get:OutputFile + val mergedSarifPath: RegularFileProperty = + project.objects + .fileProperty() + .convention(project.layout.buildDirectory.file("reports/static-analysis.sarif")) + + @TaskAction + fun merge() { + val json = Json { prettyPrint = true } + + logger.lifecycle("Merging ${source.files.size} SARIF file(s)...") + logger.lifecycle( + source.files.joinToString("\n") { " * ~${it.path.removePrefix(project.rootDir.path)}" } + ) + + val merged = + SarifSchema210( + schema = SARIF_SCHEMA, + version = Version.The210, + runs = source.files + .asSequence() + .filter { it.extension == "sarif" } + .map { file -> + file.inputStream().use { json.decodeFromStream(it) } + } + .flatMap { report -> report.runs } + .groupBy { run -> run.tool.driver.guid ?: run.tool.driver.name } + .values + .asSequence() + .filter { it.isNotEmpty() } + .map { run -> + run.first().copy(results = run.flatMap { it.results ?: emptyList() }) + } + .toList() + ) + + logger.lifecycle("Merged SARIF file contains ${merged.runs.size} run(s)") + logger.info("Writing merged SARIF file to $mergedSarifPath...") + mergedSarifPath.asFile.get().outputStream().use { json.encodeToStream(merged, it) } + } } diff --git a/buildSrc/src/main/kotlin/ValidatePublicApiTask.kt b/buildSrc/src/main/kotlin/ValidatePublicApiTask.kt index 56eeee1afc..c97e3c00b4 100644 --- a/buildSrc/src/main/kotlin/ValidatePublicApiTask.kt +++ b/buildSrc/src/main/kotlin/ValidatePublicApiTask.kt @@ -1,103 +1,102 @@ -import java.io.File -import java.util.Stack import org.gradle.api.GradleException import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.SourceTask import org.gradle.api.tasks.TaskAction +import java.io.File +import java.util.Stack @CacheableTask open class ValidatePublicApiTask : SourceTask() { - init { - group = "verification" + init { + group = "verification" - // The output is never really used, it is here for cacheability reasons only - outputs.file(project.layout.buildDirectory.file("apiValidationRun")) - } + // The output is never really used, it is here for cacheability reasons only + outputs.file(project.layout.buildDirectory.file("apiValidationRun")) + } - private val classFqnRegex = "public (?:\\w+ )*class (\\S+)\\b".toRegex() + private val classFqnRegex = "public (?:\\w+ )*class (\\S+)\\b".toRegex() - @Suppress( - "ConvertToStringTemplate" - ) // The odd concatenation is needed because of $; escapes get confused - private val copyMethodRegex = - ("public static synthetic fun copy(-\\w+)?" + "\\$" + "default\\b").toRegex() + @Suppress("ConvertToStringTemplate") // The odd concatenation is needed because of $; escapes get confused + private val copyMethodRegex = + ("public static synthetic fun copy(-\\w+)?" + "\\$" + "default\\b").toRegex() - @TaskAction - fun validatePublicApi() { - logger.info("Validating ${source.files.size} API file(s)...") + @TaskAction + fun validatePublicApi() { + logger.info("Validating ${source.files.size} API file(s)...") - val violations = mutableMapOf>() - inputs.files.forEach { apiFile -> - logger.lifecycle("Validating public API from file ${apiFile.path}") + val violations = mutableMapOf>() + inputs.files.forEach { apiFile -> + logger.lifecycle("Validating public API from file ${apiFile.path}") - apiFile.useLines { lines -> - val actualDataClasses = findDataClasses(lines) + apiFile.useLines { lines -> + val actualDataClasses = findDataClasses(lines) - if (actualDataClasses.isNotEmpty()) { - violations[apiFile] = actualDataClasses + if (actualDataClasses.isNotEmpty()) { + violations[apiFile] = actualDataClasses + } + } + } + + if (violations.isNotEmpty()) { + val message = buildString { + appendLine("Data classes found in public API.") + appendLine() + + for ((file, dataClasses) in violations.entries) { + appendLine("In file ${file.path}:") + for (dataClass in dataClasses) { + appendLine(" * ${dataClass.replace("/", ".")}") + } + appendLine() + } + } + + throw GradleException(message) + } else { + logger.lifecycle("No public API violations found.") } - } } - if (violations.isNotEmpty()) { - val message = buildString { - appendLine("Data classes found in public API.") - appendLine() - - for ((file, dataClasses) in violations.entries) { - appendLine("In file ${file.path}:") - for (dataClass in dataClasses) { - appendLine(" * ${dataClass.replace("/", ".")}") - } - appendLine() + private fun findDataClasses(lines: Sequence): Set { + val currentClassStack = Stack() + val dataClasses = mutableMapOf() + + for (line in lines) { + if (line.isBlank()) continue + + val matchResult = classFqnRegex.find(line) + if (matchResult != null) { + val classFqn = matchResult.groupValues[1] + currentClassStack.push(classFqn) + continue + } + + if (line.contains("}")) { + currentClassStack.pop() + continue + } + + val fqn = currentClassStack.peek() + if (copyMethodRegex.find(line) != null) { + val info = dataClasses.getOrPut(fqn) { DataClassInfo(fqn) } + info.hasCopyMethod = true + } else if (line.contains("public static final synthetic fun box-impl")) { + val info = dataClasses.getOrPut(fqn) { DataClassInfo(fqn) } + info.isLikelyValueClass = true + } } - } - throw GradleException(message) - } else { - logger.lifecycle("No public API violations found.") + val actualDataClasses = + dataClasses.filterValues { it.hasCopyMethod && !it.isLikelyValueClass } + .keys + return actualDataClasses } - } - - private fun findDataClasses(lines: Sequence): Set { - val currentClassStack = Stack() - val dataClasses = mutableMapOf() - - for (line in lines) { - if (line.isBlank()) continue - - val matchResult = classFqnRegex.find(line) - if (matchResult != null) { - val classFqn = matchResult.groupValues[1] - currentClassStack.push(classFqn) - continue - } - - if (line.contains("}")) { - currentClassStack.pop() - continue - } - - val fqn = currentClassStack.peek() - if (copyMethodRegex.find(line) != null) { - val info = dataClasses.getOrPut(fqn) { DataClassInfo(fqn) } - info.hasCopyMethod = true - } else if (line.contains("public static final synthetic fun box-impl")) { - val info = dataClasses.getOrPut(fqn) { DataClassInfo(fqn) } - info.isLikelyValueClass = true - } - } - - val actualDataClasses = - dataClasses.filterValues { it.hasCopyMethod && !it.isLikelyValueClass }.keys - return actualDataClasses - } } @Suppress("DataClassShouldBeImmutable") // Only used in a loop, saves memory and is faster private data class DataClassInfo( - val fqn: String, - var hasCopyMethod: Boolean = false, - var isLikelyValueClass: Boolean = false, + val fqn: String, + var hasCopyMethod: Boolean = false, + var isLikelyValueClass: Boolean = false, ) diff --git a/buildSrc/src/main/kotlin/jewel-check-public-api.gradle.kts b/buildSrc/src/main/kotlin/jewel-check-public-api.gradle.kts index 05f3b5e62a..a87d626618 100644 --- a/buildSrc/src/main/kotlin/jewel-check-public-api.gradle.kts +++ b/buildSrc/src/main/kotlin/jewel-check-public-api.gradle.kts @@ -3,6 +3,7 @@ plugins { id("org.jetbrains.kotlinx.binary-compatibility-validator") id("dev.drewhamilton.poko") + kotlin("jvm") } apiValidation { @@ -14,7 +15,13 @@ apiValidation { nonPublicMarkers.add("org.jetbrains.jewel.InternalJewelApi") } -poko { pokoAnnotation = "org.jetbrains.jewel.foundation.GenerateDataFunctions" } +poko { + pokoAnnotation = "org.jetbrains.jewel.foundation.GenerateDataFunctions" +} + +kotlin { + explicitApi() +} tasks { val validatePublicApi = diff --git a/buildSrc/src/main/kotlin/jewel.gradle.kts b/buildSrc/src/main/kotlin/jewel.gradle.kts index 8db0eb7426..cea2157c03 100644 --- a/buildSrc/src/main/kotlin/jewel.gradle.kts +++ b/buildSrc/src/main/kotlin/jewel.gradle.kts @@ -29,8 +29,6 @@ kotlin { languageVersion = 17 } - explicitApi() - target { compilations.all { kotlinOptions { freeCompilerArgs += "-Xcontext-receivers" } } sourceSets.all { diff --git a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/AndroidStudioReleases.kt b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/AndroidStudioReleases.kt index 8bfe56d118..cea52722b3 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/AndroidStudioReleases.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/AndroidStudioReleases.kt @@ -3,8 +3,6 @@ package org.jetbrains.jewel.buildlogic.demodata import com.squareup.kotlinpoet.ClassName import gradle.kotlin.dsl.accessors._c011fd04eb69b06af6f445fec200c5f6.main import gradle.kotlin.dsl.accessors._c011fd04eb69b06af6f445fec200c5f6.sourceSets -import java.io.File -import java.net.URL import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream import org.gradle.api.DefaultTask @@ -18,59 +16,67 @@ import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.gradle.kotlin.dsl.property import org.gradle.kotlin.dsl.setProperty +import java.io.File +import java.net.URL open class StudioVersionsGenerationExtension(project: Project) { - val targetDir: DirectoryProperty = - project.objects - .directoryProperty() - .convention(project.layout.buildDirectory.dir("generated/studio-releases/")) + val targetDir: DirectoryProperty = + project.objects + .directoryProperty() + .convention(project.layout.buildDirectory.dir("generated/studio-releases/")) - val resourcesDirs: SetProperty = - project.objects.setProperty().convention(project.sourceSets.main.get().resources.srcDirs) + val resourcesDirs: SetProperty = + project.objects + .setProperty() + .convention(project.sourceSets.main.get().resources.srcDirs) - val dataUrl: Property = - project.objects.property().convention("https://jb.gg/android-studio-releases-list.json") + val dataUrl: Property = + project.objects + .property() + .convention("https://jb.gg/android-studio-releases-list.json") } internal const val STUDIO_RELEASES_OUTPUT_CLASS_NAME = - "org.jetbrains.jewel.samples.ideplugin.releasessample.AndroidStudioReleases" + "org.jetbrains.jewel.samples.ideplugin.releasessample.AndroidStudioReleases" open class AndroidStudioReleasesGeneratorTask : DefaultTask() { - @get:OutputFile val outputFile: RegularFileProperty = project.objects.fileProperty() + @get:OutputFile + val outputFile: RegularFileProperty = project.objects.fileProperty() - @get:Input val dataUrl = project.objects.property() + @get:Input + val dataUrl = project.objects.property() - @get:Input val resourcesDirs = project.objects.setProperty() + @get:Input + val resourcesDirs = project.objects.setProperty() - init { - group = "jewel" - } - - @TaskAction - fun generate() { - val json = Json { - ignoreUnknownKeys = true - isLenient = true + init { + group = "jewel" } - val url = dataUrl.get() - val lookupDirs = resourcesDirs.get() - logger.lifecycle("Fetching Android Studio releases list from $url...") - logger.debug( - "Registered resources directories:\n" + - lookupDirs.joinToString("\n") { " * ${it.absolutePath}" } - ) - val releases = URL(url).openStream().use { json.decodeFromStream(it) } + @TaskAction + fun generate() { + val json = Json { + ignoreUnknownKeys = true + isLenient = true + } + val url = dataUrl.get() + val lookupDirs = resourcesDirs.get() + + logger.lifecycle("Fetching Android Studio releases list from $url...") + logger.debug( + "Registered resources directories:\n" + + lookupDirs.joinToString("\n") { " * ${it.absolutePath}" } + ) + val releases = URL(url).openStream() + .use { json.decodeFromStream(it) } - val className = ClassName.bestGuess(STUDIO_RELEASES_OUTPUT_CLASS_NAME) - val file = AndroidStudioReleasesReader.readFrom(releases, className, url, lookupDirs) + val className = ClassName.bestGuess(STUDIO_RELEASES_OUTPUT_CLASS_NAME) + val file = AndroidStudioReleasesReader.readFrom(releases, className, url, lookupDirs) - val outputFile = outputFile.get().asFile - outputFile.bufferedWriter().use { file.writeTo(it) } - logger.lifecycle( - "Android Studio releases from $url parsed and code generated into ${outputFile.path}" - ) - } + val outputFile = outputFile.get().asFile + outputFile.bufferedWriter().use { file.writeTo(it) } + logger.lifecycle("Android Studio releases from $url parsed and code generated into ${outputFile.path}") + } } diff --git a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/AndroidStudioReleasesReader.kt b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/AndroidStudioReleasesReader.kt index 42f34ebd90..634e562197 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/AndroidStudioReleasesReader.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/AndroidStudioReleasesReader.kt @@ -13,162 +13,160 @@ import java.io.File import java.time.ZonedDateTime private val ContentItemClassName = - ClassName.bestGuess( - "org.jetbrains.jewel.samples.ideplugin.releasessample.ContentItem.AndroidStudio" - ) + ClassName.bestGuess("org.jetbrains.jewel.samples.ideplugin.releasessample.ContentItem.AndroidStudio") internal object AndroidStudioReleasesReader { - fun readFrom( - releases: ApiAndroidStudioReleases, - className: ClassName, - url: String, - resourceDirs: Set, - ) = - FileSpec.builder(className) - .apply { - indent(" ") - addFileComment("Generated by the Jewel Android Studio Releases Generator\n") - addFileComment("Generated from $url on ${ZonedDateTime.now()}\n") - - addImport( - "org.jetbrains.jewel.samples.ideplugin.releasessample", - "ContentItem.AndroidStudio" - ) - addImport("kotlinx.datetime", "LocalDate") + fun readFrom( + releases: ApiAndroidStudioReleases, + className: ClassName, + url: String, + resourceDirs: Set, + ) = + FileSpec.builder(className) + .apply { + indent(" ") + addFileComment("Generated by the Jewel Android Studio Releases Generator\n") + addFileComment("Generated from $url on ${ZonedDateTime.now()}\n") - addType( - TypeSpec.objectBuilder(className) - .superclass( - ClassName.bestGuess( - "org.jetbrains.jewel.samples.ideplugin.releasessample.ContentSource" - ) + addImport("org.jetbrains.jewel.samples.ideplugin.releasessample", "ContentItem.AndroidStudio") + addImport("kotlinx.datetime", "LocalDate") + + addType(createBaseTypeSpec(className, releases, resourceDirs)) + } + .build() + + private fun createBaseTypeSpec( + className: ClassName, + releases: ApiAndroidStudioReleases, + resourceDirs: Set, + ) = TypeSpec.objectBuilder(className) + .superclass( + ClassName.bestGuess("org.jetbrains.jewel.samples.ideplugin.releasessample.ContentSource") .parameterizedBy(ContentItemClassName) - ) - .apply { - addProperty( + ) + .apply { + addProperty( PropertySpec.builder( name = "items", - type = List::class.asClassName().parameterizedBy(ContentItemClassName), + type = + List::class.asClassName().parameterizedBy(ContentItemClassName), KModifier.OVERRIDE - ) - .initializer(readReleases(releases, resourceDirs)) - .build() - ) + ) + .initializer(readReleases(releases, resourceDirs)) + .build() + ) - addProperty( + addProperty( PropertySpec.builder( "displayName", type = String::class.asClassName(), KModifier.OVERRIDE - ) - .initializer("\"%L\"", "Android Studio releases") - .build() - ) + ) + .initializer("\"%L\"", "Android Studio releases") + .build() + ) + } + .build() + + private fun readReleases(releases: ApiAndroidStudioReleases, resourceDirs: Set) = + releases.content.item + .map { readRelease(it, resourceDirs) } + .joinToCode(prefix = "listOf(\n", separator = ",\n", suffix = ")") + + private fun readRelease( + release: ApiAndroidStudioReleases.Content.Item, + resourceDirs: Set, + ) = + CodeBlock.builder() + .apply { + add("AndroidStudio(\n") + add(" displayText = \"%L\",\n", release.name) + add(" imagePath = %L,\n", imagePathForOrNull(release, resourceDirs)) + add(" versionName = \"%L\",\n", release.version) + add(" build = \"%L\",\n", release.build) + add(" platformBuild = \"%L\",\n", release.platformBuild) + add(" platformVersion = \"%L\",\n", release.platformVersion) + add(" channel = %L,\n", readChannel(release.channel)) + add(" releaseDate = LocalDate(%L),\n", translateDate(release.date)) + add(" key = \"%L\",\n", release.build) + add(")") } .build() - ) - } - .build() - - private fun readReleases(releases: ApiAndroidStudioReleases, resourceDirs: Set) = - releases.content.item - .map { readRelease(it, resourceDirs) } - .joinToCode(prefix = "listOf(\n", separator = ",\n", suffix = ")") - - private fun readRelease(release: ApiAndroidStudioReleases.Content.Item, resourceDirs: Set) = - CodeBlock.builder() - .apply { - add("AndroidStudio(\n") - add(" displayText = \"%L\",\n", release.name) - add(" imagePath = %L,\n", imagePathForOrNull(release, resourceDirs)) - add(" versionName = \"%L\",\n", release.version) - add(" build = \"%L\",\n", release.build) - add(" platformBuild = \"%L\",\n", release.platformBuild) - add(" platformVersion = \"%L\",\n", release.platformVersion) - add(" channel = %L,\n", readChannel(release.channel)) - add(" releaseDate = LocalDate(%L),\n", translateDate(release.date)) - add(" key = \"%L\",\n", release.build) - add(")") - } - .build() - - private fun imagePathForOrNull( - release: ApiAndroidStudioReleases.Content.Item, - resourceDirs: Set - ): String? { - // Take the release animal from the name, remove spaces and voila' - val releaseAnimal = - release.name.substringBefore(" | ").substringAfter("Android Studio").trim().replace(" ", "") - - if (releaseAnimal.isEmpty() || releaseAnimal.any { it.isDigit() }) return null - - // We only have stable and canary splash screens. Betas use the stable ones. - val channel = - release.channel.lowercase().let { - when (it) { - "release", - "rc", - "stable", - "beta", - "patch" -> "stable" - "canary", - "preview", - "alpha" -> "canary" - else -> { - println(" Note: channel '${it}' isn't supported for splash screens") - null - } + + private fun imagePathForOrNull( + release: ApiAndroidStudioReleases.Content.Item, + resourceDirs: Set, + ): String? { + // Take the release animal from the name, remove spaces and voila' + val releaseAnimal = + release.name + .substringBefore(" | ") + .substringAfter("Android Studio") + .trim() + .replace(" ", "") + + if (releaseAnimal.isEmpty() || releaseAnimal.any { it.isDigit() }) return null + + // We only have stable and canary splash screens. Betas use the stable ones. + val channel = + release.channel.lowercase().let { + when (it) { + "release", "rc", "stable", "beta", "patch" -> "stable" + "canary", "preview", "alpha" -> "canary" + else -> { + println(" Note: channel '${it}' isn't supported for splash screens") + null + } + } + } ?: return null + + val splashPath = "/studio-splash-screens/$releaseAnimal-$channel.png" + val splashFiles = resourceDirs.map { dir -> File(dir, splashPath) } + if (splashFiles.none { it.isFile }) { + println(" Note: expected splash screen file doesn't exist: '${splashPath}'") + return null } - } ?: return null - val splashPath = "/studio-splash-screens/$releaseAnimal-$channel.png" - val splashFiles = resourceDirs.map { dir -> File(dir, splashPath) } - if (splashFiles.none { it.isFile }) { - println(" Note: expected splash screen file doesn't exist: '${splashPath}'") - return null + return "\"$splashPath\"" } - return "\"$splashPath\"" - } + // This is the laziest crap ever, I am sorry. + private fun translateDate(rawDate: String): String { + val month = rawDate.substringBefore(" ").trimStart('0') + val year = rawDate.substringAfterLast(" ".trimStart('0')) + val day = + rawDate.substring(month.length + 1, rawDate.length - year.length - 1).trimStart('0') - // This is the laziest crap ever, I am sorry. - private fun translateDate(rawDate: String): String { - val month = rawDate.substringBefore(" ").trimStart('0') - val year = rawDate.substringAfterLast(" ".trimStart('0')) - val day = rawDate.substring(month.length + 1, rawDate.length - year.length - 1).trimStart('0') + if (day.isEmpty()) { + println("$rawDate\nMonth: '$month'\nYear: '$year'") + } - if (day.isEmpty()) { - println("$rawDate\nMonth: '$month'\nYear: '$year'") - } + val monthNumber = + when (month.trim().lowercase()) { + "january" -> 1 + "february" -> 2 + "march" -> 3 + "april" -> 4 + "may" -> 5 + "june" -> 6 + "july" -> 7 + "august" -> 8 + "september" -> 9 + "october" -> 10 + "november" -> 11 + "december" -> 12 + else -> error("Unrecognized month: $month") + } - val monthNumber = - when (month.trim().lowercase()) { - "january" -> 1 - "february" -> 2 - "march" -> 3 - "april" -> 4 - "may" -> 5 - "june" -> 6 - "july" -> 7 - "august" -> 8 - "september" -> 9 - "october" -> 10 - "november" -> 11 - "december" -> 12 - else -> error("Unrecognized month: $month") - } - - return "$year, $monthNumber, $day" - } - - private fun readChannel(rawChannel: String) = - when (rawChannel.lowercase().trim()) { - "stable", - "patch", - "release" -> "ReleaseChannel.Stable" - "beta" -> "ReleaseChannel.Beta" - "canary" -> "ReleaseChannel.Canary" - else -> "ReleaseChannel.Other" + return "$year, $monthNumber, $day" } + + private fun readChannel(rawChannel: String) = + when (rawChannel.lowercase().trim()) { + "stable", "patch", "release" -> "ReleaseChannel.Stable" + "beta" -> "ReleaseChannel.Beta" + "canary" -> "ReleaseChannel.Canary" + else -> "ReleaseChannel.Other" + } } diff --git a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/ApiAndroidStudioReleases.kt b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/ApiAndroidStudioReleases.kt index 24b96bab3a..b028de096f 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/ApiAndroidStudioReleases.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/demodata/ApiAndroidStudioReleases.kt @@ -5,33 +5,33 @@ import kotlinx.serialization.Serializable @Serializable internal data class ApiAndroidStudioReleases( - @SerialName("content") val content: Content = Content() + @SerialName("content") val content: Content = Content(), ) { - @Serializable - internal data class Content( - @SerialName("item") val item: List = listOf(), - @SerialName("version") val version: Int = 0 - ) { - @Serializable - internal data class Item( - @SerialName("build") val build: String, - @SerialName("channel") val channel: String, - @SerialName("date") val date: String, - @SerialName("download") val download: List = listOf(), - @SerialName("name") val name: String, - @SerialName("platformBuild") val platformBuild: String, - @SerialName("platformVersion") val platformVersion: String, - @SerialName("version") val version: String + internal data class Content( + @SerialName("item") val item: List = listOf(), + @SerialName("version") val version: Int = 0, ) { - @Serializable - internal data class Download( - @SerialName("checksum") val checksum: String, - @SerialName("link") val link: String, - @SerialName("size") val size: String - ) + @Serializable + internal data class Item( + @SerialName("build") val build: String, + @SerialName("channel") val channel: String, + @SerialName("date") val date: String, + @SerialName("download") val download: List = listOf(), + @SerialName("name") val name: String, + @SerialName("platformBuild") val platformBuild: String, + @SerialName("platformVersion") val platformVersion: String, + @SerialName("version") val version: String, + ) { + + @Serializable + internal data class Download( + @SerialName("checksum") val checksum: String, + @SerialName("link") val link: String, + @SerialName("size") val size: String, + ) + } } - } } diff --git a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/ideversion/ApiIdeaReleases.kt b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/ideversion/ApiIdeaReleases.kt deleted file mode 100644 index e9b83200b0..0000000000 --- a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/ideversion/ApiIdeaReleases.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.jetbrains.jewel.buildlogic.ideversion - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -internal data class ApiIdeaReleasesItem( - @SerialName("code") val code: String, - @SerialName("releases") val releases: List, -) { - - @Serializable - internal data class Release( - @SerialName("build") val build: String, - @SerialName("type") val type: String, - @SerialName("version") val version: String, - ) -} diff --git a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/ideversion/ApiIdeaReleasesItem.kt b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/ideversion/ApiIdeaReleasesItem.kt new file mode 100644 index 0000000000..12c6704a14 --- /dev/null +++ b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/ideversion/ApiIdeaReleasesItem.kt @@ -0,0 +1,18 @@ +package org.jetbrains.jewel.buildlogic.ideversion + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +internal data class ApiIdeaReleasesItem( + @SerialName("code") val code: String, + @SerialName("releases") val releases: List, +) { + + @Serializable + internal data class Release( + @SerialName("build") val build: String, + @SerialName("type") val type: String, + @SerialName("version") val version: String, + ) +} diff --git a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/ideversion/CheckIdeaVersionTask.kt b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/ideversion/CheckIdeaVersionTask.kt index c031c68c49..d5fe7fc6e9 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/ideversion/CheckIdeaVersionTask.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/ideversion/CheckIdeaVersionTask.kt @@ -1,175 +1,165 @@ package org.jetbrains.jewel.buildlogic.ideversion import SupportedIJVersion -import java.io.IOException -import java.net.URL import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.tasks.TaskAction import supportedIJVersion +import java.io.IOException +import java.net.URL open class CheckIdeaVersionTask : DefaultTask() { - private val releasesUrl = - "https://data.services.jetbrains.com/products?" + - "fields=code,releases,releases.version,releases.build,releases.type&" + - "code=IC" - - private val versionRegex = - "2\\d{2}\\.\\d+\\.\\d+(?:-EAP-SNAPSHOT)?".toRegex(RegexOption.IGNORE_CASE) + private val releasesUrl = + "https://data.services.jetbrains.com/products?" + + "fields=code,releases,releases.version,releases.build,releases.type&" + + "code=IC" - init { - group = "jewel" + private val versionRegex = + "2\\d{2}\\.\\d+\\.\\d+(?:-EAP-SNAPSHOT)?".toRegex(RegexOption.IGNORE_CASE) - val currentPlatformVersion = project.supportedIJVersion() - enabled = project.name.endsWith(getPlatformSuffix(currentPlatformVersion)) - } + init { + group = "jewel" - private fun getPlatformSuffix(currentPlatformVersion: SupportedIJVersion) = - when (currentPlatformVersion) { - SupportedIJVersion.IJ_232 -> "232" - SupportedIJVersion.IJ_233 -> "233" + val currentPlatformVersion = project.supportedIJVersion() + enabled = project.name.endsWith(getPlatformSuffix(currentPlatformVersion)) } - @TaskAction - fun generate() { - val json = Json { - ignoreUnknownKeys = true - isLenient = true - } + private fun getPlatformSuffix(currentPlatformVersion: SupportedIJVersion) = + when (currentPlatformVersion) { + SupportedIJVersion.IJ_232 -> "232" + SupportedIJVersion.IJ_233 -> "233" + } - logger.lifecycle("Fetching IntelliJ Platform releases from $releasesUrl...") - val icReleases = - try { - URL(releasesUrl) - .openStream() - .use { json.decodeFromStream>(it) } - .first() - } catch (e: IOException) { - logger.warn( - "Couldn't fetch IJ Platform releases, can't check for updates.\n" + - "Cause: ${e::class.qualifiedName} — ${e.message}" - ) - return - } catch (e: RuntimeException) { - logger.error( - "Unexpected error while fetching IJ Platform releases, can't check for updates.", - e - ) - return - } - - check(icReleases.code == "IIC") { "Was expecting code IIC but was ${icReleases.code}" } - check(icReleases.releases.isNotEmpty()) { - "Was expecting to have releases but the list is empty" - } + @TaskAction + fun generate() { + val json = Json { + ignoreUnknownKeys = true + isLenient = true + } - val currentPlatformVersion = project.supportedIJVersion() - val majorPlatformVersion = getRawPlatformVersion(currentPlatformVersion) - val rawPlatformBuild = readPlatformBuild(currentPlatformVersion) - - val isCurrentBuildStable = !rawPlatformBuild.contains("EAP") - val latestAvailableBuild = - icReleases.releases - .asSequence() - .filter { it.version.startsWith(majorPlatformVersion) } - .filter { if (isCurrentBuildStable) it.type == "release" else true } - .sortedWith(ReleaseComparator) - .last() - logger.info( - "The latest IntelliJ Platform $majorPlatformVersion build is ${latestAvailableBuild.build}" - ) - - val currentPlatformBuild = rawPlatformBuild.substringBefore('-') - if (VersionComparator.compare(currentPlatformBuild, latestAvailableBuild.build) < 0) { - throw GradleException( - buildString { - appendLine("IntelliJ Platform version dependency is out of date.") - appendLine() - appendLine("Current build: $rawPlatformBuild") - append("Latest build: ${latestAvailableBuild.build}") - if (!isCurrentBuildStable) append("-EAP-SNAPSHOT") - appendLine() - append("Detected channel: ") - appendLine(if (isCurrentBuildStable) "stable" else "non-stable (eap/beta/rc)") + logger.lifecycle("Fetching IntelliJ Platform releases from $releasesUrl...") + val icReleases = + try { + URL(releasesUrl) + .openStream() + .use { json.decodeFromStream>(it) } + .first() + } catch (e: IOException) { + logger.warn( + "Couldn't fetch IJ Platform releases, can't check for updates.\n" + + "Cause: ${e::class.qualifiedName} — ${e.message}" + ) + return + } catch (e: RuntimeException) { + logger.error("Unexpected error while fetching IJ Platform releases, can't check for updates.", e) + return + } + + check(icReleases.code == "IIC") { "Was expecting code IIC but was ${icReleases.code}" } + check(icReleases.releases.isNotEmpty()) { "Was expecting to have releases but the list is empty" } + + val currentPlatformVersion = project.supportedIJVersion() + val majorPlatformVersion = getRawPlatformVersion(currentPlatformVersion) + val rawPlatformBuild = readPlatformBuild(currentPlatformVersion) + + val isCurrentBuildStable = !rawPlatformBuild.contains("EAP") + val latestAvailableBuild = + icReleases.releases + .asSequence() + .filter { it.version.startsWith(majorPlatformVersion) } + .filter { if (isCurrentBuildStable) it.type == "release" else true } + .sortedWith(ReleaseComparator) + .last() + logger.info("The latest IntelliJ Platform $majorPlatformVersion build is ${latestAvailableBuild.build}") + + val currentPlatformBuild = rawPlatformBuild.substringBefore('-') + if (VersionComparator.compare(currentPlatformBuild, latestAvailableBuild.build) < 0) { + throw GradleException( + buildString { + appendLine("IntelliJ Platform version dependency is out of date.") + appendLine() + appendLine("Current build: $rawPlatformBuild") + append("Latest build: ${latestAvailableBuild.build}") + if (!isCurrentBuildStable) append("-EAP-SNAPSHOT") + appendLine() + append("Detected channel: ") + appendLine(if (isCurrentBuildStable) "stable" else "non-stable (eap/beta/rc)") + }) } - ) - } - logger.lifecycle( - "No IntelliJ Platform version updates available. Current: $currentPlatformBuild" - ) - } - - private fun getRawPlatformVersion(currentPlatformVersion: SupportedIJVersion) = - when (currentPlatformVersion) { - SupportedIJVersion.IJ_232 -> "2023.2" - SupportedIJVersion.IJ_233 -> "2023.3" + logger.lifecycle("No IntelliJ Platform version updates available. Current: $currentPlatformBuild") } - private fun readPlatformBuild(platformVersion: SupportedIJVersion): String { - val catalogFile = project.rootProject.file("gradle/libs.versions.toml") - val dependencyName = - when (platformVersion) { - SupportedIJVersion.IJ_232 -> "idea232" - SupportedIJVersion.IJ_233 -> "idea233" - } - - val catalogDependencyLine = - catalogFile.useLines { lines -> lines.find { it.startsWith(dependencyName) } } - ?: throw GradleException( - "Unable to find IJP dependency '$dependencyName' in the catalog file '${catalogFile.path}'" - ) - - val dependencyVersion = - catalogDependencyLine.substringAfter(dependencyName).trimStart(' ', '=').trimEnd().trim('"') - - if (!dependencyVersion.matches(versionRegex)) { - throw GradleException("Invalid IJP version found in version catalog: '$dependencyVersion'") - } + private fun getRawPlatformVersion(currentPlatformVersion: SupportedIJVersion) = + when (currentPlatformVersion) { + SupportedIJVersion.IJ_232 -> "2023.2" + SupportedIJVersion.IJ_233 -> "2023.3" + } + + private fun readPlatformBuild(platformVersion: SupportedIJVersion): String { + val catalogFile = project.rootProject.file("gradle/libs.versions.toml") + val dependencyName = + when (platformVersion) { + SupportedIJVersion.IJ_232 -> "idea232" + SupportedIJVersion.IJ_233 -> "idea233" + } + + val catalogDependencyLine = + catalogFile.useLines { lines -> lines.find { it.startsWith(dependencyName) } } + ?: throw GradleException( + "Unable to find IJP dependency '$dependencyName' in the catalog file '${catalogFile.path}'" + ) + + val dependencyVersion = + catalogDependencyLine + .substringAfter(dependencyName) + .trimStart(' ', '=') + .trimEnd() + .trim('"') + + if (!dependencyVersion.matches(versionRegex)) { + throw GradleException("Invalid IJP version found in version catalog: '$dependencyVersion'") + } - return dependencyVersion - } + return dependencyVersion + } - private object VersionComparator : Comparator { + private object VersionComparator : Comparator { - override fun compare(o1: String?, o2: String?): Int { - if (o1 == o2) return 0 - if (o1 == null) return -1 - if (o2 == null) return 1 + override fun compare(o1: String?, o2: String?): Int { + if (o1 == o2) return 0 + if (o1 == null) return -1 + if (o2 == null) return 1 - require(o1.isNotEmpty() && o1.all { it.isDigit() || it == '.' }) { - "The first version is invalid: '$o1'" - } - require(o2.isNotEmpty() && o2.all { it.isDigit() || it == '.' }) { - "The first version is invalid: '$o2'" - } + require(o1.isNotEmpty() && o1.all { it.isDigit() || it == '.' }) { "The first version is invalid: '$o1'" } + require(o2.isNotEmpty() && o2.all { it.isDigit() || it == '.' }) { "The first version is invalid: '$o2'" } - val firstGroups = o1.split('.') - val secondGroups = o2.split('.') + val firstGroups = o1.split('.') + val secondGroups = o2.split('.') - require(firstGroups.size == 3) { "The first version is invalid: '$o1'" } - require(secondGroups.size == 3) { "The second version is invalid: '$o2'" } + require(firstGroups.size == 3) { "The first version is invalid: '$o1'" } + require(secondGroups.size == 3) { "The second version is invalid: '$o2'" } - val firstComparison = firstGroups[0].toInt().compareTo(secondGroups[0].toInt()) - if (firstComparison != 0) return firstComparison + val firstComparison = firstGroups[0].toInt().compareTo(secondGroups[0].toInt()) + if (firstComparison != 0) return firstComparison - val secondComparison = firstGroups[1].toInt().compareTo(secondGroups[1].toInt()) - if (secondComparison != 0) return secondComparison + val secondComparison = firstGroups[1].toInt().compareTo(secondGroups[1].toInt()) + if (secondComparison != 0) return secondComparison - return firstGroups[2].toInt().compareTo(secondGroups[2].toInt()) + return firstGroups[2].toInt().compareTo(secondGroups[2].toInt()) + } } - } - private object ReleaseComparator : Comparator { + private object ReleaseComparator : Comparator { - override fun compare(o1: ApiIdeaReleasesItem.Release?, o2: ApiIdeaReleasesItem.Release?): Int { - if (o1 == o2) return 0 - if (o1 == null) return -1 - if (o2 == null) return 1 + override fun compare(o1: ApiIdeaReleasesItem.Release?, o2: ApiIdeaReleasesItem.Release?): Int { + if (o1 == o2) return 0 + if (o1 == null) return -1 + if (o2 == null) return 1 - return VersionComparator.compare(o1.build, o2.build) + return VersionComparator.compare(o1.build, o2.build) + } } - } } diff --git a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/theme/IntUiThemeDescriptorReader.kt b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/theme/IntUiThemeDescriptorReader.kt index 5ec7d5aaf2..62bdeb96f5 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/theme/IntUiThemeDescriptorReader.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/theme/IntUiThemeDescriptorReader.kt @@ -14,146 +14,146 @@ import kotlinx.serialization.json.JsonPrimitive internal object IntUiThemeDescriptorReader { - private val colorGroups = - setOf("Grey", "Blue", "Green", "Red", "Yellow", "Orange", "Purple", "Teal") - private val colorClassName = ClassName("androidx.compose.ui.graphics", "Color") - - fun readThemeFrom( - themeDescriptor: IntellijThemeDescriptor, - className: ClassName, - ideaVersion: String, - descriptorUrl: String, - ) = - FileSpec.builder(className) - .apply { - indent(" ") - addFileComment("Generated by the Jewel Int UI Palette Generator\n") - addFileComment("Generated from the IntelliJ Platform version $ideaVersion\n") - addFileComment("Source: $descriptorUrl") - - addImport(colorClassName.packageName, colorClassName.simpleName) - - addType( - TypeSpec.objectBuilder(className) + private val colorGroups = + setOf("Grey", "Blue", "Green", "Red", "Yellow", "Orange", "Purple", "Teal") + private val colorClassName = ClassName("androidx.compose.ui.graphics", "Color") + + fun readThemeFrom( + themeDescriptor: IntellijThemeDescriptor, + className: ClassName, + ideaVersion: String, + descriptorUrl: String, + ) = + FileSpec.builder(className) .apply { - addSuperinterface( - ClassName.bestGuess("org.jetbrains.jewel.foundation.theme.ThemeDescriptor") - ) - - addProperty( - PropertySpec.builder("isDark", Boolean::class, KModifier.OVERRIDE) - .initializer("%L", themeDescriptor.dark) - .build() - ) - - addProperty( - PropertySpec.builder("name", String::class, KModifier.OVERRIDE) - .initializer("\"%L (Int UI)\"", themeDescriptor.name) - .build() - ) - - readColors(themeDescriptor.colors) - readIcons(themeDescriptor) + indent(" ") + addFileComment("Generated by the Jewel Int UI Palette Generator\n") + addFileComment("Generated from the IntelliJ Platform version $ideaVersion\n") + addFileComment("Source: $descriptorUrl") + + addImport(colorClassName.packageName, colorClassName.simpleName) + + addType( + TypeSpec.objectBuilder(className) + .apply { + addSuperinterface( + ClassName.bestGuess("org.jetbrains.jewel.foundation.theme.ThemeDescriptor") + ) + + addProperty( + PropertySpec.builder("isDark", Boolean::class, KModifier.OVERRIDE) + .initializer("%L", themeDescriptor.dark) + .build() + ) + + addProperty( + PropertySpec.builder("name", String::class, KModifier.OVERRIDE) + .initializer("\"%L (Int UI)\"", themeDescriptor.name) + .build() + ) + + readColors(themeDescriptor.colors) + readIcons(themeDescriptor) + } + .build() + ) } .build() + + private val colorPaletteClassName = + ClassName.bestGuess("org.jetbrains.jewel.foundation.theme.ThemeColorPalette") + private val iconDataClassName = + ClassName.bestGuess("org.jetbrains.jewel.foundation.theme.ThemeIconData") + + private fun TypeSpec.Builder.readColors(colors: Map) { + val colorGroups = + colors.entries + .groupBy { it.key.replace("""\d+""".toRegex(), "") } + .filterKeys { colorGroups.contains(it) } + .map { (groupName, colors) -> + // We assume color lists are in the same order as in colorGroups + colors + .map { (_, value) -> + val colorHexString = value.replace("#", "0xFF") + CodeBlock.of("Color(%L)", colorHexString) + } + .joinToCode( + prefix = "\n${groupName.lowercase()} = listOf(\n", + separator = ",\n", + suffix = "\n)" + ) + } + + val rawMap = + colors + .map { (key, value) -> + val colorHexString = value.replace("#", "0xFF") + CodeBlock.of("%S to Color(%L)", key, colorHexString) + } + .joinToCode(prefix = "\nrawMap = mapOf(\n", separator = ",\n", suffix = "\n)") + + addProperty( + PropertySpec.builder("colors", colorPaletteClassName, KModifier.OVERRIDE) + .initializer("ThemeColorPalette(%L,\n%L\n)", colorGroups.joinToCode(","), rawMap) + .build() ) - } - .build() - - private val colorPaletteClassName = - ClassName.bestGuess("org.jetbrains.jewel.foundation.theme.ThemeColorPalette") - private val iconDataClassName = - ClassName.bestGuess("org.jetbrains.jewel.foundation.theme.ThemeIconData") - - private fun TypeSpec.Builder.readColors(colors: Map) { - val colorGroups = - colors.entries - .groupBy { it.key.replace("""\d+""".toRegex(), "") } - .filterKeys { colorGroups.contains(it) } - .map { (groupName, colors) -> - // We assume color lists are in the same order as in colorGroups - colors - .map { (_, value) -> - val colorHexString = value.replace("#", "0xFF") - CodeBlock.of("Color(%L)", colorHexString) + } + + private fun TypeSpec.Builder.readIcons(theme: IntellijThemeDescriptor) { + val iconOverrides = mutableMapOf() + val colorPalette = mutableMapOf() + + for ((key, value) in theme.icons) { + if (value is JsonPrimitive && value.isString) { + iconOverrides += key to value.content + } else if (value is JsonObject && key == "ColorPalette") { + value.entries + .mapNotNull { + val pairValue = it.value + if (pairValue is JsonPrimitive && pairValue.isString) { + it.key to pairValue.content + } else null + } + .forEach { colorPalette[it.first] = it.second } } - .joinToCode( - prefix = "\n${groupName.lowercase()} = listOf(\n", - separator = ",\n", - suffix = "\n)" - ) } - val rawMap = - colors - .map { (key, value) -> - val colorHexString = value.replace("#", "0xFF") - CodeBlock.of("%S to Color(%L)", key, colorHexString) - } - .joinToCode(prefix = "\nrawMap = mapOf(\n", separator = ",\n", suffix = "\n)") - - addProperty( - PropertySpec.builder("colors", colorPaletteClassName, KModifier.OVERRIDE) - .initializer("ThemeColorPalette(%L,\n%L\n)", colorGroups.joinToCode(","), rawMap) - .build() - ) - } - - private fun TypeSpec.Builder.readIcons(theme: IntellijThemeDescriptor) { - val iconOverrides = mutableMapOf() - val colorPalette = mutableMapOf() - - for ((key, value) in theme.icons) { - if (value is JsonPrimitive && value.isString) { - iconOverrides += key to value.content - } else if (value is JsonObject && key == "ColorPalette") { - value.entries - .mapNotNull { - val pairValue = it.value - if (pairValue is JsonPrimitive && pairValue.isString) { - it.key to pairValue.content - } else null - } - .forEach { colorPalette[it.first] = it.second } - } + val iconOverridesBlock = iconOverrides.toMapCodeBlock() + val selectionColorPaletteBlock = theme.iconColorsOnSelection.toMapCodeBlock() + + addProperty( + PropertySpec.builder("iconData", iconDataClassName, KModifier.OVERRIDE) + .initializer( + CodeBlock.of( + "ThemeIconData(iconOverrides = \n%L,colorPalette = \n%L,\nselectionColorPalette = %L\n)", + iconOverridesBlock, + colorPalette.toMapCodeBlock(), + selectionColorPaletteBlock, + ) + ) + .build() + ) } - val iconOverridesBlock = iconOverrides.toMapCodeBlock() - val selectionColorPaletteBlock = theme.iconColorsOnSelection.toMapCodeBlock() - - addProperty( - PropertySpec.builder("iconData", iconDataClassName, KModifier.OVERRIDE) - .initializer( - CodeBlock.of( - "ThemeIconData(iconOverrides = \n%L,colorPalette = \n%L,\nselectionColorPalette = %L\n)", - iconOverridesBlock, - colorPalette.toMapCodeBlock(), - selectionColorPaletteBlock, - ) + private inline fun Map.toMapCodeBlock() = + entries.map { (key, value) -> CodeBlock.of("\"%L\" to \"%L\"", key, value) } + .joinToCode(prefix = "mapOf(", separator = ",\n", suffix = ")") + + private inline fun createOverrideStringMapProperty( + name: String, + values: Map, + ) = + PropertySpec.builder( + name = name, + type = + Map::class.asTypeName() + .parameterizedBy(K::class.asTypeName(), V::class.asTypeName()), + KModifier.OVERRIDE ) - .build() - ) - } - - private inline fun Map.toMapCodeBlock() = - entries - .map { (key, value) -> CodeBlock.of("\"%L\" to \"%L\"", key, value) } - .joinToCode(prefix = "mapOf(", separator = ",\n", suffix = ")") - - private inline fun createOverrideStringMapProperty( - name: String, - values: Map - ) = - PropertySpec.builder( - name = name, - type = - Map::class.asTypeName().parameterizedBy(K::class.asTypeName(), V::class.asTypeName()), - KModifier.OVERRIDE - ) - .initializer( - values.entries - .map { (key, value) -> CodeBlock.of("\"%L\" to \"%L\"", key, value) } - .joinToCode(prefix = "mapOf(", separator = ",\n", suffix = ")") - ) - .build() + .initializer( + values.entries + .map { (key, value) -> CodeBlock.of("\"%L\" to \"%L\"", key, value) } + .joinToCode(prefix = "mapOf(", separator = ",\n", suffix = ")") + ) + .build() } diff --git a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/theme/IntelliJThemeGeneratorPlugin.kt b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/theme/IntelliJThemeGeneratorPlugin.kt index 8ea0da7e41..b31e8bb968 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/theme/IntelliJThemeGeneratorPlugin.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/jewel/buildlogic/theme/IntelliJThemeGeneratorPlugin.kt @@ -1,7 +1,6 @@ package org.jetbrains.jewel.buildlogic.theme import com.squareup.kotlinpoet.ClassName -import java.net.URL import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement @@ -15,69 +14,75 @@ import org.gradle.api.tasks.Input import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.gradle.kotlin.dsl.property +import java.net.URL class ThemeGeneratorContainer(container: NamedDomainObjectContainer) : - NamedDomainObjectContainer by container + NamedDomainObjectContainer by container class ThemeGeneration(val name: String, project: Project) { - val targetDir: DirectoryProperty = - project.objects - .directoryProperty() - .convention(project.layout.buildDirectory.dir("generated/theme")) - val ideaVersion = project.objects.property().convention("232.6734") - val themeClassName = project.objects.property() - val themeFile = project.objects.property() + val targetDir: DirectoryProperty = + project.objects + .directoryProperty() + .convention(project.layout.buildDirectory.dir("generated/theme")) + val ideaVersion = project.objects.property().convention("232.6734") + val themeClassName = project.objects.property() + val themeFile = project.objects.property() } open class IntelliJThemeGeneratorTask : DefaultTask() { - @get:OutputFile val outputFile: RegularFileProperty = project.objects.fileProperty() - - @get:Input val ideaVersion = project.objects.property() + @get:OutputFile + val outputFile: RegularFileProperty = project.objects.fileProperty() - @get:Input val themeFile = project.objects.property() + @get:Input + val ideaVersion = project.objects.property() - @get:Input val themeClassName = project.objects.property() + @get:Input + val themeFile = project.objects.property() - init { - group = "jewel" - } + @get:Input + val themeClassName = project.objects.property() - @TaskAction - fun generate() { - val json = Json { ignoreUnknownKeys = true } - val url = buildString { - append("https://raw.githubusercontent.com/JetBrains/intellij-community/") - append(ideaVersion.get()) - append("/") - append(themeFile.get()) + init { + group = "jewel" } - logger.lifecycle("Fetching theme descriptor from $url...") - val themeDescriptor = - URL(url).openStream().use { json.decodeFromStream(it) } + @TaskAction + fun generate() { + val json = Json { ignoreUnknownKeys = true } + val url = buildString { + append("https://raw.githubusercontent.com/JetBrains/intellij-community/") + append(ideaVersion.get()) + append("/") + append(themeFile.get()) + } - val className = ClassName.bestGuess(themeClassName.get()) - val file = - IntUiThemeDescriptorReader.readThemeFrom(themeDescriptor, className, ideaVersion.get(), url) + logger.lifecycle("Fetching theme descriptor from $url...") + val themeDescriptor = + URL(url).openStream().use { json.decodeFromStream(it) } - val outputFile = outputFile.get().asFile - logger.lifecycle( - "Theme descriptor for ${themeDescriptor.name} parsed and code generated into ${outputFile.path}" - ) - outputFile.bufferedWriter().use { file.writeTo(it) } - } + val className = ClassName.bestGuess(themeClassName.get()) + val file = + IntUiThemeDescriptorReader.readThemeFrom(themeDescriptor, className, ideaVersion.get(), url) + + val outputFile = outputFile.get().asFile + logger.lifecycle( + "Theme descriptor for ${themeDescriptor.name} parsed and " + + "code generated into ${outputFile.path}" + ) + outputFile.bufferedWriter().use { file.writeTo(it) } + } } @Serializable data class IntellijThemeDescriptor( - val name: String, - val author: String = "", - val dark: Boolean = false, - val editorScheme: String, - val colors: Map = emptyMap(), - val ui: Map = emptyMap(), - val icons: Map = emptyMap(), - val iconColorsOnSelection: Map = emptyMap(), + val name: String, + val author: String = "", + val dark: Boolean = false, + val editorScheme: String, + val colors: Map = emptyMap(), + val ui: Map = emptyMap(), + val icons: Map = emptyMap(), + val iconColorsOnSelection: Map = emptyMap(), ) diff --git a/samples/ide-plugin/build.gradle.kts b/samples/ide-plugin/build.gradle.kts index 8c1b73ac8a..72656666a8 100644 --- a/samples/ide-plugin/build.gradle.kts +++ b/samples/ide-plugin/build.gradle.kts @@ -11,11 +11,10 @@ plugins { intellij { pluginName.set("Jewel Demo") plugins.set(listOf("org.jetbrains.kotlin")) - val versionRaw = - when (supportedIJVersion()) { - IJ_232 -> libs.versions.idea232.get() - IJ_233 -> libs.versions.idea233.get() - } + val versionRaw = when (supportedIJVersion()) { + IJ_232 -> libs.versions.idea232.get() + IJ_233 -> libs.versions.idea233.get() + } version.set(versionRaw) } @@ -30,7 +29,9 @@ repositories { } dependencies { - implementation(projects.ideLafBridge) { exclude(group = "org.jetbrains.kotlinx") } + implementation(projects.ideLafBridge) { + exclude(group = "org.jetbrains.kotlinx") + } implementation(compose.desktop.currentOs) { exclude(group = "org.jetbrains.compose.material") @@ -40,7 +41,11 @@ dependencies { tasks { // We don't have any settings in the demo plugin - buildSearchableOptions { enabled = false } + buildSearchableOptions { + enabled = false + } - runIde { systemProperties["org.jetbrains.jewel.debug"] = "true" } + runIde { + systemProperties["org.jetbrains.jewel.debug"] = "true" + } } diff --git a/samples/ide-plugin/src/main/kotlin/icons/JewelIcons.kt b/samples/ide-plugin/src/main/kotlin/icons/JewelIcons.kt index ea3843efcc..27a014c2e9 100644 --- a/samples/ide-plugin/src/main/kotlin/icons/JewelIcons.kt +++ b/samples/ide-plugin/src/main/kotlin/icons/JewelIcons.kt @@ -1,10 +1,9 @@ package icons import com.intellij.openapi.util.IconLoader -import javax.swing.Icon -public object JewelIcons { +object JewelIcons { @JvmField - public val ToolWindowIcon: Icon = IconLoader.getIcon("/icons/jewel-tool-window.svg", javaClass) + val ToolWindowIcon = IconLoader.getIcon("/icons/jewel-tool-window.svg", javaClass) } diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt index c5bbe11935..65c02566f1 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt @@ -50,13 +50,11 @@ import org.jetbrains.jewel.ui.component.Tooltip @Composable internal fun ToolWindowScope.ComponentShowcaseTab() { SwingBridgeTheme { - val bgColor by - remember(JewelTheme.isDark) { mutableStateOf(JBColor.PanelBackground.toComposeColor()) } + val bgColor by remember(JewelTheme.isDark) { mutableStateOf(JBColor.PanelBackground.toComposeColor()) } val scrollState = rememberScrollState() Row( - modifier = - Modifier.trackComponentActivation(panel) + modifier = Modifier.trackComponentActivation(panel) .fillMaxSize() .background(bgColor) .verticalScroll(scrollState) @@ -88,12 +86,20 @@ private fun RowScope.ColumnOne() { verticalAlignment = Alignment.CenterVertically, ) { var clicks1 by remember { mutableStateOf(0) } - OutlinedButton({ clicks1++ }) { Text("Outlined: $clicks1") } - OutlinedButton({}, enabled = false) { Text("Outlined") } + OutlinedButton({ clicks1++ }) { + Text("Outlined: $clicks1") + } + OutlinedButton({ }, enabled = false) { + Text("Outlined") + } var clicks2 by remember { mutableStateOf(0) } - DefaultButton({ clicks2++ }) { Text("Default: $clicks2") } - DefaultButton({}, enabled = false) { Text("Default") } + DefaultButton({ clicks2++ }) { + Text("Default: $clicks2") + } + DefaultButton({ }, enabled = false) { + Text("Default") + } } var textFieldValue by remember { mutableStateOf("") } @@ -114,8 +120,12 @@ private fun RowScope.ColumnOne() { Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { var index by remember { mutableStateOf(0) } - RadioButtonRow(selected = index == 0, onClick = { index = 0 }) { Text("I am number one") } - RadioButtonRow(selected = index == 1, onClick = { index = 1 }) { Text("Sad second") } + RadioButtonRow(selected = index == 0, onClick = { index = 0 }) { + Text("I am number one") + } + RadioButtonRow(selected = index == 1, onClick = { index = 1 }) { + Text("Sad second") + } } Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { @@ -132,10 +142,10 @@ private fun RowScope.ColumnOne() { contentDescription = "An icon", ) - IconButton(onClick = {}) { + IconButton(onClick = { }) { Icon("actions/close.svg", contentDescription = "An icon", AllIcons::class.java) } - IconButton(onClick = {}) { + IconButton(onClick = { }) { Icon("actions/addList.svg", contentDescription = "An icon", AllIcons::class.java) } } @@ -157,18 +167,15 @@ private fun RowScope.ColumnOne() { } Row(verticalAlignment = Alignment.CenterVertically) { - Tooltip( - tooltip = { - Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { - Icon("general/showInfos.svg", contentDescription = null, AllIcons::class.java) + Tooltip(tooltip = { + Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { + Icon("general/showInfos.svg", contentDescription = null, AllIcons::class.java) - Text("This is a tooltip") - } - }, - ) { + Text("This is a tooltip") + } + }) { Text( - modifier = - Modifier.border(1.dp, JewelTheme.globalColors.borders.normal).padding(12.dp, 8.dp), + modifier = Modifier.border(1.dp, JewelTheme.globalColors.borders.normal).padding(12.dp, 8.dp), text = "Hover Me!", ) } @@ -217,7 +224,9 @@ private fun RowScope.ColumnTwo() { onElementClick = {}, onElementDoubleClick = {}, ) { element -> - Box(Modifier.fillMaxWidth()) { Text(element.data, Modifier.padding(2.dp)) } + Box(Modifier.fillMaxWidth()) { + Text(element.data, Modifier.padding(2.dp)) + } } } } diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt index e85d55cd5e..4cbafee94c 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt @@ -19,11 +19,15 @@ import org.jetbrains.jewel.samples.ideplugin.releasessample.ReleasesSamplePanel internal class JewelDemoToolWindowFactory : ToolWindowFactory, DumbAware { override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) { - toolWindow.addComposeTab("Components") { ComponentShowcaseTab() } + toolWindow.addComposeTab("Components") { + ComponentShowcaseTab() + } addSwingTab(toolWindow) - toolWindow.addComposeTab("Compose Sample") { ReleasesSampleCompose(project) } + toolWindow.addComposeTab("Compose Sample") { + ReleasesSampleCompose(project) + } } private fun addSwingTab(toolWindow: ToolWindow) { diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ChannelIndication.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ChannelIndication.kt index c8bb98e616..d142751d75 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ChannelIndication.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ChannelIndication.kt @@ -9,8 +9,7 @@ import java.awt.Graphics import java.awt.Graphics2D import javax.swing.JLabel -internal class ChannelIndication(private val channel: ReleaseChannel) : - JLabel(channel.name.lowercase()) { +internal class ChannelIndication(private val channel: ReleaseChannel) : JLabel(channel.name.lowercase()) { init { border = JBUI.Borders.empty(2, 4) @@ -24,16 +23,7 @@ internal class ChannelIndication(private val channel: ReleaseChannel) : val graphicsConfig = GraphicsConfig(this) graphicsConfig.setupRoundedBorderAntialiasing() - RectanglePainter.paint( - this, - x, - y, - width, - height - y, - JBUIScale.scale(8), - channel.background, - null, - ) + RectanglePainter.paint(this, x, y, width, height - y, JBUIScale.scale(8), channel.background, null) graphicsConfig.restore() } diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ContentItem.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ContentItem.kt index b4c12ad5cc..b5c127bfb6 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ContentItem.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ContentItem.kt @@ -3,38 +3,39 @@ package org.jetbrains.jewel.samples.ideplugin.releasessample import kotlinx.datetime.LocalDate import org.jetbrains.annotations.Nls -public sealed class ContentItem { +sealed class ContentItem { - @get:Nls public abstract val displayText: String - public abstract val imagePath: String? - public abstract val versionName: String - public abstract val releaseDate: LocalDate? - public abstract val key: Any + @get:Nls + abstract val displayText: String + abstract val imagePath: String? + abstract val versionName: String + abstract val releaseDate: LocalDate? + abstract val key: Any - public data class AndroidStudio( + data class AndroidStudio( @Nls override val displayText: String, override val imagePath: String?, override val versionName: String, - public val build: String, - public val platformBuild: String, - public val platformVersion: String, - public val channel: ReleaseChannel, + val build: String, + val platformBuild: String, + val platformVersion: String, + val channel: ReleaseChannel, override val releaseDate: LocalDate?, override val key: Any = build, ) : ContentItem() - public data class AndroidRelease( + data class AndroidRelease( @Nls override val displayText: String, override val imagePath: String?, override val versionName: String, - public val codename: String?, - public val apiLevel: Int, + val codename: String?, + val apiLevel: Int, override val releaseDate: LocalDate?, override val key: Any = releaseDate ?: displayText, ) : ContentItem() } -public fun ContentItem.matches(text: String): Boolean { +fun ContentItem.matches(text: String): Boolean { if (displayText.contains(text, ignoreCase = true)) return true if (versionName.contains(text, ignoreCase = true)) return true @@ -45,6 +46,7 @@ public fun ContentItem.matches(text: String): Boolean { if (platformBuild.contains(text, ignoreCase = true)) return true if (platformVersion.contains(text, ignoreCase = true)) return true } + is ContentItem.AndroidRelease -> { if (codename?.contains(text, ignoreCase = true) == true) return true if (this.apiLevel.toString().contains(text, ignoreCase = true)) return true diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ContentSource.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ContentSource.kt index e197501c2a..808cc6a1ce 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ContentSource.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ContentSource.kt @@ -2,13 +2,13 @@ package org.jetbrains.jewel.samples.ideplugin.releasessample import kotlinx.datetime.LocalDate -public abstract class ContentSource { +abstract class ContentSource { - public abstract val items: List + abstract val items: List - public abstract val displayName: String + abstract val displayName: String - public fun isSameAs(other: ContentSource<*>): Boolean { + fun isSameAs(other: ContentSource<*>): Boolean { val thisComparable = getComparableSource() val otherComparable = other.getComparableSource() @@ -22,292 +22,291 @@ public abstract class ContentSource { } } -public data class FilteredContentSource( +data class FilteredContentSource( override val items: List, - public val original: ContentSource<*>, + val original: ContentSource<*>, ) : ContentSource() { override val displayName: String get() = original.displayName } -public object AndroidReleases : ContentSource() { +object AndroidReleases : ContentSource() { - override val items: List = - listOf( - ContentItem.AndroidRelease( - displayText = "Android 1.0", - imagePath = null, - versionName = "1.0", - codename = null, - apiLevel = 1, - releaseDate = LocalDate(2008, 9, 23), - ), - ContentItem.AndroidRelease( - displayText = "Android 1.1", - imagePath = null, - versionName = "1.1", - codename = "Petit Four", - apiLevel = 2, - releaseDate = LocalDate(2009, 2, 9), - ), - ContentItem.AndroidRelease( - displayText = "Android Cupcake", - imagePath = "/android-releases/cupcake.png", - versionName = "1.5", - codename = "Cupcake", - apiLevel = 3, - releaseDate = LocalDate(2009, 4, 27), - ), - ContentItem.AndroidRelease( - displayText = "Android Donut", - imagePath = "/android-releases/donut.png", - versionName = "1.6", - codename = "Donut", - apiLevel = 4, - releaseDate = LocalDate(2009, 9, 15), - ), - ContentItem.AndroidRelease( - displayText = "Android Eclair (2.0)", - imagePath = "/android-releases/eclair.png", - versionName = "2.0", - codename = "Eclair", - apiLevel = 5, - releaseDate = LocalDate(2009, 10, 27), - ), - ContentItem.AndroidRelease( - displayText = "Android Eclair (2.0.1)", - imagePath = "/android-releases/eclair.png", - versionName = "2.0.1", - codename = "Eclair", - apiLevel = 6, - releaseDate = LocalDate(2009, 12, 3), - ), - ContentItem.AndroidRelease( - displayText = "Android Eclair (2.1)", - imagePath = "/android-releases/eclair.png", - versionName = "2.1", - codename = "Eclair", - apiLevel = 7, - releaseDate = LocalDate(2010, 1, 11), - ), - ContentItem.AndroidRelease( - displayText = "Android Froyo", - imagePath = "/android-releases/froyo.png", - versionName = "2.2 – 2.2.3", - codename = "Froyo", - apiLevel = 8, - releaseDate = LocalDate(2010, 5, 20), - ), - ContentItem.AndroidRelease( - displayText = "Android Gingerbread (2.3 – 2.3.2)", - imagePath = "/android-releases/gingerbread.png", - versionName = "2.3 – 2.3.2", - codename = "Gingerbread", - apiLevel = 9, - releaseDate = LocalDate(2010, 12, 6), - ), - ContentItem.AndroidRelease( - displayText = "Android Gingerbread (2.3.3 – 2.3.7)", - imagePath = "/android-releases/gingerbread.png", - versionName = "2.3.3 – 2.3.7", - codename = "Gingerbread", - apiLevel = 10, - releaseDate = LocalDate(2011, 2, 9), - ), - ContentItem.AndroidRelease( - displayText = "Android Honeycomb (3.0)", - imagePath = "/android-releases/honeycomb.svg", - versionName = "3.0", - codename = "Honeycomb", - apiLevel = 11, - releaseDate = LocalDate(2011, 2, 22), - ), - ContentItem.AndroidRelease( - displayText = "Android Honeycomb (3.1)", - imagePath = "/android-releases/honeycomb.svg", - versionName = "3.1", - codename = "Honeycomb", - apiLevel = 12, - releaseDate = LocalDate(2011, 5, 10), - ), - ContentItem.AndroidRelease( - displayText = "Android Honeycomb (3.2 – 3.2.6)", - imagePath = "/android-releases/honeycomb.svg", - versionName = "3.2 – 3.2.6", - codename = "Honeycomb", - apiLevel = 13, - releaseDate = LocalDate(2011, 7, 15), - ), - ContentItem.AndroidRelease( - displayText = "Android Ice Cream Sandwich (4.0 – 4.0.2)", - imagePath = "/android-releases/ice-cream-sandwich.svg", - versionName = "4.0 – 4.0.2", - codename = "Ice Cream Sandwich", - apiLevel = 14, - releaseDate = LocalDate(2011, 10, 18), - ), - ContentItem.AndroidRelease( - displayText = "Android Ice Cream Sandwich (4.0.3 – 4.0.4)", - imagePath = "/android-releases/ice-cream-sandwich.svg", - versionName = "4.0.3 – 4.0.4", - codename = "Ice Cream Sandwich", - apiLevel = 15, - releaseDate = LocalDate(2011, 12, 16), - ), - ContentItem.AndroidRelease( - displayText = "Android Jelly Bean (4.1 – 4.1.2)", - imagePath = "/android-releases/jelly-bean.svg", - versionName = "4.1 – 4.1.2", - codename = "Jelly Bean", - apiLevel = 16, - releaseDate = LocalDate(2012, 7, 9), - ), - ContentItem.AndroidRelease( - displayText = "Android Jelly Bean (4.2 – 4.2.2)", - imagePath = "/android-releases/jelly-bean.svg", - versionName = "4.2 – 4.2.2", - codename = "Jelly Bean", - apiLevel = 17, - releaseDate = LocalDate(2012, 11, 13), - ), - ContentItem.AndroidRelease( - displayText = "Android Jelly Bean (4.3 – 4.3.1)", - imagePath = "/android-releases/jelly-bean.svg", - versionName = "4.3 – 4.3.1", - codename = "Jelly Bean", - apiLevel = 18, - releaseDate = LocalDate(2013, 7, 24), - ), - ContentItem.AndroidRelease( - displayText = "Android KitKat (4.4 – 4.4.4)", - imagePath = "/android-releases/kitkat.svg", - versionName = "4.4 – 4.4.4", - codename = "Key Lime Pie", - apiLevel = 19, - releaseDate = LocalDate(2013, 10, 31), - ), - ContentItem.AndroidRelease( - displayText = "Android KitKat (4.4W – 4.4W.2)", - imagePath = "/android-releases/kitkat.svg", - versionName = "4.4W – 4.4W.2", - codename = "Key Lime Pie", - apiLevel = 20, - releaseDate = LocalDate(2014, 6, 25), - ), - ContentItem.AndroidRelease( - displayText = "Android Lollipop (5.0 – 5.0.2)", - imagePath = "/android-releases/lollipop.svg", - versionName = "5.0 – 5.0.2", - codename = "Lemon Meringue Pie", - apiLevel = 21, - releaseDate = LocalDate(2014, 10, 4), - ), - ContentItem.AndroidRelease( - displayText = "Android Lollipop (5.1 – 5.1.1)", - imagePath = "/android-releases/lollipop.svg", - versionName = "5.1 – 5.1.1", - codename = "Lemon Meringue Pie", - apiLevel = 22, - releaseDate = LocalDate(2015, 3, 2), - ), - ContentItem.AndroidRelease( - displayText = "Android Marshmallow", - imagePath = "/android-releases/marshmallow.svg", - versionName = "6.0 – 6.0.1", - codename = "Macadamia Nut Cookie", - apiLevel = 23, - releaseDate = LocalDate(2015, 10, 2), - ), - ContentItem.AndroidRelease( - displayText = "Android Nougat (7.0)", - imagePath = "/android-releases/nougat.svg", - versionName = "7.0", - codename = "New York Cheesecake", - apiLevel = 24, - releaseDate = LocalDate(2016, 8, 22), - ), - ContentItem.AndroidRelease( - displayText = "Android Nougat (7.1 – 7.1.2)", - imagePath = "/android-releases/nougat.svg", - versionName = "7.1 – 7.1.2", - codename = "New York Cheesecake", - apiLevel = 25, - releaseDate = LocalDate(2016, 10, 4), - ), - ContentItem.AndroidRelease( - displayText = "Android Oreo (8.0)", - imagePath = "/android-releases/oreo.svg", - versionName = "8.0", - codename = "Oatmeal Cookie", - apiLevel = 26, - releaseDate = LocalDate(2017, 8, 21), - ), - ContentItem.AndroidRelease( - displayText = "Android Oreo (8.1)", - imagePath = "/android-releases/oreo.svg", - versionName = "8.1", - codename = "Oatmeal Cookie", - apiLevel = 27, - releaseDate = LocalDate(2017, 12, 5), - ), - ContentItem.AndroidRelease( - displayText = "Android Pie", - imagePath = "/android-releases/pie.svg", - versionName = "9", - codename = "Pistachio Ice Cream", - apiLevel = 28, - releaseDate = LocalDate(2018, 8, 6), - ), - ContentItem.AndroidRelease( - displayText = "Android 10", - imagePath = "/android-releases/10.svg", - versionName = "10", - codename = "Quince Tart", - apiLevel = 29, - releaseDate = LocalDate(2019, 9, 3), - ), - ContentItem.AndroidRelease( - displayText = "Android 11", - imagePath = "/android-releases/11.svg", - versionName = "11", - codename = "Red Velvet Cake", - apiLevel = 30, - releaseDate = LocalDate(2020, 9, 8), - ), - ContentItem.AndroidRelease( - displayText = "Android 12", - imagePath = "/android-releases/12.svg", - versionName = "12", - codename = "Snow Cone", - apiLevel = 31, - releaseDate = LocalDate(2021, 10, 4), - ), - ContentItem.AndroidRelease( - displayText = "Android 12L", - imagePath = "/android-releases/12.svg", - versionName = "12.1", - codename = "Snow Cone v2", - apiLevel = 32, - releaseDate = LocalDate(2022, 3, 7), - ), - ContentItem.AndroidRelease( - displayText = "Android 13", - imagePath = "/android-releases/13.svg", - versionName = "13", - codename = "Tiramisu", - apiLevel = 33, - releaseDate = LocalDate(2022, 8, 15), - ), - ContentItem.AndroidRelease( - displayText = "Android 14", - imagePath = "/android-releases/14.svg", - versionName = "14", - codename = "Upside Down Cake", - apiLevel = 33, - releaseDate = LocalDate(2023, 10, 4), - ), - ) + override val items = listOf( + ContentItem.AndroidRelease( + displayText = "Android 1.0", + imagePath = null, + versionName = "1.0", + codename = null, + apiLevel = 1, + releaseDate = LocalDate(2008, 9, 23), + ), + ContentItem.AndroidRelease( + displayText = "Android 1.1", + imagePath = null, + versionName = "1.1", + codename = "Petit Four", + apiLevel = 2, + releaseDate = LocalDate(2009, 2, 9), + ), + ContentItem.AndroidRelease( + displayText = "Android Cupcake", + imagePath = "/android-releases/cupcake.png", + versionName = "1.5", + codename = "Cupcake", + apiLevel = 3, + releaseDate = LocalDate(2009, 4, 27), + ), + ContentItem.AndroidRelease( + displayText = "Android Donut", + imagePath = "/android-releases/donut.png", + versionName = "1.6", + codename = "Donut", + apiLevel = 4, + releaseDate = LocalDate(2009, 9, 15), + ), + ContentItem.AndroidRelease( + displayText = "Android Eclair (2.0)", + imagePath = "/android-releases/eclair.png", + versionName = "2.0", + codename = "Eclair", + apiLevel = 5, + releaseDate = LocalDate(2009, 10, 27), + ), + ContentItem.AndroidRelease( + displayText = "Android Eclair (2.0.1)", + imagePath = "/android-releases/eclair.png", + versionName = "2.0.1", + codename = "Eclair", + apiLevel = 6, + releaseDate = LocalDate(2009, 12, 3), + ), + ContentItem.AndroidRelease( + displayText = "Android Eclair (2.1)", + imagePath = "/android-releases/eclair.png", + versionName = "2.1", + codename = "Eclair", + apiLevel = 7, + releaseDate = LocalDate(2010, 1, 11), + ), + ContentItem.AndroidRelease( + displayText = "Android Froyo", + imagePath = "/android-releases/froyo.png", + versionName = "2.2 – 2.2.3", + codename = "Froyo", + apiLevel = 8, + releaseDate = LocalDate(2010, 5, 20), + ), + ContentItem.AndroidRelease( + displayText = "Android Gingerbread (2.3 – 2.3.2)", + imagePath = "/android-releases/gingerbread.png", + versionName = "2.3 – 2.3.2", + codename = "Gingerbread", + apiLevel = 9, + releaseDate = LocalDate(2010, 12, 6), + ), + ContentItem.AndroidRelease( + displayText = "Android Gingerbread (2.3.3 – 2.3.7)", + imagePath = "/android-releases/gingerbread.png", + versionName = "2.3.3 – 2.3.7", + codename = "Gingerbread", + apiLevel = 10, + releaseDate = LocalDate(2011, 2, 9), + ), + ContentItem.AndroidRelease( + displayText = "Android Honeycomb (3.0)", + imagePath = "/android-releases/honeycomb.svg", + versionName = "3.0", + codename = "Honeycomb", + apiLevel = 11, + releaseDate = LocalDate(2011, 2, 22), + ), + ContentItem.AndroidRelease( + displayText = "Android Honeycomb (3.1)", + imagePath = "/android-releases/honeycomb.svg", + versionName = "3.1", + codename = "Honeycomb", + apiLevel = 12, + releaseDate = LocalDate(2011, 5, 10), + ), + ContentItem.AndroidRelease( + displayText = "Android Honeycomb (3.2 – 3.2.6)", + imagePath = "/android-releases/honeycomb.svg", + versionName = "3.2 – 3.2.6", + codename = "Honeycomb", + apiLevel = 13, + releaseDate = LocalDate(2011, 7, 15), + ), + ContentItem.AndroidRelease( + displayText = "Android Ice Cream Sandwich (4.0 – 4.0.2)", + imagePath = "/android-releases/ice-cream-sandwich.svg", + versionName = "4.0 – 4.0.2", + codename = "Ice Cream Sandwich", + apiLevel = 14, + releaseDate = LocalDate(2011, 10, 18), + ), + ContentItem.AndroidRelease( + displayText = "Android Ice Cream Sandwich (4.0.3 – 4.0.4)", + imagePath = "/android-releases/ice-cream-sandwich.svg", + versionName = "4.0.3 – 4.0.4", + codename = "Ice Cream Sandwich", + apiLevel = 15, + releaseDate = LocalDate(2011, 12, 16), + ), + ContentItem.AndroidRelease( + displayText = "Android Jelly Bean (4.1 – 4.1.2)", + imagePath = "/android-releases/jelly-bean.svg", + versionName = "4.1 – 4.1.2", + codename = "Jelly Bean", + apiLevel = 16, + releaseDate = LocalDate(2012, 7, 9), + ), + ContentItem.AndroidRelease( + displayText = "Android Jelly Bean (4.2 – 4.2.2)", + imagePath = "/android-releases/jelly-bean.svg", + versionName = "4.2 – 4.2.2", + codename = "Jelly Bean", + apiLevel = 17, + releaseDate = LocalDate(2012, 11, 13), + ), + ContentItem.AndroidRelease( + displayText = "Android Jelly Bean (4.3 – 4.3.1)", + imagePath = "/android-releases/jelly-bean.svg", + versionName = "4.3 – 4.3.1", + codename = "Jelly Bean", + apiLevel = 18, + releaseDate = LocalDate(2013, 7, 24), + ), + ContentItem.AndroidRelease( + displayText = "Android KitKat (4.4 – 4.4.4)", + imagePath = "/android-releases/kitkat.svg", + versionName = "4.4 – 4.4.4", + codename = "Key Lime Pie", + apiLevel = 19, + releaseDate = LocalDate(2013, 10, 31), + ), + ContentItem.AndroidRelease( + displayText = "Android KitKat (4.4W – 4.4W.2)", + imagePath = "/android-releases/kitkat.svg", + versionName = "4.4W – 4.4W.2", + codename = "Key Lime Pie", + apiLevel = 20, + releaseDate = LocalDate(2014, 6, 25), + ), + ContentItem.AndroidRelease( + displayText = "Android Lollipop (5.0 – 5.0.2)", + imagePath = "/android-releases/lollipop.svg", + versionName = "5.0 – 5.0.2", + codename = "Lemon Meringue Pie", + apiLevel = 21, + releaseDate = LocalDate(2014, 10, 4), + ), + ContentItem.AndroidRelease( + displayText = "Android Lollipop (5.1 – 5.1.1)", + imagePath = "/android-releases/lollipop.svg", + versionName = "5.1 – 5.1.1", + codename = "Lemon Meringue Pie", + apiLevel = 22, + releaseDate = LocalDate(2015, 3, 2), + ), + ContentItem.AndroidRelease( + displayText = "Android Marshmallow", + imagePath = "/android-releases/marshmallow.svg", + versionName = "6.0 – 6.0.1", + codename = "Macadamia Nut Cookie", + apiLevel = 23, + releaseDate = LocalDate(2015, 10, 2), + ), + ContentItem.AndroidRelease( + displayText = "Android Nougat (7.0)", + imagePath = "/android-releases/nougat.svg", + versionName = "7.0", + codename = "New York Cheesecake", + apiLevel = 24, + releaseDate = LocalDate(2016, 8, 22), + ), + ContentItem.AndroidRelease( + displayText = "Android Nougat (7.1 – 7.1.2)", + imagePath = "/android-releases/nougat.svg", + versionName = "7.1 – 7.1.2", + codename = "New York Cheesecake", + apiLevel = 25, + releaseDate = LocalDate(2016, 10, 4), + ), + ContentItem.AndroidRelease( + displayText = "Android Oreo (8.0)", + imagePath = "/android-releases/oreo.svg", + versionName = "8.0", + codename = "Oatmeal Cookie", + apiLevel = 26, + releaseDate = LocalDate(2017, 8, 21), + ), + ContentItem.AndroidRelease( + displayText = "Android Oreo (8.1)", + imagePath = "/android-releases/oreo.svg", + versionName = "8.1", + codename = "Oatmeal Cookie", + apiLevel = 27, + releaseDate = LocalDate(2017, 12, 5), + ), + ContentItem.AndroidRelease( + displayText = "Android Pie", + imagePath = "/android-releases/pie.svg", + versionName = "9", + codename = "Pistachio Ice Cream", + apiLevel = 28, + releaseDate = LocalDate(2018, 8, 6), + ), + ContentItem.AndroidRelease( + displayText = "Android 10", + imagePath = "/android-releases/10.svg", + versionName = "10", + codename = "Quince Tart", + apiLevel = 29, + releaseDate = LocalDate(2019, 9, 3), + ), + ContentItem.AndroidRelease( + displayText = "Android 11", + imagePath = "/android-releases/11.svg", + versionName = "11", + codename = "Red Velvet Cake", + apiLevel = 30, + releaseDate = LocalDate(2020, 9, 8), + ), + ContentItem.AndroidRelease( + displayText = "Android 12", + imagePath = "/android-releases/12.svg", + versionName = "12", + codename = "Snow Cone", + apiLevel = 31, + releaseDate = LocalDate(2021, 10, 4), + ), + ContentItem.AndroidRelease( + displayText = "Android 12L", + imagePath = "/android-releases/12.svg", + versionName = "12.1", + codename = "Snow Cone v2", + apiLevel = 32, + releaseDate = LocalDate(2022, 3, 7), + ), + ContentItem.AndroidRelease( + displayText = "Android 13", + imagePath = "/android-releases/13.svg", + versionName = "13", + codename = "Tiramisu", + apiLevel = 33, + releaseDate = LocalDate(2022, 8, 15), + ), + ContentItem.AndroidRelease( + displayText = "Android 14", + imagePath = "/android-releases/14.svg", + versionName = "14", + codename = "Upside Down Cake", + apiLevel = 33, + releaseDate = LocalDate(2023, 10, 4), + ), + ) - override val displayName: String = "Android releases" + override val displayName = "Android releases" } diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/DetailsPanel.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/DetailsPanel.kt index 0ef36928b5..40fc467867 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/DetailsPanel.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/DetailsPanel.kt @@ -20,18 +20,16 @@ import java.time.format.DateTimeFormatter import java.time.format.FormatStyle import javax.swing.ScrollPaneConstants -internal class DetailsPanel(private val scope: CoroutineScope) : - JBPanelWithEmptyText(BorderLayout()), ComponentWithEmptyText { +internal class DetailsPanel(private val scope: CoroutineScope) : JBPanelWithEmptyText(BorderLayout()), ComponentWithEmptyText { - public fun display(contentItem: ContentItem?) { + fun display(contentItem: ContentItem?) { removeAll() - val content = - when (contentItem) { - is ContentItem.AndroidRelease -> ItemDetailsPanel(contentItem, scope) - is ContentItem.AndroidStudio -> ItemDetailsPanel(contentItem, scope) - null -> return - } + val content = when (contentItem) { + is ContentItem.AndroidRelease -> ItemDetailsPanel(contentItem, scope) + is ContentItem.AndroidStudio -> ItemDetailsPanel(contentItem, scope) + null -> return + } add(content, BorderLayout.CENTER) } } @@ -44,17 +42,15 @@ private class ItemDetailsPanel( private val formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM) init { - val bufferedImage = - contentItem.imagePath - ?.let { ImageLoader.loadFromResource(it, javaClass) } - ?.let { ImageUtil.toBufferedImage(it) } + val bufferedImage = contentItem.imagePath + ?.let { ImageLoader.loadFromResource(it, javaClass) } + ?.let { ImageUtil.toBufferedImage(it) } if (bufferedImage != null) { - val imageContainer = - ImageComponent(scope).apply { - maximumHeight = scale(200) - image = bufferedImage - } + val imageContainer = ImageComponent(scope).apply { + maximumHeight = scale(200) + image = bufferedImage + } addToTop(imageContainer) } @@ -91,10 +87,8 @@ private class ItemDetailsPanel( it } } - .component - .font = JBFont.h1() - } - .bottomGap(BottomGap.MEDIUM) + .component.font = JBFont.h1() + }.bottomGap(BottomGap.MEDIUM) } private fun Panel.androidReleaseContent(contentItem: ContentItem.AndroidRelease) { diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/FoilModifier.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/FoilModifier.kt index 570e481d50..82f0058cd8 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/FoilModifier.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/FoilModifier.kt @@ -9,8 +9,7 @@ import org.jetbrains.skia.RuntimeEffect import org.jetbrains.skia.RuntimeShaderBuilder @Language("GLSL") // Technically, SkSL -private const val FOIL_SHADER_CODE = - """ +private const val FOIL_SHADER_CODE = """ const float SCALE = 1.8; // Effect scale (> 1 means smaller rainbow) const float SATURATION = 0.9; // Color saturation (0.0 = grayscale, 1.0 = full color) const float LIGHTNESS = 0.65; // Color lightness (0.0 = black, 1.0 = white) @@ -75,22 +74,22 @@ vec4 main(float2 fragCoord) { private val runtimeEffect = RuntimeEffect.makeForShader(FOIL_SHADER_CODE) private val shaderBuilder = RuntimeShaderBuilder(runtimeEffect) -internal fun Modifier.holoFoil(offset: Float, intensity: Float = 1f) = graphicsLayer { - shaderBuilder.uniform("resolution", size.width, size.height) - shaderBuilder.uniform("offset", 0f, offset) - shaderBuilder.uniform("intensity", intensity * .65f) +internal fun Modifier.holoFoil(offset: Float, intensity: Float = 1f) = + graphicsLayer { + shaderBuilder.uniform("resolution", size.width, size.height) + shaderBuilder.uniform("offset", 0f, offset) + shaderBuilder.uniform("intensity", intensity * .65f) - renderEffect = - ImageFilter.makeRuntimeShader( - runtimeShaderBuilder = shaderBuilder, - shaderNames = arrayOf("content"), - inputs = arrayOf(null), - ) - .asComposeRenderEffect() + renderEffect = + ImageFilter.makeRuntimeShader( + runtimeShaderBuilder = shaderBuilder, + shaderNames = arrayOf("content"), + inputs = arrayOf(null), + ).asComposeRenderEffect() - rotationX = offset * 4f * intensity - rotationY = offset * 10f * intensity - rotationZ = offset * -3f * intensity - scaleX = 1f - .1f * intensity - scaleY = 1f - .1f * intensity -} + rotationX = offset * 4f * intensity + rotationY = offset * 10f * intensity + rotationZ = offset * -3f * intensity + scaleX = 1f - .1f * intensity + scaleY = 1f - .1f * intensity + } diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ImageComponent.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ImageComponent.kt index bb6e164281..d251337490 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ImageComponent.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ImageComponent.kt @@ -39,31 +39,28 @@ internal class ImageComponent( private var scaledImage: Image? = null init { - addComponentListener( - object : ComponentListener { - override fun componentResized(e: ComponentEvent?) { - updateScaledImage() - } - - override fun componentMoved(e: ComponentEvent?) { - // No-op - } - - override fun componentShown(e: ComponentEvent?) { - // No-op - } - - override fun componentHidden(e: ComponentEvent?) { - // No-op - } - }, - ) + addComponentListener(object : ComponentListener { + override fun componentResized(e: ComponentEvent?) { + updateScaledImage() + } + + override fun componentMoved(e: ComponentEvent?) { + // No-op + } + + override fun componentShown(e: ComponentEvent?) { + // No-op + } + + override fun componentHidden(e: ComponentEvent?) { + // No-op + } + }) registerUiInspectorInfoProvider { mapOf( "image" to image, - "imageSize" to - image?.let { Dimension(ImageUtil.getUserWidth(it), ImageUtil.getUserHeight(it)) }, + "imageSize" to image?.let { Dimension(ImageUtil.getUserWidth(it), ImageUtil.getUserHeight(it)) }, ) } } @@ -74,31 +71,29 @@ internal class ImageComponent( val currentImage = image ?: return - resizeJob = - scope.launch(Dispatchers.Default) { - val imageWidth = currentImage.width + resizeJob = scope.launch(Dispatchers.Default) { + val imageWidth = currentImage.width - val componentWidth = width - val ratioToFit = componentWidth.toDouble() / imageWidth + val componentWidth = width + val ratioToFit = componentWidth.toDouble() / imageWidth - val newImage = ImageUtil.scaleImage(currentImage, ratioToFit) + val newImage = ImageUtil.scaleImage(currentImage, ratioToFit) - launch(Dispatchers.EDT) { - scaledImage = newImage - revalidate() - } + launch(Dispatchers.EDT) { + scaledImage = newImage + revalidate() } + } } override fun getPreferredSize(): Dimension { val currentImage = scaledImage return if (!isPreferredSizeSet && currentImage != null) { - val dimension = - Dimension( - ImageUtil.getRealWidth(currentImage).coerceAtMost(maximumWidth), - ImageUtil.getRealHeight(currentImage).coerceAtMost(maximumHeight), - ) + val dimension = Dimension( + ImageUtil.getRealWidth(currentImage).coerceAtMost(maximumWidth), + ImageUtil.getRealHeight(currentImage).coerceAtMost(maximumHeight), + ) dimension } else { super.getPreferredSize() diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleaseChannel.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleaseChannel.kt index 70c3c1b2d0..ac6fc7710a 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleaseChannel.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleaseChannel.kt @@ -4,21 +4,19 @@ import com.intellij.ui.JBColor import java.awt.Color @Suppress("UnregisteredNamedColor") // They exist at runtime -public enum class ReleaseChannel( - public val background: Color, - public val foreground: Color, +enum class ReleaseChannel( + val background: Color, + val foreground: Color, ) { Stable( - background = - JBColor( + background = JBColor( /* regular = */ JBColor.namedColor("ColorPalette.Green10", 0xE6F7E9), /* dark = */ JBColor.namedColor("ColorPalette.Green3", 0x436946), ), - foreground = - JBColor( + foreground = JBColor( /* regular = */ JBColor.namedColor("ColorPalette.Green5", 0x369650), /* dark = */ @@ -26,15 +24,13 @@ public enum class ReleaseChannel( ), ), Beta( - background = - JBColor( + background = JBColor( /* regular = */ JBColor.namedColor("ColorPalette.Yellow10", 0xFCEBA4), /* dark = */ JBColor.namedColor("ColorPalette.Yellow3", 0x826A41), ), - foreground = - JBColor( + foreground = JBColor( /* regular = */ JBColor.namedColor("ColorPalette.Yellow4", 0xFFAF0F), /* dark = */ @@ -42,15 +38,13 @@ public enum class ReleaseChannel( ), ), Canary( - background = - JBColor( + background = JBColor( /* regular = */ JBColor.namedColor("ColorPalette.Orange8", 0xEC8F4C), /* dark = */ JBColor.namedColor("ColorPalette.Orange3", 0x825845), ), - foreground = - JBColor( + foreground = JBColor( /* regular = */ JBColor.namedColor("ColorPalette.Orange5", 0xEC8F4C), /* dark = */ @@ -58,15 +52,13 @@ public enum class ReleaseChannel( ), ), Other( - background = - JBColor( + background = JBColor( /* regular = */ JBColor.namedColor("ColorPalette.Grey12", 0xEBECF0), /* dark = */ JBColor.namedColor("ColorPalette.Grey5", 0x4E5157), ), - foreground = - JBColor( + foreground = JBColor( /* regular = */ JBColor.namedColor("ColorPalette.Grey6", 0x6C707E), /* dark = */ diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt index 2411f37672..1593cbc281 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt @@ -102,7 +102,7 @@ import kotlin.time.Duration.Companion.seconds @OptIn(DependsOnJBR::class) @Composable -public fun ReleasesSampleCompose(project: Project) { +fun ReleasesSampleCompose(project: Project) { SwingBridgeTheme { var selectedItem: ContentItem? by remember { mutableStateOf(null) } HorizontalSplitLayout( @@ -138,7 +138,9 @@ private fun LeftColumn( Column(modifier) { Row( - modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Min).padding(4.dp, 6.dp), + modifier = Modifier.fillMaxWidth() + .height(IntrinsicSize.Min) + .padding(4.dp, 6.dp), verticalAlignment = Alignment.CenterVertically, ) { Text("Filter elements:") @@ -149,7 +151,9 @@ private fun LeftColumn( Spacer(Modifier.width(4.dp)) - OverflowMenu(currentContentSource) { service.setContentSource(it) } + OverflowMenu(currentContentSource) { + service.setContentSource(it) + } } val listState = rememberSelectableLazyListState() @@ -159,12 +163,11 @@ private fun LeftColumn( state = listState, selectionMode = SelectionMode.Single, onSelectedIndexesChanged = { - val selectedItem = - if (it.isNotEmpty()) { - currentContentSource.items[it.first()] - } else { - null - } + val selectedItem = if (it.isNotEmpty()) { + currentContentSource.items[it.first()] + } else { + null + } onSelectedItemChange(selectedItem) }, @@ -179,7 +182,9 @@ private fun LeftColumn( } }, ) { - ContentItemRow(it, isSelected, isActive) { newFilter -> service.filterContent(newFilter) } + ContentItemRow(it, isSelected, isActive) { newFilter -> + service.filterContent(newFilter) + } } } @@ -198,15 +203,13 @@ private fun ContentItemRow( isActive: Boolean, onTagClick: (String) -> Unit, ) { - val color = - when { - isSelected && isActive -> retrieveColorOrUnspecified("List.selectionBackground") - isSelected && !isActive -> retrieveColorOrUnspecified("List.selectionInactiveBackground") - else -> Transparent - } + val color = when { + isSelected && isActive -> retrieveColorOrUnspecified("List.selectionBackground") + isSelected && !isActive -> retrieveColorOrUnspecified("List.selectionInactiveBackground") + else -> Transparent + } Row( - modifier = - Modifier.height(JewelTheme.globalMetrics.rowHeight) + modifier = Modifier.height(JewelTheme.globalMetrics.rowHeight) .background(color) .padding(start = 4.dp, end = 12.dp), verticalAlignment = Alignment.CenterVertically, @@ -229,6 +232,7 @@ private fun ContentItemRow( modifier = pointerModifier.onClick { onTagClick(item.apiLevel.toString()) }, ) } + is ContentItem.AndroidStudio -> { val channel = item.channel ItemTag( @@ -255,13 +259,14 @@ private fun ItemTag( text = text, fontSize = JBFont.medium().size2D.sp, color = foregroundColor, - modifier = modifier.background(backgroundColor, shape).padding(padding), + modifier = modifier + .background(backgroundColor, shape) + .padding(padding), ) } private enum class ItemType { - AndroidRelease, - AndroidStudio, + AndroidRelease, AndroidStudio } @Composable @@ -273,7 +278,9 @@ private fun SearchBar( val focusRequester = remember { FocusRequester() } - LaunchedEffect(Unit) { focusRequester.requestFocus() } + LaunchedEffect(Unit) { + focusRequester.requestFocus() + } TextField( value = filterText, @@ -316,14 +323,13 @@ private fun CloseIconButton( Icon( painter = if (hovered) hoveredCloseIcon else closeIcon, contentDescription = "Clear", - modifier = - Modifier.pointerHoverIcon(PointerIcon.Default).clickable( - interactionSource = interactionSource, - indication = null, - role = Role.Button, - ) { - service.resetFilter() - }, + modifier = Modifier + .pointerHoverIcon(PointerIcon.Default) + .clickable( + interactionSource = interactionSource, + indication = null, + role = Role.Button, + ) { service.resetFilter() }, ) } @@ -342,9 +348,7 @@ private fun OverflowMenu( is HoverInteraction.Enter -> hovered = true is HoverInteraction.Exit -> hovered = false is PressInteraction.Press -> pressed = true - is PressInteraction.Release, - is PressInteraction.Cancel, - -> pressed = false + is PressInteraction.Release, is PressInteraction.Cancel -> pressed = false } } } @@ -353,18 +357,17 @@ private fun OverflowMenu( // Emulates Swing actions that pop up menus — they stay pressed while the menu is open IconButton( - modifier = - Modifier.fillMaxHeight().thenIf(menuVisible) { - background( - color = JewelTheme.iconButtonStyle.colors.backgroundPressed, - shape = RoundedCornerShape(JewelTheme.iconButtonStyle.metrics.cornerSize), - ) - .border( + modifier = Modifier.fillMaxHeight() + .thenIf(menuVisible) { + background( + color = JewelTheme.iconButtonStyle.colors.backgroundPressed, + shape = RoundedCornerShape(JewelTheme.iconButtonStyle.metrics.cornerSize), + ).border( width = JewelTheme.iconButtonStyle.metrics.borderWidth, color = JewelTheme.iconButtonStyle.colors.backgroundPressed, shape = RoundedCornerShape(JewelTheme.iconButtonStyle.metrics.cornerSize), ) - }, + }, onClick = { menuVisible = !menuVisible }, ) { Icon( @@ -374,11 +377,12 @@ private fun OverflowMenu( ) } - val contentSources = remember { listOf(AndroidStudioReleases, AndroidReleases) } + val contentSources = remember { + listOf(AndroidStudioReleases, AndroidReleases) + } if (menuVisible) { - val checkedIconProvider = - rememberResourcePainterProvider("actions/checked.svg", AllIcons::class.java) + val checkedIconProvider = rememberResourcePainterProvider("actions/checked.svg", AllIcons::class.java) val checkedIcon by checkedIconProvider.getPainter() PopupMenu( @@ -425,10 +429,7 @@ private fun RightColumn( ) { Box(modifier, contentAlignment = Alignment.Center) { if (selectedItem == null) { - Text( - "Nothing to see here", - color = JBUI.CurrentTheme.Label.disabledForeground().toComposeColor(), - ) + Text("Nothing to see here", color = JBUI.CurrentTheme.Label.disabledForeground().toComposeColor()) } else { val scrollState = rememberScrollState() VerticalScrollbarContainer(scrollState, modifier = modifier) { @@ -454,20 +455,15 @@ private fun ReleaseImage(imagePath: String) { val painterProvider = rememberResourcePainterProvider(imagePath, JewelIcons::class.java) val painter by painterProvider.getPainter() val transition = rememberInfiniteTransition("HoloFoil") - val offset by - transition.animateFloat( - initialValue = -1f, - targetValue = 1f, - animationSpec = - infiniteRepeatable( - tween( - durationMillis = 2.seconds.inWholeMilliseconds.toInt(), - easing = FastOutSlowInEasing, - ), - repeatMode = RepeatMode.Reverse, - ), - "holoFoil offset", - ) + val offset by transition.animateFloat( + initialValue = -1f, + targetValue = 1f, + animationSpec = infiniteRepeatable( + tween(durationMillis = 2.seconds.inWholeMilliseconds.toInt(), easing = FastOutSlowInEasing), + repeatMode = RepeatMode.Reverse, + ), + "holoFoil offset", + ) var isHovered by remember { mutableStateOf(false) } var applyModifier by remember { mutableStateOf(false) } val intensity by animateFloatAsState(if (isHovered) 1f else 0f, animationSpec = tween(300)) @@ -477,8 +473,7 @@ private fun ReleaseImage(imagePath: String) { Image( painter = painter, contentDescription = null, - modifier = - Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth() .sizeIn(minHeight = 150.dp, maxHeight = 250.dp) .onHover { newIsHovered -> scope.launch { @@ -517,8 +512,7 @@ private fun ItemDetailsText(selectedItem: ContentItem) { ) { Text( selectedItem.displayText, - style = - runBlocking { + style = runBlocking { retrieveTextStyle( key = "Label.font", bold = true, @@ -575,11 +569,10 @@ private fun TextWithLabel(labelText: String, valueText: String) { // Logic from com.intellij.openapi.ui.panel.ComponentPanelBuilder#getCommentFont private fun getCommentFontSize(font: Font = JBFont.label()): TextUnit { - val commentFont = - if (NewUI.isEnabled()) { - JBFont.medium() - } else { - RelativeFont.NORMAL.fromResource("ContextHelp.fontSizeOffset", -2).derive(font) - } + val commentFont = if (NewUI.isEnabled()) { + JBFont.medium() + } else { + RelativeFont.NORMAL.fromResource("ContextHelp.fontSizeOffset", -2).derive(font) + } return commentFont.size2D.sp } diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSamplePanel.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSamplePanel.kt index 3acb973311..c026005e2a 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSamplePanel.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSamplePanel.kt @@ -24,57 +24,55 @@ import javax.swing.ListSelectionModel import javax.swing.event.DocumentEvent import javax.swing.event.DocumentListener -public class ReleasesSamplePanel(scope: CoroutineScope) : BorderLayoutPanel() { +class ReleasesSamplePanel(scope: CoroutineScope) : BorderLayoutPanel() { private val sidePanel = DetailsPanel(scope) private var currentContentSource: ContentSource<*> = AndroidStudioReleases - private val filterTextField = - SearchTextField(false).apply { - addDocumentListener( - object : DocumentListener { - override fun insertUpdate(e: DocumentEvent) { - filterContent(text) - } - - override fun removeUpdate(e: DocumentEvent) { - filterContent(text) - } - - override fun changedUpdate(e: DocumentEvent) { - filterContent(text) - } - }, - ) - } + private val filterTextField = SearchTextField(false).apply { + addDocumentListener(object : DocumentListener { + override fun insertUpdate(e: DocumentEvent) { + filterContent(text) + } - private val actions: List = - listOf( - object : CheckboxAction(AndroidStudioReleases.displayName), DumbAware { + override fun removeUpdate(e: DocumentEvent) { + filterContent(text) + } - override fun isSelected(e: AnActionEvent): Boolean = - currentContentSource == AndroidStudioReleases + override fun changedUpdate(e: DocumentEvent) { + filterContent(text) + } + }) + } - override fun setSelected(e: AnActionEvent, state: Boolean) { - setContentSource(AndroidStudioReleases) - } + private val actions: List = listOf( + object : CheckboxAction(AndroidStudioReleases.displayName), DumbAware { - override fun getActionUpdateThread() = ActionUpdateThread.BGT - }, - object : CheckboxAction(AndroidReleases.displayName), DumbAware { + override fun isSelected(e: AnActionEvent): Boolean = + currentContentSource == AndroidStudioReleases - override fun isSelected(e: AnActionEvent): Boolean = currentContentSource == AndroidReleases + override fun setSelected(e: AnActionEvent, state: Boolean) { + setContentSource(AndroidStudioReleases) + } - override fun setSelected(e: AnActionEvent, state: Boolean) { - setContentSource(AndroidReleases) - } + override fun getActionUpdateThread() = ActionUpdateThread.BGT + }, + object : CheckboxAction(AndroidReleases.displayName), DumbAware { - override fun getActionUpdateThread() = ActionUpdateThread.BGT - }, - ) + override fun isSelected(e: AnActionEvent): Boolean = + currentContentSource == AndroidReleases + + override fun setSelected(e: AnActionEvent, state: Boolean) { + setContentSource(AndroidReleases) + } - private val overflowAction = MoreActionGroup().apply { addAll(actions) } + override fun getActionUpdateThread() = ActionUpdateThread.BGT + }, + ) + + private val overflowAction = MoreActionGroup() + .apply { addAll(actions) } private val overflowActionButton: ActionButton = ActionButton( @@ -84,41 +82,37 @@ public class ReleasesSamplePanel(scope: CoroutineScope) : BorderLayoutPanel() { ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE, ) - private val topBar = - BorderLayoutPanel().apply { - addToLeft(JBLabel("Filter elements: ")) - addToCenter(filterTextField) - addToRight(overflowActionButton) - border = JBUI.Borders.empty(4) - } + private val topBar = BorderLayoutPanel().apply { + addToLeft(JBLabel("Filter elements: ")) + addToCenter(filterTextField) + addToRight(overflowActionButton) + border = JBUI.Borders.empty(4) + } private var lastSelected: ContentItem? = null - private val contentList = - JBList().apply { - selectionMode = ListSelectionModel.SINGLE_SELECTION - - addListSelectionListener { - if (selectedValue != lastSelected) { - lastSelected = selectedValue - onListSelectionChanged() - } + private val contentList = JBList().apply { + selectionMode = ListSelectionModel.SINGLE_SELECTION + + addListSelectionListener { + if (selectedValue != lastSelected) { + lastSelected = selectedValue + onListSelectionChanged() } } + } - private val mainPanel = - BorderLayoutPanel().apply { - addToTop(topBar) - - val scrollPane = - JBScrollPane(contentList).apply { - setBorder(JBUI.Borders.empty()) - setViewportBorder(JBUI.Borders.empty()) - horizontalScrollBarPolicy = JBScrollPane.HORIZONTAL_SCROLLBAR_NEVER - } + private val mainPanel = BorderLayoutPanel().apply { + addToTop(topBar) - addToCenter(scrollPane) + val scrollPane = JBScrollPane(contentList).apply { + setBorder(JBUI.Borders.empty()) + setViewportBorder(JBUI.Borders.empty()) + horizontalScrollBarPolicy = JBScrollPane.HORIZONTAL_SCROLLBAR_NEVER } + addToCenter(scrollPane) + } + init { val splitter = OnePixelSplitter(false, .7f, .25f, .75f) splitter.firstComponent = mainPanel diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleService.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleService.kt index 7bee7bebd6..c68d270609 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleService.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleService.kt @@ -20,8 +20,7 @@ internal class ReleasesSampleService : CoroutineScope, Disposable { private val dispatcher = AppExecutorUtil.getAppExecutorService().asCoroutineDispatcher() - override val coroutineContext = - SupervisorJob() + CoroutineName("ReleasesSampleService") + dispatcher + override val coroutineContext = SupervisorJob() + CoroutineName("ReleasesSampleService") + dispatcher private val originalContentSource = MutableStateFlow>(AndroidStudioReleases) @@ -36,7 +35,8 @@ internal class ReleasesSampleService : CoroutineScope, Disposable { val normalizedFilter = filter.trim() if (normalizedFilter.isBlank()) return@combine source - val filteredContentItems = source.items.filter { it.matches(normalizedFilter) } + val filteredContentItems = source.items + .filter { it.matches(normalizedFilter) } FilteredContentSource(filteredContentItems, source) } @@ -44,18 +44,18 @@ internal class ReleasesSampleService : CoroutineScope, Disposable { .launchIn(this) } - public fun setContentSource(contentSource: ContentSource<*>) { + fun setContentSource(contentSource: ContentSource<*>) { if (contentSource != originalContentSource.value) { originalContentSource.tryEmit(contentSource) resetFilter() } } - public fun resetFilter() { + fun resetFilter() { filterContent("") } - public fun filterContent(filter: String) { + fun filterContent(filter: String) { _filter.tryEmit(filter) } diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/UiInspectorUtil.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/UiInspectorUtil.kt index 62149b6e68..5374ec82d3 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/UiInspectorUtil.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/UiInspectorUtil.kt @@ -4,7 +4,7 @@ import com.intellij.internal.inspector.PropertyBean import com.intellij.internal.inspector.UiInspectorUtil import javax.swing.JComponent -public fun JComponent.registerUiInspectorInfoProvider(provider: () -> Map) { +fun JComponent.registerUiInspectorInfoProvider(provider: () -> Map) { UiInspectorUtil.registerProvider(this) { provider().map { (key, value) -> PropertyBean(key, value) } } diff --git a/samples/standalone/build.gradle.kts b/samples/standalone/build.gradle.kts index cc7f27658b..6eb080e217 100644 --- a/samples/standalone/build.gradle.kts +++ b/samples/standalone/build.gradle.kts @@ -11,7 +11,9 @@ dependencies { implementation(libs.kotlin.reflect) implementation(projects.intUi.intUiStandalone) implementation(projects.intUi.intUiDecoratedWindow) - implementation(compose.desktop.currentOs) { exclude(group = "org.jetbrains.compose.material") } + implementation(compose.desktop.currentOs) { + exclude(group = "org.jetbrains.compose.material") + } } compose.desktop { diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/IntUiThemes.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/IntUiThemes.kt index d8d0c981e8..a5659b923e 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/IntUiThemes.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/IntUiThemes.kt @@ -3,23 +3,20 @@ package org.jetbrains.jewel.samples.standalone import org.jetbrains.skiko.SystemTheme import org.jetbrains.skiko.currentSystemTheme -public enum class IntUiThemes { +enum class IntUiThemes { Light, LightWithLightHeader, Dark, SYSTEM; - public fun isDark(): Boolean { - val theme = if (this == SYSTEM) { - fromSystemTheme(currentSystemTheme) - } else { - this - } - return theme == Dark - } + fun isDark(): Boolean = if (this == SYSTEM) { + fromSystemTheme(currentSystemTheme) + } else { + this + } == Dark - public fun isLightHeader(): Boolean = this == LightWithLightHeader + fun isLightHeader() = this == LightWithLightHeader - public companion object { + companion object { - public fun fromSystemTheme(systemTheme: SystemTheme): IntUiThemes = + fun fromSystemTheme(systemTheme: SystemTheme) = if (systemTheme == SystemTheme.LIGHT) Light else Dark } } diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt index 651495ab1d..b77a402339 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt @@ -20,7 +20,7 @@ import org.jetbrains.jewel.window.DecoratedWindow import org.jetbrains.jewel.window.styling.TitleBarStyle import java.io.InputStream -public fun main() { +fun main() { val icon = svgResource("icons/jewel-logo.svg") application { val themeDefinition = @@ -33,8 +33,7 @@ public fun main() { IntUiTheme( themeDefinition, ComponentStyling.decoratedWindow( - titleBarStyle = - when (MainViewModel.theme) { + titleBarStyle = when (MainViewModel.theme) { IntUiThemes.Light -> TitleBarStyle.light() IntUiThemes.LightWithLightHeader -> TitleBarStyle.lightWithLightHeader() IntUiThemes.Dark -> TitleBarStyle.dark() @@ -63,4 +62,7 @@ private fun svgResource( resourcePath: String, loader: ResourceLoader = ResourceLoader.Default, ): Painter = - loader.load(resourcePath).use { stream: InputStream -> loadSvgPainter(stream, Density(1f)) } + loader.load(resourcePath) + .use { stream: InputStream -> + loadSvgPainter(stream, Density(1f)) + } diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/StandaloneSampleIcons.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/StandaloneSampleIcons.kt index 19f517d5f1..bbf0bc6e97 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/StandaloneSampleIcons.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/StandaloneSampleIcons.kt @@ -1,3 +1,3 @@ package org.jetbrains.jewel.samples.standalone -public object StandaloneSampleIcons +object StandaloneSampleIcons diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/ComponentsView.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/ComponentsView.kt index 52642fc6a6..4e50af6e30 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/ComponentsView.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/ComponentsView.kt @@ -33,7 +33,7 @@ import org.jetbrains.jewel.ui.painter.rememberResourcePainterProvider @Composable @View(title = "Components", position = 1, icon = "icons/structure.svg") -public fun ComponentsView() { +fun ComponentsView() { Row(Modifier.trackActivation().fillMaxSize().background(JewelTheme.globalColors.paneBackground)) { ComponentsToolBar() Divider(Orientation.Vertical) @@ -42,7 +42,7 @@ public fun ComponentsView() { } @Composable -public fun ComponentsToolBar() { +fun ComponentsToolBar() { Column(Modifier.fillMaxHeight().width(40.dp)) { ComponentsViewModel.views.forEach { Tooltip({ @@ -62,7 +62,7 @@ public fun ComponentsToolBar() { } @Composable -public fun ComponentView(view: ViewInfo) { +fun ComponentView(view: ViewInfo) { Column(Modifier.fillMaxSize().padding(24.dp), verticalArrangement = Arrangement.spacedBy(24.dp)) { Text(view.title, fontSize = 20.sp) view.content() diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/TitleBarView.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/TitleBarView.kt index 31cd709899..21de995ecc 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/TitleBarView.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/TitleBarView.kt @@ -27,7 +27,7 @@ import java.awt.Desktop import java.net.URI @Composable -public fun DecoratedWindowScope.TitleBarView() { +fun DecoratedWindowScope.TitleBarView() { TitleBar(Modifier.newFullscreenControls(), gradientStartColor = MainViewModel.projectColor) { Row(Modifier.align(Alignment.Start)) { Dropdown(Modifier.height(30.dp), menuContent = { diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/WelcomeView.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/WelcomeView.kt index af1c46b5a2..5d89da89eb 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/WelcomeView.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/WelcomeView.kt @@ -29,7 +29,7 @@ import org.jetbrains.jewel.ui.painter.rememberResourcePainterProvider @Composable @View(title = "Welcome", position = 0, icon = "icons/meetNewUi.svg") -public fun WelcomeView() { +fun WelcomeView() { Box( Modifier.trackActivation().fillMaxSize() .background(JewelTheme.globalColors.paneBackground) @@ -74,7 +74,7 @@ public fun WelcomeView() { } @Composable -public fun ThemeSelectionChip(theme: IntUiThemes, name: String, icon: String) { +fun ThemeSelectionChip(theme: IntUiThemes, name: String, icon: String) { RadioButtonChip( selected = MainViewModel.theme == theme, onClick = { MainViewModel.theme = theme }, diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Borders.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Borders.kt index 3ca668e9ac..159664c849 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Borders.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Borders.kt @@ -55,10 +55,26 @@ internal fun Borders() { horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically, ) { - OutlinedButton({ width += 1.dp }) { Text("+width") } - OutlinedButton({ width -= 1.dp }, enabled = width > 1.dp) { Text("-width") } - OutlinedButton({ expand += 1.dp }) { Text("+expand") } - OutlinedButton({ expand -= 1.dp }) { Text("-expand") } + OutlinedButton({ + width += 1.dp + }) { + Text("+width") + } + OutlinedButton({ + width -= 1.dp + }, enabled = width > 1.dp) { + Text("-width") + } + OutlinedButton({ + expand += 1.dp + }) { + Text("+expand") + } + OutlinedButton({ + expand -= 1.dp + }) { + Text("-expand") + } } Row( horizontalArrangement = Arrangement.spacedBy(10.dp), diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Buttons.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Buttons.kt index 8239adc6e9..45ae38ac17 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Buttons.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Buttons.kt @@ -17,19 +17,27 @@ import org.jetbrains.jewel.ui.component.Text @Composable @View(title = "Buttons", position = 0) -public fun Buttons() { +fun Buttons() { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.CenterVertically, ) { - OutlinedButton(onClick = {}) { Text("Outlined") } + OutlinedButton(onClick = { }) { + Text("Outlined") + } - OutlinedButton(onClick = {}, enabled = false) { Text("Outlined Disabled") } + OutlinedButton(onClick = {}, enabled = false) { + Text("Outlined Disabled") + } - DefaultButton(onClick = {}) { Text("Default") } + DefaultButton(onClick = {}) { + Text("Default") + } - DefaultButton(onClick = {}, enabled = false) { Text("Default disabled") } + DefaultButton(onClick = {}, enabled = false) { + Text("Default disabled") + } IconButton(onClick = {}) { Icon( diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Checkboxes.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Checkboxes.kt index 3159a9dc6a..917bfe3fde 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Checkboxes.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Checkboxes.kt @@ -16,50 +16,33 @@ import org.jetbrains.jewel.ui.component.TriStateCheckboxRow @Composable @View(title = "Checkboxes", position = 1) -public fun Checkboxes() { +fun Checkboxes() { Row( horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically, ) { var checked by remember { mutableStateOf(ToggleableState.On) } - TriStateCheckboxRow( - "Checkbox", - checked, - { - checked = - when (checked) { - ToggleableState.On -> ToggleableState.Off - ToggleableState.Off -> ToggleableState.Indeterminate - ToggleableState.Indeterminate -> ToggleableState.On - } - }, - ) - TriStateCheckboxRow( - "Error", - checked, - { - checked = - when (checked) { - ToggleableState.On -> ToggleableState.Off - ToggleableState.Off -> ToggleableState.Indeterminate - ToggleableState.Indeterminate -> ToggleableState.On - } - }, - outline = Outline.Error, - ) - TriStateCheckboxRow( - "Warning", - checked, - { - checked = - when (checked) { - ToggleableState.On -> ToggleableState.Off - ToggleableState.Off -> ToggleableState.Indeterminate - ToggleableState.Indeterminate -> ToggleableState.On - } - }, - outline = Outline.Warning, - ) + TriStateCheckboxRow("Checkbox", checked, { + checked = when (checked) { + ToggleableState.On -> ToggleableState.Off + ToggleableState.Off -> ToggleableState.Indeterminate + ToggleableState.Indeterminate -> ToggleableState.On + } + }) + TriStateCheckboxRow("Error", checked, { + checked = when (checked) { + ToggleableState.On -> ToggleableState.Off + ToggleableState.Off -> ToggleableState.Indeterminate + ToggleableState.Indeterminate -> ToggleableState.On + } + }, outline = Outline.Error) + TriStateCheckboxRow("Warning", checked, { + checked = when (checked) { + ToggleableState.On -> ToggleableState.Off + ToggleableState.Off -> ToggleableState.Indeterminate + ToggleableState.Indeterminate -> ToggleableState.On + } + }, outline = Outline.Warning) TriStateCheckboxRow("Disabled", checked, {}, enabled = false) } } diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/ChipsAndTree.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/ChipsAndTree.kt index 4634b72607..1762ce9f31 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/ChipsAndTree.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/ChipsAndTree.kt @@ -36,7 +36,7 @@ import org.jetbrains.jewel.ui.theme.colorPalette @Composable @View(title = "ChipsAndTree", position = 11) -public fun ChipsAndTree() { +fun ChipsAndTree() { Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(16.dp)) { Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(8.dp)) { GroupHeader(text = "Chips", modifier = Modifier.fillMaxWidth()) @@ -56,11 +56,15 @@ public fun ChipsAndTree() { } @Composable -public fun SelectableLazyColumnSample() { - val listOfItems = remember { List((5000..10000).random()) { "Item $it" } } +fun SelectableLazyColumnSample() { + val listOfItems = remember { + List((5000..10000).random()) { "Item $it" } + } val interactionSource = remember { MutableInteractionSource() } SelectableLazyColumn( - modifier = Modifier.size(200.dp, 200.dp).focusable(interactionSource = interactionSource), + modifier = Modifier + .size(200.dp, 200.dp) + .focusable(interactionSource = interactionSource), content = { items( count = listOfItems.size, @@ -75,8 +79,9 @@ public fun SelectableLazyColumnSample() { isSelected && !isActive -> Modifier.background(Color.Gray) else -> Modifier }, - ) - .clickable { println("click on $index") }, + ).clickable { + println("click on $index") + }, ) } }, @@ -85,7 +90,7 @@ public fun SelectableLazyColumnSample() { } @Composable -public fun ChipsSample(modifier: Modifier = Modifier) { +fun ChipsSample(modifier: Modifier = Modifier) { Column(modifier, verticalArrangement = Arrangement.spacedBy(8.dp)) { Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { var selectedIndex by remember { mutableStateOf(-1) } @@ -118,7 +123,9 @@ public fun ChipsSample(modifier: Modifier = Modifier) { var isChecked by remember { mutableStateOf(false) } ToggleableChip( checked = isChecked, - onClick = { isChecked = it }, + onClick = { + isChecked = it + }, enabled = true, ) { Text("Toggleable") @@ -145,7 +152,7 @@ public fun ChipsSample(modifier: Modifier = Modifier) { } @Composable -public fun TreeSample(modifier: Modifier = Modifier) { +fun TreeSample(modifier: Modifier = Modifier) { val tree = remember { buildTree { addNode("root 1") { @@ -180,7 +187,9 @@ public fun TreeSample(modifier: Modifier = Modifier) { onElementClick = {}, onElementDoubleClick = {}, ) { element -> - Box(Modifier.fillMaxWidth()) { Text(element.data, Modifier.padding(2.dp)) } + Box(Modifier.fillMaxWidth()) { + Text(element.data, Modifier.padding(2.dp)) + } } } } diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Dropdowns.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Dropdowns.kt index 22fa2d514b..1097ee18b4 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Dropdowns.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Dropdowns.kt @@ -17,7 +17,7 @@ import org.jetbrains.jewel.ui.component.separator @Composable @View(title = "Dropdowns", position = 3) -public fun Dropdowns() { +fun Dropdowns() { Row( horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically, @@ -36,7 +36,8 @@ public fun Dropdowns() { Dropdown( enabled = false, - menuContent = {}, + menuContent = { + }, ) { Text("Disabled") } @@ -46,35 +47,43 @@ public fun Dropdowns() { if (it == "---") { separator() } else { - selectableItem(selected == it, { selected = it }) { Text(it) } + selectableItem(selected == it, { + selected = it + }) { + Text(it) + } } } separator() - submenu( - submenu = { + submenu(submenu = { + items.forEach { + if (it == "---") { + separator() + } else { + selectableItem(selected == it, { + selected = it + }) { + Text(it) + } + } + } + separator() + submenu(submenu = { items.forEach { if (it == "---") { separator() } else { - selectableItem(selected == it, { selected = it }) { Text(it) } - } - } - separator() - submenu( - submenu = { - items.forEach { - if (it == "---") { - separator() - } else { - selectableItem(selected == it, { selected = it }) { Text(it) } - } + selectableItem(selected == it, { + selected = it + }) { + Text(it) } - }, - ) { - Text("Submenu2") + } } - }, - ) { + }) { + Text("Submenu2") + } + }) { Text("Submenu") } }, @@ -88,7 +97,11 @@ public fun Dropdowns() { if (it == "---") { separator() } else { - selectableItem(selected == it, { selected = it }) { Text(it) } + selectableItem(selected == it, { + selected = it + }) { + Text(it) + } } } }, diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Links.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Links.kt index 613cbeee7f..42e892752d 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Links.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Links.kt @@ -18,7 +18,7 @@ import org.jetbrains.jewel.ui.component.separator @Composable @View(title = "Links", position = 4) -public fun Links() { +fun Links() { Row( horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically, @@ -43,7 +43,11 @@ public fun Links() { if (it == "---") { separator() } else { - selectableItem(selected == it, { selected = it }) { Text(it) } + selectableItem(selected == it, { + selected = it + }) { + Text(it) + } } } } @@ -56,6 +60,7 @@ public fun Links() { ExternalLink("ExternalLink", {}, enabled = false) - DropdownLink("DropdownLink", enabled = false) {} + DropdownLink("DropdownLink", enabled = false) { + } } } diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/ProgressBar.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/ProgressBar.kt index cc3a0649d5..96a58e2662 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/ProgressBar.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/ProgressBar.kt @@ -27,22 +27,19 @@ import org.jetbrains.jewel.ui.component.Text @Composable @View(title = "ProgressBar", position = 5) -public fun ProgressBar() { +fun ProgressBar() { val transition = rememberInfiniteTransition() - val currentOffset by - transition.animateFloat( - initialValue = 0f, - targetValue = 1f, - animationSpec = - infiniteRepeatable( - animation = - keyframes { - durationMillis = 4000 - 0f at 1000 - 1f at 3000 - }, - ), - ) + val currentOffset by transition.animateFloat( + initialValue = 0f, + targetValue = 1f, + animationSpec = infiniteRepeatable( + animation = keyframes { + durationMillis = 4000 + 0f at 1000 + 1f at 3000 + }, + ), + ) var intermittentProgress by remember { mutableStateOf(0f) } LaunchedEffect(Unit) { while (true) { @@ -83,8 +80,7 @@ public fun ProgressBar() { horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, ) { - val smoothedProgress by - androidx.compose.animation.core.animateFloatAsState(intermittentProgress) + val smoothedProgress by androidx.compose.animation.core.animateFloatAsState(intermittentProgress) HorizontalProgressBar(modifier = Modifier.width(500.dp), progress = smoothedProgress) Text("${(intermittentProgress * 100).toInt()} %") } diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/RadioButtons.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/RadioButtons.kt index 39948692ed..a74e516471 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/RadioButtons.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/RadioButtons.kt @@ -15,7 +15,7 @@ import org.jetbrains.jewel.ui.component.RadioButtonRow @Composable @View(title = "RadioButtons", position = 2) -public fun RadioButtons() { +fun RadioButtons() { Row( horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically, diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Tabs.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Tabs.kt index adcad646e9..fee1e7dcc4 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Tabs.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Tabs.kt @@ -37,7 +37,7 @@ import kotlin.math.max @Composable @View(title = "Tabs", position = 7) -public fun Tabs() { +fun Tabs() { Text("Default tabs", Modifier.fillMaxWidth()) DefaultTabShowcase() @@ -62,7 +62,8 @@ private fun DefaultTabShowcase() { tabIds = tabIds.toMutableList().apply { removeAt(index) } if (selectedTabIndex >= index) { val maxPossibleIndex = max(0, tabIds.lastIndex) - selectedTabIndex = (selectedTabIndex - 1).coerceIn(0..maxPossibleIndex) + selectedTabIndex = (selectedTabIndex - 1) + .coerceIn(0..maxPossibleIndex) } }, onClick = { selectedTabIndex = index }, @@ -74,7 +75,8 @@ private fun DefaultTabShowcase() { val insertionIndex = (selectedTabIndex + 1).coerceIn(0..tabIds.size) val nextTabId = maxId + 1 - tabIds = tabIds.toMutableList().apply { add(insertionIndex, nextTabId) } + tabIds = tabIds.toMutableList() + .apply { add(insertionIndex, nextTabId) } selectedTabIndex = insertionIndex } } @@ -95,7 +97,8 @@ private fun EditorTabShowcase() { tabIds = tabIds.toMutableList().apply { removeAt(index) } if (selectedTabIndex >= index) { val maxPossibleIndex = max(0, tabIds.lastIndex) - selectedTabIndex = (selectedTabIndex - 1).coerceIn(0..maxPossibleIndex) + selectedTabIndex = (selectedTabIndex - 1) + .coerceIn(0..maxPossibleIndex) } }, onClick = { selectedTabIndex = index }, @@ -107,7 +110,8 @@ private fun EditorTabShowcase() { val insertionIndex = (selectedTabIndex + 1).coerceIn(0..tabIds.size) val nextTabId = maxId + 1 - tabIds = tabIds.toMutableList().apply { add(insertionIndex, nextTabId) } + tabIds = tabIds.toMutableList() + .apply { add(insertionIndex, nextTabId) } selectedTabIndex = insertionIndex } } @@ -135,16 +139,14 @@ private fun TabStripWithAddButton( } // TODO create an IconButton instead of this hack - val backgroundColor = - if (isHovered) { - JewelTheme.defaultTabStyle.colors.backgroundHovered - } else { - JewelTheme.defaultTabStyle.colors.background - } + val backgroundColor = if (isHovered) { + JewelTheme.defaultTabStyle.colors.backgroundHovered + } else { + JewelTheme.defaultTabStyle.colors.background + } Box( - modifier = - Modifier.size(JewelTheme.defaultTabStyle.metrics.tabHeight) + modifier = Modifier.size(JewelTheme.defaultTabStyle.metrics.tabHeight) .clickable( onClick = onAddClick, onClickLabel = "Add a tab", diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextAreas.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextAreas.kt index e2b47c5af7..8a93949fad 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextAreas.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextAreas.kt @@ -18,22 +18,21 @@ import org.jetbrains.jewel.ui.component.Text import org.jetbrains.jewel.ui.component.TextArea @Suppress("SpellCheckingInspection") -private const val LOREM_IPSUM = - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. \n" + - "Sed auctor, neque in accumsan vehicula, enim purus vestibulum odio, non tristique dolor quam vel ipsum. \n" + - "Proin egestas, orci id hendrerit bibendum, nisl neque imperdiet nisl, a euismod nibh diam nec lectus. \n" + - "Duis euismod, quam nec aliquam iaculis, dolor lorem bibendum turpis, vel malesuada augue sapien vel mi. \n" + - "Quisque ut facilisis nibh. Maecenas euismod hendrerit sem, ac scelerisque odio auctor nec. \n" + - "Sed sit amet consequat eros. Donec nisl tellus, accumsan nec ligula in, eleifend sodales sem. \n" + - "Sed malesuada, nulla ac eleifend fermentum, nibh mi consequat quam, quis convallis lacus nunc eu dui. \n" + - "Pellentesque eget enim quis orci porttitor consequat sed sed quam. \n" + - "Sed aliquam, nisl et lacinia lacinia, diam nunc laoreet nisi, sit amet consectetur dolor lorem et sem. \n" + - "Duis ultricies, mauris in aliquam interdum, orci nulla finibus massa, a tristique urna sapien vel quam. \n" + - "Sed nec sapien nec dui rhoncus bibendum. Sed blandit bibendum libero." +private const val LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. \n" + + "Sed auctor, neque in accumsan vehicula, enim purus vestibulum odio, non tristique dolor quam vel ipsum. \n" + + "Proin egestas, orci id hendrerit bibendum, nisl neque imperdiet nisl, a euismod nibh diam nec lectus. \n" + + "Duis euismod, quam nec aliquam iaculis, dolor lorem bibendum turpis, vel malesuada augue sapien vel mi. \n" + + "Quisque ut facilisis nibh. Maecenas euismod hendrerit sem, ac scelerisque odio auctor nec. \n" + + "Sed sit amet consequat eros. Donec nisl tellus, accumsan nec ligula in, eleifend sodales sem. \n" + + "Sed malesuada, nulla ac eleifend fermentum, nibh mi consequat quam, quis convallis lacus nunc eu dui. \n" + + "Pellentesque eget enim quis orci porttitor consequat sed sed quam. \n" + + "Sed aliquam, nisl et lacinia lacinia, diam nunc laoreet nisi, sit amet consectetur dolor lorem et sem. \n" + + "Duis ultricies, mauris in aliquam interdum, orci nulla finibus massa, a tristique urna sapien vel quam. \n" + + "Sed nec sapien nec dui rhoncus bibendum. Sed blandit bibendum libero." @Composable @View(title = "TextAreas", position = 8) -public fun TextAreas() { +fun TextAreas() { Row( Modifier.padding(horizontal = 16.dp).height(150.dp), horizontalArrangement = Arrangement.spacedBy(16.dp), diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextFields.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextFields.kt index a437f3678b..30f6b61127 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextFields.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextFields.kt @@ -33,7 +33,7 @@ import org.jetbrains.jewel.ui.painter.rememberResourcePainterProvider @Composable @View(title = "TextFields", position = 9) -public fun TextFields() { +fun TextFields() { Row( horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically, @@ -45,20 +45,10 @@ public fun TextFields() { TextField(text2, { text2 = it }, placeholder = { Text("Placeholder") }) var text3 by remember { mutableStateOf("") } - TextField( - text3, - { text3 = it }, - outline = Outline.Error, - placeholder = { Text("Error outline") }, - ) + TextField(text3, { text3 = it }, outline = Outline.Error, placeholder = { Text("Error outline") }) var text4 by remember { mutableStateOf("") } - TextField( - text4, - { text4 = it }, - outline = Outline.Warning, - placeholder = { Text("Warning outline") }, - ) + TextField(text4, { text4 = it }, outline = Outline.Warning, placeholder = { Text("Warning outline") }) var text5 by remember { mutableStateOf("Disabled") } TextField(text5, { text5 = it }, enabled = false) diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Tooltips.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Tooltips.kt index 1be170f73a..d8de039ffc 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Tooltips.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Tooltips.kt @@ -12,7 +12,7 @@ import org.jetbrains.jewel.ui.component.Tooltip @Composable @View(title = "Tooltips", position = 10) -public fun Tooltips() { +fun Tooltips() { Tooltip(tooltip = { Text("This is a tooltip") }) { diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/ComponentsViewModel.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/ComponentsViewModel.kt index 391659273d..073b6f14da 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/ComponentsViewModel.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/ComponentsViewModel.kt @@ -3,15 +3,12 @@ package org.jetbrains.jewel.samples.standalone.viewmodel import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue -import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.runtime.toMutableStateList import org.jetbrains.jewel.samples.standalone.reflection.findViews -public object ComponentsViewModel { +object ComponentsViewModel { - public val views: SnapshotStateList = - findViews("org.jetbrains.jewel.samples.standalone.view.component") - .toMutableStateList() + val views = findViews("org.jetbrains.jewel.samples.standalone.view.component").toMutableStateList() - public var currentView: ViewInfo by mutableStateOf(views.first()) + var currentView by mutableStateOf(views.first()) } diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt index 7b6b2bbe44..c45f0bfbf5 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt @@ -3,28 +3,25 @@ package org.jetbrains.jewel.samples.standalone.viewmodel import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue -import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.runtime.toMutableStateList import androidx.compose.ui.graphics.Color import org.jetbrains.jewel.samples.standalone.IntUiThemes import org.jetbrains.jewel.samples.standalone.reflection.findViews -public object MainViewModel { +object MainViewModel { - public var theme: IntUiThemes by mutableStateOf(IntUiThemes.Light) + var theme: IntUiThemes by mutableStateOf(IntUiThemes.Light) - public var swingCompat: Boolean by mutableStateOf(false) + var swingCompat: Boolean by mutableStateOf(false) - public val projectColor: Color + val projectColor get() = if (theme.isLightHeader()) { Color(0xFFF5D4C1) } else { Color(0xFF654B40) } - public val views: SnapshotStateList = - findViews("org.jetbrains.jewel.samples.standalone.view") - .toMutableStateList() + val views = findViews("org.jetbrains.jewel.samples.standalone.view").toMutableStateList() - public var currentView: ViewInfo by mutableStateOf(views.first()) + var currentView by mutableStateOf(views.first()) } diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/View.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/View.kt index 1d2d6676dc..aec63c969a 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/View.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/View.kt @@ -2,16 +2,16 @@ package org.jetbrains.jewel.samples.standalone.viewmodel import androidx.compose.runtime.Composable -public data class ViewInfo( - public val title: String, - public val position: Int, - public val icon: String, - public val content: @Composable () -> Unit, +data class ViewInfo( + val title: String, + val position: Int, + val icon: String, + val content: @Composable () -> Unit, ) @Target(AnnotationTarget.FUNCTION) -public annotation class View( - public val title: String, - public val position: Int = 0, - public val icon: String = "icons/stub.svg", +annotation class View( + val title: String, + val position: Int = 0, + val icon: String = "icons/stub.svg", ) diff --git a/samples/standalone/src/main/resources/fonts/Roboto/LICENSE.txt b/samples/standalone/src/main/resources/fonts/Roboto/LICENSE.txt index 97594b3419..d645695673 100644 --- a/samples/standalone/src/main/resources/fonts/Roboto/LICENSE.txt +++ b/samples/standalone/src/main/resources/fonts/Roboto/LICENSE.txt @@ -34,7 +34,7 @@ and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or - public object form, made available under the License, as indicated by a + Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).