Skip to content

Commit 3a99785

Browse files
t-regbsegorikftp
authored andcommitted
feat: add image vector icon support and refactor completion contributor to share icon creation utility
1 parent 0c5a2dd commit 3a99785

File tree

5 files changed

+92
-23
lines changed

5 files changed

+92
-23
lines changed

tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/completion/ImageVectorCompletionContributor.kt

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,8 @@ import com.intellij.codeInsight.lookup.LookupElementDecorator
88
import com.intellij.codeInsight.lookup.LookupElementPresentation
99
import com.intellij.psi.util.CachedValueProvider
1010
import com.intellij.psi.util.CachedValuesManager
11-
import io.github.composegears.valkyrie.psi.imagevector.ImageVectorPsiParser
1211
import io.github.composegears.valkyrie.sdk.core.extensions.safeAs
13-
import io.github.composegears.valkyrie.sdk.ir.util.aspectRatio
14-
import io.github.composegears.valkyrie.sdk.ir.util.dominantShadeColor
15-
import io.github.composegears.valkyrie.sdk.ir.xml.toVectorXmlString
12+
import io.github.composegears.valkyrie.util.createImageVectorIcon
1613
import javax.swing.Icon
1714
import org.jetbrains.kotlin.psi.KtFile
1815
import org.jetbrains.kotlin.psi.KtProperty
@@ -54,22 +51,11 @@ class ImageVectorCompletionContributor : CompletionContributor() {
5451
val cachedValuesManager = CachedValuesManager.getManager(ktFile.project)
5552

5653
return cachedValuesManager.getCachedValue(ktFile) {
57-
val icon = createIconFromKtFile(ktFile)
54+
val icon = ktFile.createImageVectorIcon()
5855
CachedValueProvider.Result.create(icon, ktFile)
5956
}
6057
}
6158

