User: joseph burton Date: 18 Feb 25 15:16 Revision: 1e66be05e21acb00dcd0f1db224d62cd235dab5a Summary: Change mixin gutter icons to use svg (#2441) Co-authored-by: Voided Aries TeamCity URL: https://ci.mcdev.io/viewModification.html?tab=vcsModificationFiles&modId=9820&personal=false The following binary files were skipped: src/main/resources/assets/icons/mixin/mixin_class_gutter.png src/main/resources/assets/icons/mixin/mixin_class_gutter_dark.png src/main/resources/assets/icons/mixin/shadow.png src/main/resources/assets/icons/mixin/shadow_dark.png Index: src/main/kotlin/asset/MixinAssets.kt =================================================================== --- src/main/kotlin/asset/MixinAssets.kt (revision 043bd58ccc4bba1a25fbed1134b42a7277ce582a) +++ src/main/kotlin/asset/MixinAssets.kt (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) @@ -22,11 +22,11 @@ @Suppress("unused") object MixinAssets : Assets() { - val SHADOW = loadIcon("/assets/icons/mixin/shadow.png") - val SHADOW_DARK = loadIcon("/assets/icons/mixin/shadow_dark.png") + val MIXIN_ELEMENT_ICON = loadIcon("/assets/icons/mixin/mixin_element.svg") + val MIXIN_ELEMENT_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_element_dark.svg") - val MIXIN_CLASS_ICON = loadIcon("/assets/icons/mixin/mixin_class_gutter.png") - val MIXIN_CLASS_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_class_gutter_dark.png") + val MIXIN_CLASS_ICON = loadIcon("/assets/icons/mixin/mixin_class_gutter.svg") + val MIXIN_CLASS_ICON_DARK = loadIcon("/assets/icons/mixin/mixin_class_gutter_dark.svg") val MIXIN_MARK = loadIcon("/assets/icons/mixin/mixin_mark.svg") } Index: src/main/kotlin/platform/mixin/insight/MixinElementLineMarkerProvider.kt =================================================================== --- src/main/kotlin/platform/mixin/insight/MixinElementLineMarkerProvider.kt (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) +++ src/main/kotlin/platform/mixin/insight/MixinElementLineMarkerProvider.kt (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) @@ -0,0 +1,124 @@ +/* + * Minecraft Development for IntelliJ + * + * https://mcdev.io/ + * + * Copyright (C) 2025 minecraft-dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 3.0 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.demonwav.mcdev.platform.mixin.insight + +import com.demonwav.mcdev.asset.MixinAssets +import com.demonwav.mcdev.platform.mixin.handlers.MixinAnnotationHandler +import com.demonwav.mcdev.platform.mixin.util.isMixin +import com.demonwav.mcdev.util.mapFirstNotNull +import com.intellij.codeInsight.daemon.GutterIconNavigationHandler +import com.intellij.codeInsight.daemon.LineMarkerInfo +import com.intellij.codeInsight.daemon.LineMarkerProviderDescriptor +import com.intellij.codeInsight.hint.HintManager +import com.intellij.codeInsight.navigation.getPsiElementPopup +import com.intellij.openapi.editor.markup.GutterIconRenderer +import com.intellij.openapi.fileEditor.FileEditorManager +import com.intellij.psi.PsiAnnotation +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiField +import com.intellij.psi.PsiIdentifier +import com.intellij.psi.PsiMember +import com.intellij.psi.PsiMethod +import com.intellij.psi.SmartPsiElementPointer +import com.intellij.psi.util.createSmartPointer +import com.intellij.ui.awt.RelativePoint +import com.intellij.util.PsiNavigateUtil +import java.awt.event.MouseEvent + +class MixinElementLineMarkerProvider : LineMarkerProviderDescriptor() { + + override fun getName() = "Mixin element line marker" + override fun getIcon() = MixinAssets.MIXIN_ELEMENT_ICON + + override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo? { + if (element !is PsiMember) { + return null + } + val containingClass = element.containingClass ?: return null + if (!containingClass.isMixin) { + return null + } + + val identifier = when (element) { + is PsiMethod -> element.nameIdentifier + is PsiField -> element.nameIdentifier + else -> null + } ?: return null + + val (handler, annotation) = element.annotations.mapFirstNotNull { annotation -> + annotation.qualifiedName?.let { qName -> + MixinAnnotationHandler.forMixinAnnotation(qName, annotation.project)?.let { it to annotation } + } + } ?: return null + if (handler.isUnresolved(annotation) != null) { + return null + } + val simpleName = annotation.qualifiedName?.substringAfterLast('.') ?: return null + + return LineMarkerInfo( + identifier, + identifier.textRange, + icon, + { "Go to the $simpleName target" }, + MixinGutterIconNavigationHandler(identifier.createSmartPointer(), annotation.createSmartPointer(), handler), + GutterIconRenderer.Alignment.LEFT, + { "mixin $simpleName target indicator" }, + ) + } + + private class MixinGutterIconNavigationHandler( + private val identifierPointer: SmartPsiElementPointer, + private val annotationPointer: SmartPsiElementPointer, + private val handler: MixinAnnotationHandler, + ) : GutterIconNavigationHandler { + override fun navigate(e: MouseEvent, elt: PsiIdentifier) { + val element = identifierPointer.element ?: return + if (element != elt) { + return + } + val annotation = annotationPointer.element ?: return + val targets = handler.resolveForNavigation(annotation) + val editor = FileEditorManager.getInstance(elt.project).selectedTextEditor + when (targets.size) { + 0 -> { + if (editor != null) { + HintManager.getInstance().showErrorHint( + editor, + "Cannot find corresponding element in source code", + ) + } + } + 1 -> { + PsiNavigateUtil.navigate(targets[0]) + } + else -> { + if (editor != null) { + getPsiElementPopup(targets.toTypedArray(), "Choose Target") + .showInBestPositionFor(editor) + } else { + getPsiElementPopup(targets.toTypedArray(), "Choose Target") + .show(RelativePoint(e)) + } + } + } + } + } +} Index: src/main/kotlin/platform/mixin/insight/MixinTargetLineMarkerProvider.kt =================================================================== --- src/main/kotlin/platform/mixin/insight/MixinTargetLineMarkerProvider.kt (revision 043bd58ccc4bba1a25fbed1134b42a7277ce582a) +++ src/main/kotlin/platform/mixin/insight/MixinTargetLineMarkerProvider.kt (revision 043bd58ccc4bba1a25fbed1134b42a7277ce582a) @@ -1,124 +0,0 @@ -/* - * Minecraft Development for IntelliJ - * - * https://mcdev.io/ - * - * Copyright (C) 2025 minecraft-dev - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, version 3.0 only. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.demonwav.mcdev.platform.mixin.insight - -import com.demonwav.mcdev.asset.MixinAssets -import com.demonwav.mcdev.platform.mixin.handlers.MixinAnnotationHandler -import com.demonwav.mcdev.platform.mixin.util.isMixin -import com.demonwav.mcdev.util.mapFirstNotNull -import com.intellij.codeInsight.daemon.GutterIconNavigationHandler -import com.intellij.codeInsight.daemon.LineMarkerInfo -import com.intellij.codeInsight.daemon.LineMarkerProviderDescriptor -import com.intellij.codeInsight.hint.HintManager -import com.intellij.codeInsight.navigation.getPsiElementPopup -import com.intellij.openapi.editor.markup.GutterIconRenderer -import com.intellij.openapi.fileEditor.FileEditorManager -import com.intellij.psi.PsiAnnotation -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiField -import com.intellij.psi.PsiIdentifier -import com.intellij.psi.PsiMember -import com.intellij.psi.PsiMethod -import com.intellij.psi.SmartPsiElementPointer -import com.intellij.psi.util.createSmartPointer -import com.intellij.ui.awt.RelativePoint -import com.intellij.util.PsiNavigateUtil -import java.awt.event.MouseEvent - -class MixinTargetLineMarkerProvider : LineMarkerProviderDescriptor() { - - override fun getName() = "Mixin target line marker" - override fun getIcon() = MixinAssets.SHADOW - - override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo? { - if (element !is PsiMember) { - return null - } - val containingClass = element.containingClass ?: return null - if (!containingClass.isMixin) { - return null - } - - val identifier = when (element) { - is PsiMethod -> element.nameIdentifier - is PsiField -> element.nameIdentifier - else -> null - } ?: return null - - val (handler, annotation) = element.annotations.mapFirstNotNull { annotation -> - annotation.qualifiedName?.let { qName -> - MixinAnnotationHandler.forMixinAnnotation(qName, annotation.project)?.let { it to annotation } - } - } ?: return null - if (handler.isUnresolved(annotation) != null) { - return null - } - val simpleName = annotation.qualifiedName?.substringAfterLast('.') ?: return null - - return LineMarkerInfo( - identifier, - identifier.textRange, - icon, - { "Go to the $simpleName target" }, - MixinGutterIconNavigationHandler(identifier.createSmartPointer(), annotation.createSmartPointer(), handler), - GutterIconRenderer.Alignment.LEFT, - { "mixin $simpleName target indicator" }, - ) - } - - private class MixinGutterIconNavigationHandler( - private val identifierPointer: SmartPsiElementPointer, - private val annotationPointer: SmartPsiElementPointer, - private val handler: MixinAnnotationHandler, - ) : GutterIconNavigationHandler { - override fun navigate(e: MouseEvent, elt: PsiIdentifier) { - val element = identifierPointer.element ?: return - if (element != elt) { - return - } - val annotation = annotationPointer.element ?: return - val targets = handler.resolveForNavigation(annotation) - val editor = FileEditorManager.getInstance(elt.project).selectedTextEditor - when (targets.size) { - 0 -> { - if (editor != null) { - HintManager.getInstance().showErrorHint( - editor, - "Cannot find corresponding element in source code", - ) - } - } - 1 -> { - PsiNavigateUtil.navigate(targets[0]) - } - else -> { - if (editor != null) { - getPsiElementPopup(targets.toTypedArray(), "Choose Target") - .showInBestPositionFor(editor) - } else { - getPsiElementPopup(targets.toTypedArray(), "Choose Target") - .show(RelativePoint(e)) - } - } - } - } - } -} Index: src/main/resources/META-INF/plugin.xml =================================================================== --- src/main/resources/META-INF/plugin.xml (revision 043bd58ccc4bba1a25fbed1134b42a7277ce582a) +++ src/main/resources/META-INF/plugin.xml (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) @@ -740,7 +740,7 @@ + implementationClass="com.demonwav.mcdev.platform.mixin.insight.MixinElementLineMarkerProvider"/> Index: src/main/resources/assets/icons/mixin/mixin_class_gutter.svg =================================================================== --- src/main/resources/assets/icons/mixin/mixin_class_gutter.svg (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) +++ src/main/resources/assets/icons/mixin/mixin_class_gutter.svg (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) @@ -0,0 +1,17 @@ + + + + Index: src/main/resources/assets/icons/mixin/mixin_class_gutter_dark.svg =================================================================== --- src/main/resources/assets/icons/mixin/mixin_class_gutter_dark.svg (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) +++ src/main/resources/assets/icons/mixin/mixin_class_gutter_dark.svg (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) @@ -0,0 +1,17 @@ + + + + Index: src/main/resources/assets/icons/mixin/mixin_element.svg =================================================================== --- src/main/resources/assets/icons/mixin/mixin_element.svg (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) +++ src/main/resources/assets/icons/mixin/mixin_element.svg (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) @@ -0,0 +1,28 @@ + + + + Index: src/main/resources/assets/icons/mixin/mixin_element_dark.svg =================================================================== --- src/main/resources/assets/icons/mixin/mixin_element_dark.svg (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) +++ src/main/resources/assets/icons/mixin/mixin_element_dark.svg (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) @@ -0,0 +1,28 @@ + + + + Index: src/main/resources/assets/icons/mixin/mixin_mark.svg =================================================================== --- src/main/resources/assets/icons/mixin/mixin_mark.svg (revision 043bd58ccc4bba1a25fbed1134b42a7277ce582a) +++ src/main/resources/assets/icons/mixin/mixin_mark.svg (revision 1e66be05e21acb00dcd0f1db224d62cd235dab5a) @@ -1,3 +1,17 @@ - + - + +