Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support different plugin mode (simple and icon pack mode) #6

Merged
merged 29 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
92f6263
- support Simple and Icon pack mode
egorikftp Jun 25, 2024
4f8829e
Move ImageVectorGenerator into new package
egorikftp Jun 26, 2024
82fe6e2
Generate IconPack object class
egorikftp Jun 26, 2024
e53712e
Clean up dependencies
egorikftp Jun 26, 2024
f5d2559
add mutable state wrapper
egorikftp Jun 28, 2024
18148e5
Add ability to export icon pack
egorikftp Jun 28, 2024
300655b
create CodeBlockAnnotatedString
egorikftp Jun 28, 2024
2504a31
create IconButton component
egorikftp Jun 28, 2024
3cd95c0
allow to preview icon pack object class
egorikftp Jun 28, 2024
a59ea59
repackage classes
egorikftp Jun 28, 2024
a49c4d8
refresh filesystem after export
egorikftp Jun 28, 2024
0540594
separate SimpleConversionScreen and IconPackConversionScreen
egorikftp Jun 28, 2024
c6edc39
update plugin description
egorikftp Jun 28, 2024
6250562
update drag and drop logic
egorikftp Jun 28, 2024
f9ab350
implement batch icon export
egorikftp Jul 2, 2024
6b765f0
optimize preview generation
egorikftp Jul 2, 2024
2755b4c
update preview generation logic
egorikftp Jul 4, 2024
1c76c22
handle enable/disable export
egorikftp Jul 4, 2024
8076bac
split valid and broken icons
egorikftp Jul 4, 2024
ba17a1a
generate icon with "ImageVector.Builder", simplify imports
egorikftp Jul 4, 2024
bb462e1
don't handle hover state in icon picker screen
egorikftp Jul 4, 2024
91479e4
optimize reload from disk logic
egorikftp Jul 4, 2024
906e013
use CodePreviewScreen for preview iconpack object
egorikftp Jul 4, 2024
6c63830
handle initialDirectory for DirectoryPicker
egorikftp Jul 4, 2024
9aaf18f
split processing logic into separate modules
egorikftp Jul 5, 2024
d64e0aa
clean up generated float values in path
egorikftp Jul 5, 2024
06d9176
update IntroScreen design
egorikftp Jul 5, 2024
3d8b147
update README.md
egorikftp Jul 5, 2024
f6ec02a
add sort icons by name
egorikftp Jul 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[{*.kt,*.kts}]
ij_kotlin_line_break_after_multiline_when_entry = false
ij_kotlin_name_count_to_use_star_import = 2147483647
ij_kotlin_name_count_to_use_star_import_for_members = 2147483647
178 changes: 175 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,191 @@
- built using [Compose Multiplatform](https://github.com/JetBrains/compose-multiplatform)
and [Tiamat](https://github.com/ComposeGears/Tiamat) navigation library
- support SVG/XML
- convenient code formatting for generated ImageVector icon
- skip default ImageVector path parameters to reduce visual noise
- convenient code formatting for generated icon
- remove redundant code
- remove unused imports
- skip default ImageVector parameters
- support drag and drop inside IDE

## Conversion modes:

### **Simple** - one-click solution to convert SVG/XML to ImageVector
Allows previewing the generated icon and facilitates copying the result directly to the clipboard for easy integration into your project.

<img src="assets/simple_mode_1.png" width="300" /> <img src="assets/simple_mode_2.png" width="300" />

Demo:


https://github.com/ComposeGears/Valkyrie/assets/16294951/1c5ca6ef-4240-4916-b523-cf9bb15a7422



### **IconPack** - create your organized icon pack and auto export icons into your directory

Allows to create organized icon pack with an extension property of you pack object and batch export into your specified directory.

<img src="assets/iconpack_mode_1.png" width="300" /> <img src="assets/iconpack_mode_2.png" width="305" />


## Comparison

Source SVG icon:
```svg
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
```

ImageVector output:

<table>
<tr>
<td> Valkyrie </td> <td> composables.com </td>
</tr>
<tr>
<td valign="top">

```kotlin
package io.github.composegears.valkyrie

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp

val Add: ImageVector
get() {
if (_Add != null) {
return _Add!!
}
_Add = ImageVector.Builder(
name = "Add",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f
).apply {
path(fill = SolidColor(Color(0xFFE8EAED))) {
moveTo(19f, 13f)
horizontalLineToRelative(-6f)
verticalLineToRelative(6f)
horizontalLineToRelative(-2f)
verticalLineToRelative(-6f)
horizontalLineTo(5f)
verticalLineToRelative(-2f)
horizontalLineToRelative(6f)
verticalLineTo(5f)
horizontalLineToRelative(2f)
verticalLineToRelative(6f)
horizontalLineToRelative(6f)
verticalLineToRelative(2f)
close()
}
}.build()

return _Add!!
}

private var _Add: ImageVector? = null

```

</td>
<td>

```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.foundation.Image
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp

private var _Add: ImageVector? = null

public val Add: ImageVector
get() {
if (_Add != null) {
return _Add!!
}
_Add = ImageVector.Builder(
name = "Add",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f
).apply {
path(
fill = null,
fillAlpha = 1.0f,
stroke = null,
strokeAlpha = 1.0f,
strokeLineWidth = 1.0f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Miter,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero
) {
moveTo(0f, 0f)
horizontalLineToRelative(24f)
verticalLineToRelative(24f)
horizontalLineTo(0f)
verticalLineTo(0f)
close()
}
path(
fill = SolidColor(Color(0xFFE8EAED)),
fillAlpha = 1.0f,
stroke = null,
strokeAlpha = 1.0f,
strokeLineWidth = 1.0f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Miter,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero
) {
moveTo(19f, 13f)
horizontalLineToRelative(-6f)
verticalLineToRelative(6f)
horizontalLineToRelative(-2f)
verticalLineToRelative(-6f)
horizontalLineTo(5f)
verticalLineToRelative(-2f)
horizontalLineToRelative(6f)
verticalLineTo(5f)
horizontalLineToRelative(2f)
verticalLineToRelative(6f)
horizontalLineToRelative(6f)
verticalLineToRelative(2f)
close()
}
}.build()
return _Add!!
}

```

</td>
</tr>
</table>

## Requirements

- Intellij IDEA 2024.1+
- Android Studio Koala+

## Installation

- Manually:
- Download from [Jetbrains Marketplace](https://plugins.jetbrains.com/plugin/24786-valkyrie) or find plugin inside IDE:

<kbd>Settings/Preferences</kbd> > <kbd>Plugins</kbd> > <kbd>Marketplace</kbd> > <kbd>Search for "Valkyrie"</kbd> >
<kbd>Install Plugin</kbd>

- Manually:
Download the [latest release](https://github.com/ComposeGears/Valkyrie/releases/latest)
or [build your self](#Building) and install it manually using
<kbd>Settings</kbd> -> <kbd>Plugins</kbd> -> <kbd>⚙️</kbd> -> <kbd>Install plugin from disk...</kbd>
Expand Down
3 changes: 3 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- add tests with nested icon packs
- add test for linear gradient icon
- add test for radial gradient icon
Binary file added assets/iconpack_mode_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/iconpack_mode_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/simple_mode_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/simple_mode_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ repositories {

dependencies {
implementation(libs.kotlinpoet)
implementation(libs.xpp3)

testImplementation(libs.kotlin.test)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@ import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.TypeSpec

private val Indent = " ".repeat(4)
fun FileSpec.Builder.setIndent() = indent(Indent)

fun FileSpec.removeDeadCode(): String = toString()
.replace("public ", "")

inline fun objectBuilder(
name: String,
builderAction: TypeSpec.Builder.() -> Unit = {}
) = TypeSpec.objectBuilder(name)
.apply(builderAction)
.build()

inline fun fileSpecBuilder(
packageName: String,
fileName: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package io.github.composegears.valkyrie
package io.github.composegears.valkyrie.generator.ext

import io.github.composegears.valkyrie.generator.ext.formatFloat
import io.github.composegears.valkyrie.generator.ext.toColorHex
import io.github.composegears.valkyrie.generator.ext.trimTrailingZero
import org.junit.Test
import kotlin.test.assertEquals

Expand Down
15 changes: 15 additions & 0 deletions components/generator/iconpack/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
plugins {
alias(libs.plugins.kotlin.jvm)
}

repositories {
mavenCentral()
}

dependencies {
implementation(projects.components.generator.common)

implementation(libs.kotlinpoet)

testImplementation(libs.kotlin.test)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.github.composegears.valkyrie.generator.iconpack

import io.github.composegears.valkyrie.generator.ext.fileSpecBuilder
import io.github.composegears.valkyrie.generator.ext.objectBuilder
import io.github.composegears.valkyrie.generator.ext.removeDeadCode
import io.github.composegears.valkyrie.generator.ext.setIndent

internal class IconPackFileSpec(private val config: IconPackGeneratorConfig) {

fun createSpec(): IconPackSpecOutput {
val iconPackSpec = objectBuilder(name = config.iconPackName) {
config.subPacks.forEach { icon ->
addType(objectBuilder(name = icon))
}
}
val fileSpec = fileSpecBuilder(
packageName = config.packageName,
fileName = config.iconPackName
) {
addType(iconPackSpec)
setIndent()
}
return IconPackSpecOutput(
content = fileSpec.removeDeadCode(),
name = fileSpec.name
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.github.composegears.valkyrie.generator.iconpack

data class IconPackGeneratorConfig(
val packageName: String,
val iconPackName: String,
val subPacks: List<String>
)

data class IconPackSpecOutput(
val content: String,
val name: String
)

object IconPackGenerator {

fun create(config: IconPackGeneratorConfig) = IconPackFileSpec(config).createSpec()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.github.composegears.valkyrie.generator.iconpack

import org.junit.Test
import kotlin.test.assertEquals

class IconPackGeneratorTest {

@Test
fun `generate icon pack`() {
val result = IconPackGenerator.create(
config = IconPackGeneratorConfig(
packageName = "io.github.composegears.valkyrie.icons",
iconPackName = "ValkyrieIcons",
subPacks = emptyList()
)
)

val expectedContent = """
package io.github.composegears.valkyrie.icons

object ValkyrieIcons

""".trimIndent()

assertEquals(result.content, expectedContent)
assertEquals(result.name, "ValkyrieIcons")
}

@Test
fun `generate nested packs`() {
val result = IconPackGenerator.create(
config = IconPackGeneratorConfig(
packageName = "io.github.composegears.valkyrie.icons",
iconPackName = "ValkyrieIcons",
subPacks = listOf("Filled", "Colored")
)
)

val expectedContent = """
package io.github.composegears.valkyrie.icons

object ValkyrieIcons {
object Filled

object Colored
}

""".trimIndent()

assertEquals(result.content, expectedContent)
assertEquals(result.name, "ValkyrieIcons")
}
}
18 changes: 18 additions & 0 deletions components/generator/imagevector/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
plugins {
alias(libs.plugins.kotlin.jvm)
}

repositories {
google()
mavenCentral()
}

dependencies {
implementation(projects.components.generator.common)
implementation(projects.components.google)

implementation(libs.kotlinpoet)

testImplementation(projects.components.parser)
testImplementation(libs.kotlin.test)
}
Loading