Skip to content

Commit cbf7b89

Browse files
committed
Dynamically set contrast the gutter icon's background if its dominant color matches the IDE's theme color
1 parent 428d9d2 commit cbf7b89

File tree

12 files changed

+56
-36
lines changed

12 files changed

+56
-36
lines changed

components/ir/api/ir.api

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,6 @@ public final class io/github/composegears/valkyrie/ir/IrImageVector {
116116
public fun toString ()Ljava/lang/String;
117117
}
118118

119-
public final class io/github/composegears/valkyrie/ir/IrImageVectorKt {
120-
public static final fun getAspectRatio (Lio/github/composegears/valkyrie/ir/IrImageVector;)F
121-
}
122-
123119
public final class io/github/composegears/valkyrie/ir/IrPathFillType : java/lang/Enum {
124120
public static final field EvenOdd Lio/github/composegears/valkyrie/ir/IrPathFillType;
125121
public static final field NonZero Lio/github/composegears/valkyrie/ir/IrPathFillType;
@@ -513,11 +509,6 @@ public final class io/github/composegears/valkyrie/ir/IrVectorNode$IrPath : io/g
513509
public fun toString ()Ljava/lang/String;
514510
}
515511

516-
public final class io/github/composegears/valkyrie/ir/util/ColorClassification {
517-
public static final field INSTANCE Lio/github/composegears/valkyrie/ir/util/ColorClassification;
518-
public final fun from (Ljava/util/List;)Lio/github/composegears/valkyrie/ir/util/DominantShade;
519-
}
520-
521512
public final class io/github/composegears/valkyrie/ir/util/DominantShade : java/lang/Enum {
522513
public static final field Black Lio/github/composegears/valkyrie/ir/util/DominantShade;
523514
public static final field Mixed Lio/github/composegears/valkyrie/ir/util/DominantShade;
@@ -527,8 +518,9 @@ public final class io/github/composegears/valkyrie/ir/util/DominantShade : java/
527518
public static fun values ()[Lio/github/composegears/valkyrie/ir/util/DominantShade;
528519
}
529520

530-
public final class io/github/composegears/valkyrie/ir/util/IrImageVectorColorKt {
531-
public static final fun iconColors (Lio/github/composegears/valkyrie/ir/IrImageVector;)Ljava/util/List;
521+
public final class io/github/composegears/valkyrie/ir/util/IrImageVectorExtensionsKt {
522+
public static final fun getAspectRatio (Lio/github/composegears/valkyrie/ir/IrImageVector;)F
523+
public static final fun getDominantShadeColor (Lio/github/composegears/valkyrie/ir/IrImageVector;)Lio/github/composegears/valkyrie/ir/util/DominantShade;
532524
}
533525

534526
public final class io/github/composegears/valkyrie/ir/util/PathNodeKt {

components/ir/api/ir.klib.api

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -654,12 +654,9 @@ final value class io.github.composegears.valkyrie.ir/IrColor { // io.github.comp
654654
}
655655
}
656656

657-
final object io.github.composegears.valkyrie.ir.util/ColorClassification { // io.github.composegears.valkyrie.ir.util/ColorClassification|null[0]
658-
final fun from(kotlin.collections/List<io.github.composegears.valkyrie.ir/IrColor>): io.github.composegears.valkyrie.ir.util/DominantShade // io.github.composegears.valkyrie.ir.util/ColorClassification.from|from(kotlin.collections.List<io.github.composegears.valkyrie.ir.IrColor>){}[0]
659-
}
660-
661-
final val io.github.composegears.valkyrie.ir/aspectRatio // io.github.composegears.valkyrie.ir/aspectRatio|@io.github.composegears.valkyrie.ir.IrImageVector{}aspectRatio[0]
662-
final fun (io.github.composegears.valkyrie.ir/IrImageVector).<get-aspectRatio>(): kotlin/Float // io.github.composegears.valkyrie.ir/aspectRatio.<get-aspectRatio>|<get-aspectRatio>@io.github.composegears.valkyrie.ir.IrImageVector(){}[0]
657+
final val io.github.composegears.valkyrie.ir.util/aspectRatio // io.github.composegears.valkyrie.ir.util/aspectRatio|@io.github.composegears.valkyrie.ir.IrImageVector{}aspectRatio[0]
658+
final fun (io.github.composegears.valkyrie.ir/IrImageVector).<get-aspectRatio>(): kotlin/Float // io.github.composegears.valkyrie.ir.util/aspectRatio.<get-aspectRatio>|<get-aspectRatio>@io.github.composegears.valkyrie.ir.IrImageVector(){}[0]
659+
final val io.github.composegears.valkyrie.ir.util/dominantShadeColor // io.github.composegears.valkyrie.ir.util/dominantShadeColor|@io.github.composegears.valkyrie.ir.IrImageVector{}dominantShadeColor[0]
660+
final fun (io.github.composegears.valkyrie.ir/IrImageVector).<get-dominantShadeColor>(): io.github.composegears.valkyrie.ir.util/DominantShade // io.github.composegears.valkyrie.ir.util/dominantShadeColor.<get-dominantShadeColor>|<get-dominantShadeColor>@io.github.composegears.valkyrie.ir.IrImageVector(){}[0]
663661

664-
final fun (io.github.composegears.valkyrie.ir/IrImageVector).io.github.composegears.valkyrie.ir.util/iconColors(): kotlin.collections/List<io.github.composegears.valkyrie.ir/IrColor> // io.github.composegears.valkyrie.ir.util/iconColors|[email protected](){}[0]
665662
final fun (kotlin/Char).io.github.composegears.valkyrie.ir.util/toPathNodes(kotlin/FloatArray): kotlin.collections/List<io.github.composegears.valkyrie.ir/IrPathNode> // io.github.composegears.valkyrie.ir.util/toPathNodes|[email protected](kotlin.FloatArray){}[0]

components/ir/src/commonMain/kotlin/io/github/composegears/valkyrie/ir/IrImageVector.kt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,3 @@ data class IrImageVector(
99
val viewportHeight: Float,
1010
val nodes: List<IrVectorNode>,
1111
)
12-
13-
val IrImageVector.aspectRatio: Float
14-
get() = if (viewportHeight != 0f && viewportWidth != 0f) {
15-
viewportWidth / viewportHeight
16-
} else {
17-
1f
18-
}

components/ir/src/commonMain/kotlin/io/github/composegears/valkyrie/ir/util/ColorClassification.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ enum class DominantShade {
1111
Mixed,
1212
}
1313

14-
object ColorClassification {
14+
internal object ColorClassification {
1515

1616
private const val BLACK_THRESHOLD = 0.2f
1717
private const val WHITE_THRESHOLD = 0.8f

components/ir/src/commonMain/kotlin/io/github/composegears/valkyrie/ir/util/IrImageVectorColor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import io.github.composegears.valkyrie.ir.IrImageVector
66
import io.github.composegears.valkyrie.ir.IrStroke
77
import io.github.composegears.valkyrie.ir.IrVectorNode
88

9-
fun IrImageVector.iconColors(): List<IrColor> {
9+
internal fun IrImageVector.iconColors(): List<IrColor> {
1010
val colors = mutableSetOf<IrColor>()
1111

1212
nodes.onEach { node ->
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.github.composegears.valkyrie.ir.util
2+
3+
import io.github.composegears.valkyrie.ir.IrImageVector
4+
5+
val IrImageVector.aspectRatio: Float
6+
get() = if (viewportHeight != 0f && viewportWidth != 0f) {
7+
viewportWidth / viewportHeight
8+
} else {
9+
1f
10+
}
11+
12+
val IrImageVector.dominantShadeColor: DominantShade
13+
get() = ColorClassification.from(iconColors())

tools/idea-plugin/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Added
66

77
- Setup of changelog plugin
8+
- Dynamically set the gutter icon's background to maintain contrast when its dominant color matches the IDE theme color
89

910
## [0.17.2](https://github.com/ComposeGears/Valkyrie/releases/tag/0.17.2) - 2025-10-11
1011

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +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.ir.aspectRatio
11+
import io.github.composegears.valkyrie.ir.util.aspectRatio
12+
import io.github.composegears.valkyrie.ir.util.dominantShadeColor
1213
import io.github.composegears.valkyrie.ir.xml.toVectorXmlString
1314
import io.github.composegears.valkyrie.psi.imagevector.ImageVectorPsiParser
1415
import io.github.composegears.valkyrie.sdk.core.extensions.safeAs
@@ -65,6 +66,7 @@ class ImageVectorCompletionContributor : CompletionContributor() {
6566
return ImageVectorIcon(
6667
vectorXml = vectorXml,
6768
aspectRatio = irImageVector.aspectRatio,
69+
dominantShade = irImageVector.dominantShadeColor,
6870
)
6971
}
7072

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package io.github.composegears.valkyrie.completion
22

33
import com.android.ide.common.vectordrawable.VdPreview
44
import com.intellij.openapi.diagnostic.Logger
5+
import com.intellij.ui.JBColor
6+
import io.github.composegears.valkyrie.ir.util.DominantShade
7+
import java.awt.Color
58
import java.awt.Component
69
import java.awt.Graphics
710
import java.awt.Graphics2D
@@ -12,13 +15,15 @@ class ImageVectorIcon(
1215
private val vectorXml: String,
1316
private val size: Int = 16,
1417
private val aspectRatio: Float,
18+
private val dominantShade: DominantShade,
1519
) : Icon {
1620

1721
@Volatile
1822
private var cachedImage: Image? = null
1923

2024
override fun paintIcon(c: Component?, g: Graphics?, x: Int, y: Int) {
2125
if (g !is Graphics2D) return
26+
drawBackground(g = g, x = x, y = y)
2227

2328
if (cachedImage == null) {
2429
cachedImage = renderImage()
@@ -38,6 +43,20 @@ class ImageVectorIcon(
3843
g.drawImage(img, offsetX, offsetY, width, height, null)
3944
}
4045

46+
private fun drawBackground(g: Graphics2D, x: Int, y: Int) {
47+
when (dominantShade) {
48+
DominantShade.Black -> {
49+
g.color = blackIconBackgroundColor
50+
g.fillRoundRect(x, y, size, size, 2, 2)
51+
}
52+
DominantShade.White -> {
53+
g.color = whiteIconBackgroundColor
54+
g.fillRoundRect(x, y, size, size, 2, 2)
55+
}
56+
DominantShade.Mixed -> {}
57+
}
58+
}
59+
4160
private fun renderImage(): Image? {
4261
val maxDimension = ICON_SCALE_FACTOR * size
4362
val errorLog = StringBuilder()
@@ -61,5 +80,8 @@ class ImageVectorIcon(
6180

6281
companion object {
6382
private const val ICON_SCALE_FACTOR = 4
83+
84+
private val blackIconBackgroundColor = JBColor(Color(0, 0, 0, 0), Color.WHITE)
85+
private val whiteIconBackgroundColor = JBColor(Color.DARK_GRAY, Color(0, 0, 0, 0))
6486
}
6587
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import com.intellij.psi.util.CachedValueProvider
1111
import com.intellij.psi.util.CachedValuesManager
1212
import io.github.composegears.valkyrie.completion.ImageVectorIcon
1313
import io.github.composegears.valkyrie.ir.IrImageVector
14-
import io.github.composegears.valkyrie.ir.aspectRatio
14+
import io.github.composegears.valkyrie.ir.util.aspectRatio
15+
import io.github.composegears.valkyrie.ir.util.dominantShadeColor
1516
import io.github.composegears.valkyrie.ir.xml.toVectorXmlString
1617
import io.github.composegears.valkyrie.psi.imagevector.ImageVectorPsiParser
1718
import io.github.composegears.valkyrie.sdk.core.extensions.safeAs
@@ -87,6 +88,7 @@ class ImageVectorGutterProvider : LineMarkerProvider {
8788
return ImageVectorIcon(
8889
vectorXml = vectorXml,
8990
aspectRatio = irImageVector.aspectRatio,
91+
dominantShade = irImageVector.dominantShadeColor,
9092
)
9193
}
9294

0 commit comments

Comments
 (0)