Skip to content

Commit e7c276d

Browse files
Add more mixin icons for different types of annotations and accessor mixins
Co-authored-by: Voided Aries <[email protected]>
1 parent 62a893e commit e7c276d

33 files changed

+483
-74
lines changed

src/main/kotlin/asset/MixinAssets.kt

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,30 @@ package com.demonwav.mcdev.asset
2222

2323
@Suppress("unused")
2424
object MixinAssets : Assets() {
25-
val MIXIN_ELEMENT_ICON = loadIcon("/assets/icons/mixin/mixin_element.svg")
26-
val MIXIN_ELEMENT_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_element_dark.svg")
25+
val MIXIN_ACCESSOR_ICON = loadIcon("/assets/icons/mixin/mixin_accessor.svg")
26+
val MIXIN_ACCESSOR_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_accessor_dark.svg")
27+
28+
val MIXIN_ACCESSOR_MIXIN_ICON = loadIcon("/assets/icons/mixin/mixin_accessor_mixin.svg")
29+
val MIXIN_ACCESSOR_MIXIN_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_accessor_mixin_dark.svg")
2730

2831
val MIXIN_CLASS_ICON = loadIcon("/assets/icons/mixin/mixin_class_gutter.svg")
2932
val MIXIN_CLASS_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_class_gutter_dark.svg")
3033

31-
val MIXIN_CLASS_TARGET_ICON = loadIcon("/assets/icons/mixin/mixin_class_target_gutter.svg")
32-
val MIXIN_CLASS_TARGET_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_class_target_gutter_dark.svg")
34+
val MIXIN_ELEMENT_ICON = loadIcon("/assets/icons/mixin/mixin_element.svg")
35+
val MIXIN_ELEMENT_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_element_dark.svg")
36+
37+
val MIXIN_INJECTOR_ICON = loadIcon("/assets/icons/mixin/mixin_injector.svg")
38+
val MIXIN_INJECTOR_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_injector_dark.svg")
39+
40+
val MIXIN_SHADOW_ICON = loadIcon("/assets/icons/mixin/mixin_shadow.svg")
41+
val MIXIN_SHADOW_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_shadow_dark_alt.svg")
42+
43+
val MIXIN_TARGET_ACCESSOR_MIXIN_ICON = loadIcon("/assets/icons/mixin/mixin_target_accessor_mixin.svg")
44+
val MIXIN_TARGET_ACCESSOR_MIXIN_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_target_accessor_mixin_dark.svg")
45+
46+
val MIXIN_TARGET_CLASS_ICON = loadIcon("/assets/icons/mixin/mixin_target_class_gutter.svg")
47+
val MIXIN_TARGET_CLASS_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_target_class_gutter_dark.svg")
3348

3449
val MIXIN_MARK = loadIcon("/assets/icons/mixin/mixin_mark.svg")
50+
val ACCESSOR_MARK = loadIcon("/assets/icons/mixin/accessor_mark.svg")
3551
}

src/main/kotlin/platform/mixin/framework/MixinIconProvider.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,26 @@ package com.demonwav.mcdev.platform.mixin.framework
2222

2323
import com.demonwav.mcdev.MinecraftSettings
2424
import com.demonwav.mcdev.asset.MixinAssets
25+
import com.demonwav.mcdev.platform.mixin.util.isAccessorMixin
2526
import com.demonwav.mcdev.platform.mixin.util.isMixin
2627
import com.intellij.ide.IconLayerProvider
2728
import com.intellij.openapi.util.Iconable
2829
import com.intellij.psi.PsiClass
2930
import javax.swing.Icon
3031