62-
private fun createIconFromKtFile(ktFile: KtFile): Icon? {
63-
val irImageVector = ImageVectorPsiParser.parseToIrImageVector(ktFile)
64-
val vectorXml = irImageVector?.toVectorXmlString() ?: return null
65-
66-
return ImageVectorIcon(
67-
vectorXml = vectorXml,
68-
aspectRatio = irImageVector.aspectRatio,
69-
dominantShade = irImageVector.dominantShadeColor,
70-
)
71-
}
72-
7359
private class ComposeColorLookupElementDecorator(
7460
delegate: LookupElement,
7561
private val icon: Icon,

tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/gutter/ImageVectorGutterProvider.kt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import io.github.composegears.valkyrie.sdk.ir.core.IrImageVector
1616
import io.github.composegears.valkyrie.sdk.ir.util.aspectRatio
1717
import io.github.composegears.valkyrie.sdk.ir.util.dominantShadeColor
1818
import io.github.composegears.valkyrie.sdk.ir.xml.toVectorXmlString
19+
import io.github.composegears.valkyrie.util.isImageVector
1920
import javax.swing.Icon
2021
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
2122
import org.jetbrains.kotlin.psi.KtProperty
@@ -135,12 +136,5 @@ class ImageVectorGutterProvider : LineMarkerProvider {
135136

136137
private companion object {
137138
private const val COMPILED_CODE_MARKER = "/* compiled code */"
138-
139-
private val IMAGE_VECTOR_TYPES = setOf(
140-
"ImageVector",
141-
"androidx.compose.ui.graphics.vector.ImageVector",
142-
)
143-
144-
private fun KtProperty.isImageVector(): Boolean = typeReference?.text in IMAGE_VECTOR_TYPES
145139
}
146140
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.github.composegears.valkyrie.icon
2+
3+
import com.intellij.ide.IconProvider
4+
import com.intellij.openapi.project.DumbAware
5+
import com.intellij.psi.PsiElement
6+
import com.intellij.psi.PsiFile
7+
import com.intellij.psi.util.CachedValueProvider
8+
import com.intellij.psi.util.CachedValuesManager
9+
import io.github.composegears.valkyrie.util.createImageVectorIcon
10+
import io.github.composegears.valkyrie.util.hasImageVectorProperties
11+
import javax.swing.Icon
12+
import org.jetbrains.kotlin.psi.KtFile
13+
14+
class ImageVectorIconProvider :
15+
IconProvider(),
16+
DumbAware {
17+
18+
override fun getIcon(element: PsiElement, flags: Int): Icon? {
19+
val ktFile = when (element) {
20+
is KtFile -> element
21+
is PsiFile -> null
22+
else -> element.containingFile as? KtFile
23+
} ?: return null
24+
25+
if (!ktFile.hasImageVectorProperties()) {
26+
return null
27+
}
28+
29+
return CachedValuesManager.getCachedValue(ktFile) {
30+
val icon = ktFile.createImageVectorIcon()
31+
CachedValueProvider.Result.create(icon, ktFile)
32+
}
33+
}
34+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package io.github.composegears.valkyrie.util
2+
3+
import io.github.composegears.valkyrie.completion.ImageVectorIcon
4+
import io.github.composegears.valkyrie.psi.imagevector.ImageVectorPsiParser
5+
import io.github.composegears.valkyrie.sdk.ir.util.aspectRatio
6+
import io.github.composegears.valkyrie.sdk.ir.util.dominantShadeColor
7+
import io.github.composegears.valkyrie.sdk.ir.xml.toVectorXmlString
8+
import javax.swing.Icon
9+
import org.jetbrains.kotlin.psi.KtFile
10+
import org.jetbrains.kotlin.psi.KtProperty
11+
12+
val IMAGE_VECTOR_TYPES = setOf(
13+
"ImageVector",
14+
"androidx.compose.ui.graphics.vector.ImageVector",
15+
)
16+
17+
/**
18+
* Checks if this property is an ImageVector based on its type reference.
19+
*/
20+
fun KtProperty.isImageVector(): Boolean {
21+
val typeText = typeReference?.text ?: return false
22+
return typeText in IMAGE_VECTOR_TYPES
23+
}
24+
25+
/**
26+
* Checks if this Kotlin file contains ImageVector properties.
27+
*
28+
* A file is considered to contain ImageVector if it has at least one top-level
29+
* property with an ImageVector type annotation.
30+
*/
31+
fun KtFile.hasImageVectorProperties(): Boolean {
32+
val properties = declarations.filterIsInstance<KtProperty>()
33+
if (properties.isEmpty()) return false
34+
35+
return properties.any { it.isImageVector() }
36+
}
37+
38+
/**
39+
* Creates an icon representation from this Kotlin file containing an ImageVector.
40+
*
41+
* This function parses the ImageVector definition and renders it as a Swing Icon
42+
* suitable for display in the IDE UI (project view, gutter, completion, etc.).
43+
*/
44+
fun KtFile.createImageVectorIcon(): Icon? {
45+
val irImageVector = ImageVectorPsiParser.parseToIrImageVector(this) ?: return null
46+
val vectorXml = irImageVector.toVectorXmlString()
47+
48+
return ImageVectorIcon(
49+
vectorXml = vectorXml,
50+
aspectRatio = irImageVector.aspectRatio,
51+
dominantShade = irImageVector.dominantShadeColor,
52+
)
53+
}

tools/idea-plugin/src/main/resources/META-INF/plugin.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ Allows to create organized icon pack with an extension property of you pack obje
7575
language="kotlin"
7676
order="first, before KotlinCompletionContributor, before AndroidComposeCompletionContributor"
7777
implementationClass="io.github.composegears.valkyrie.completion.ImageVectorCompletionContributor"/>
78+
79+
<iconProvider implementation="io.github.composegears.valkyrie.icon.ImageVectorIconProvider" order="first"/>
7880
</extensions>
7981

8082
<extensions defaultExtensionNs="org.jetbrains.kotlin">

0 commit comments

Comments
 (0)