3132
class MixinIconProvider : IconLayerProvider {
32-
override fun getLayerIcon(element: Iconable, isLocked: Boolean): Icon? =
33-
MixinAssets.MIXIN_MARK.takeIf {
34-
MinecraftSettings.instance.mixinClassIcon && element is PsiClass && element.isMixin
33+
override fun getLayerIcon(element: Iconable, isLocked: Boolean): Icon? {
34+
if (!MinecraftSettings.instance.mixinClassIcon || element !is PsiClass || !element.isMixin) {
35+
return null
3536
}
3637

38+
return if (element.isAccessorMixin) {
39+
MixinAssets.ACCESSOR_MARK
40+
} else {
41+
MixinAssets.MIXIN_MARK
42+
}
43+
}
44+
3745
override fun getLayerDescription(): String =
3846
"Mixin class"
3947
}

src/main/kotlin/platform/mixin/handlers/AccessorHandler.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
package com.demonwav.mcdev.platform.mixin.handlers
2222

23+
import com.demonwav.mcdev.asset.MixinAssets
2324
import com.demonwav.mcdev.platform.mixin.util.FieldTargetMember
2425
import com.demonwav.mcdev.platform.mixin.util.MixinConstants.Annotations.ACCESSOR
2526
import com.demonwav.mcdev.platform.mixin.util.MixinTargetMember
@@ -108,6 +109,8 @@ class AccessorHandler : MixinMemberAnnotationHandler {
108109

109110
override val isEntryPoint = false
110111

112+
override val icon = MixinAssets.MIXIN_ACCESSOR_ICON
113+
111114
data class AccessorInfo(val name: String, val type: AccessorType)
112115

113116
enum class AccessorType(val allowGetters: Boolean, val allowSetters: Boolean) {

src/main/kotlin/platform/mixin/handlers/InjectorAnnotationHandler.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
package com.demonwav.mcdev.platform.mixin.handlers
2222

23+
import com.demonwav.mcdev.asset.MixinAssets
2324
import com.demonwav.mcdev.platform.mixin.handlers.injectionPoint.AtResolver
2425
import com.demonwav.mcdev.platform.mixin.handlers.injectionPoint.CollectVisitor
2526
import com.demonwav.mcdev.platform.mixin.handlers.injectionPoint.InsnResolutionInfo
@@ -174,6 +175,8 @@ abstract class InjectorAnnotationHandler : MixinAnnotationHandler {
174175

175176
override val isEntryPoint = true
176177

178+
override val icon = MixinAssets.MIXIN_INJECTOR_ICON
179+
177180
abstract val mixinExtrasExpressionContextType: ExpressionContext.Type
178181

179182
data class InsnResult(val method: ClassAndMethodNode, val result: CollectVisitor.Result<*>)

src/main/kotlin/platform/mixin/handlers/InvokerHandler.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
package com.demonwav.mcdev.platform.mixin.handlers
2222

23+
import com.demonwav.mcdev.asset.MixinAssets
2324
import com.demonwav.mcdev.platform.mixin.util.MethodTargetMember
2425
import com.demonwav.mcdev.platform.mixin.util.MixinConstants.Annotations.INVOKER
2526
import com.demonwav.mcdev.platform.mixin.util.MixinTargetMember
@@ -108,4 +109,6 @@ class InvokerHandler : MixinMemberAnnotationHandler {
108109
}
109110

110111
override val isEntryPoint = false
112+
113+
override val icon = MixinAssets.MIXIN_ACCESSOR_ICON
111114
}

src/main/kotlin/platform/mixin/handlers/MixinAnnotationHandler.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
package com.demonwav.mcdev.platform.mixin.handlers
2222

23+
import com.demonwav.mcdev.asset.MixinAssets
2324
import com.demonwav.mcdev.platform.mixin.handlers.injectionPoint.InsnResolutionInfo
2425
import com.demonwav.mcdev.platform.mixin.util.MixinConstants
2526
import com.demonwav.mcdev.platform.mixin.util.MixinTargetMember
@@ -43,6 +44,7 @@ import com.intellij.psi.util.PsiModificationTracker
4344
import com.intellij.serviceContainer.BaseKeyedLazyInstance
4445
import com.intellij.util.KeyedLazyInstance
4546
import com.intellij.util.xmlb.annotations.Attribute
47+
import javax.swing.Icon
4648
import org.objectweb.asm.tree.ClassNode
4749

4850
interface MixinAnnotationHandler {
@@ -83,6 +85,8 @@ interface MixinAnnotationHandler {
8385
*/
8486
val isEntryPoint: Boolean
8587

88+
val icon: Icon get() = MixinAssets.MIXIN_ELEMENT_ICON
89+
8690
companion object {
8791
private val EP_NAME = ExtensionPointName<KeyedLazyInstance<MixinAnnotationHandler>>(
8892
"com.demonwav.minecraft-dev.mixinAnnotationHandler",

src/main/kotlin/platform/mixin/handlers/ShadowHandler.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
package com.demonwav.mcdev.platform.mixin.handlers
2222

23+
import com.demonwav.mcdev.asset.MixinAssets
2324
import com.demonwav.mcdev.platform.mixin.handlers.injectionPoint.InsnResolutionInfo
2425
import com.demonwav.mcdev.platform.mixin.util.FieldTargetMember
2526
import com.demonwav.mcdev.platform.mixin.util.MethodTargetMember
@@ -102,6 +103,8 @@ class ShadowHandler : MixinMemberAnnotationHandler {
102103

103104
override val isEntryPoint = false
104105

106+
override val icon = MixinAssets.MIXIN_SHADOW_ICON
107+
105108
companion object {
106109
fun getInstance(): ShadowHandler? {
107110
return MixinAnnotationHandler.forMixinAnnotation(SHADOW) as? ShadowHandler

src/main/kotlin/platform/mixin/insight/MixinElementLineMarkerProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class MixinElementLineMarkerProvider : LineMarkerProviderDescriptor() {
7676
return LineMarkerInfo(
7777
identifier,
7878
identifier.textRange,
79-
icon,
79+
handler.icon,
8080
{ "Go to the $simpleName target" },
8181
MixinGutterIconNavigationHandler(identifier.createSmartPointer(), annotation.createSmartPointer(), handler),
8282
GutterIconRenderer.Alignment.LEFT,

src/main/kotlin/platform/mixin/insight/MixinLineMarkerProvider.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package com.demonwav.mcdev.platform.mixin.insight
2222

2323
import com.demonwav.mcdev.asset.MixinAssets
2424
import com.demonwav.mcdev.platform.mixin.util.findSourceClass
25+
import com.demonwav.mcdev.platform.mixin.util.isAccessorMixin
2526
import com.demonwav.mcdev.platform.mixin.util.isMixin
2627
import com.demonwav.mcdev.platform.mixin.util.mixinTargets
2728
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler
@@ -50,6 +51,12 @@ class MixinLineMarkerProvider : LineMarkerProviderDescriptor(), GutterIconNaviga
5051
return null
5152
}
5253

54+
val icon = if (element.isAccessorMixin) {
55+
MixinAssets.MIXIN_ACCESSOR_MIXIN_ICON
56+
} else {
57+
icon
58+
}
59+
5360
return LineMarkerInfo(
5461
identifier,
5562
identifier.textRange,
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Minecraft Development for IntelliJ
3+
*
4+
* https://mcdev.io/
5+
*
6+
* Copyright (C) 2025 minecraft-dev
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Lesser General Public License as published
10+
* by the Free Software Foundation, version 3.0 only.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
package com.demonwav.mcdev.platform.mixin.insight.target
22+
23+
import com.demonwav.mcdev.asset.MixinAssets
24+
import com.demonwav.mcdev.platform.mixin.action.FindMixinsAction
25+
import com.demonwav.mcdev.platform.mixin.util.isAccessorMixin
26+
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler
27+
import com.intellij.codeInsight.daemon.LineMarkerInfo
28+
import com.intellij.codeInsight.daemon.LineMarkerProviderDescriptor
29+
import com.intellij.openapi.editor.markup.GutterIconRenderer
30+
import com.intellij.psi.PsiClass
31+
import com.intellij.psi.PsiElement
32+
import com.intellij.psi.PsiIdentifier
33+
import com.intellij.ui.awt.RelativePoint
34+
import java.awt.event.MouseEvent
35+
36+
class MixinAccessorTargetLineMarkerProvider : LineMarkerProviderDescriptor(), GutterIconNavigationHandler<PsiIdentifier> {
37+
override fun getName() = "Accessor mixin target line marker"
38+
override fun getIcon() = MixinAssets.MIXIN_TARGET_ACCESSOR_MIXIN_ICON
39+
40+
override fun getLineMarkerInfo(element: PsiElement) = null
41+
42+
override fun collectSlowLineMarkers(
43+
elements: List<PsiElement>,
44+
result: MutableCollection<in LineMarkerInfo<*>>
45+
) {
46+
for (element in elements) {
47+
if (element !is PsiClass) {
48+
continue
49+
}
50+
51+
val identifier = element.nameIdentifier ?: continue
52+
53+
val mixins = FindMixinsAction.findMixins(element, element.project) ?: continue
54+
if (mixins.none { it.isAccessorMixin }) {
55+
continue
56+
}
57+
58+
result += LineMarkerInfo(
59+
identifier,
60+
identifier.textRange,
61+
icon,
62+
{ "Go to accessor mixins" },
63+
this,
64+
GutterIconRenderer.Alignment.LEFT,
65+
{ "accessor mixin target class indicator" },
66+
)
67+
}
68+
}
69+
70+
override fun navigate(e: MouseEvent, elt: PsiIdentifier) {
71+
val targetClass = elt.parent as? PsiClass ?: return
72+
FindMixinsAction.openFindMixinsUI(
73+
targetClass.project,
74+
targetClass,
75+
{ show(RelativePoint(e)) }
76+
) {
77+
it.isAccessorMixin
78+
}
79+
}
80+
}

0 commit comments

Comments
 (0)