From b9b03887d633c84913f0dafcebd2f773d0c8076d Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Tue, 27 Aug 2024 18:55:59 +0200 Subject: [PATCH] IJPL-161142 vcs: fix CheckboxIcon rendering The mutable 'mySelected' state does not work well with 'JBCachingScalableIcon' cache. GitOrigin-RevId: 0610f54a55900be826137ebf119724d29daf6e0c --- .../src/com/intellij/util/ui/CheckboxIcon.kt | 33 +++++++++++-------- .../filter/StructureFilterPopupComponent.java | 30 ++++++++--------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/platform/platform-api/src/com/intellij/util/ui/CheckboxIcon.kt b/platform/platform-api/src/com/intellij/util/ui/CheckboxIcon.kt index 546f2ea49722..a3881c4ffaab 100644 --- a/platform/platform-api/src/com/intellij/util/ui/CheckboxIcon.kt +++ b/platform/platform-api/src/com/intellij/util/ui/CheckboxIcon.kt @@ -25,8 +25,18 @@ object CheckboxIcon { fun createAndScale(color: Color): ColorIcon = JBUIScale.scaleIcon(create(color)) @JvmStatic - fun createAndScaleCheckbox(color: Color): WithColor { - return JBUIScale.scaleIcon(WithColor(iconSize, color, arcSize)) + fun createAndScaleCheckbox(color: Color): JBScalableIcon { + return createAndScaleCheckbox(color, true) + } + + @JvmStatic + fun createAndScaleCheckbox(color: Color, isSelected: Boolean): JBScalableIcon { + if (isSelected) { + return JBUIScale.scaleIcon(WithColor(iconSize, color, arcSize)) + } + else { + return JBUIScale.scaleIcon(ColorIcon(iconSize, iconSize, iconSize, iconSize, color, false, arcSize)) + } } private const val iconSize = 14 @@ -36,12 +46,9 @@ object CheckboxIcon { get() = if (ExperimentalUI.isNewUI()) 4 else 0 - class WithColor(size: Int, color: Color, arc: Int) : ColorIcon(size, size, size, size, color, false, arc) { - private var mySelected = false + class WithColor(private val size: Int, color: Color, arc: Int) : ColorIcon(size, size, size, size, color, false, arc) { private var mySizedIcon: SizedIcon - fun isSelected() = mySelected - init { val icon = if (ExperimentalUI.isNewUI()) { IconUtil.resizeSquared(LafIconLookup.getIcon("checkmark", true), checkMarkSize) @@ -52,10 +59,6 @@ object CheckboxIcon { mySizedIcon = SizedIcon(icon, checkMarkSize, checkMarkSize) } - fun prepare(selected: Boolean) { - mySelected = selected - } - override fun withIconPreScaled(preScaled: Boolean): WithColor { mySizedIcon = mySizedIcon.withIconPreScaled(preScaled) as SizedIcon return super.withIconPreScaled(preScaled) as WithColor @@ -64,10 +67,12 @@ object CheckboxIcon { override fun paintIcon(component: Component, g: Graphics, i: Int, j: Int) { super.paintIcon(component, g, i, j) - if (mySelected) { - val offset = (iconWidth - mySizedIcon.iconWidth) / 2 - mySizedIcon.paintIcon(component, g, i + offset, j + offset) - } + val offset = (iconWidth - mySizedIcon.iconWidth) / 2 + mySizedIcon.paintIcon(component, g, i + offset, j + offset) + } + + override fun copy(): ColorIcon { + return WithColor(size, iconColor, arcSize) } } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java index 2b0f1dc17d4d..7a3fca6f6596 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java @@ -43,9 +43,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.io.File; +import java.util.List; import java.util.*; import java.util.function.Function; @@ -183,7 +185,7 @@ public class StructureFilterPopupComponent extends FilterPopupComponent rootActions = new ArrayList<>(); if (myColorManager.hasMultiplePaths()) { for (VirtualFile root : ContainerUtil.sorted(roots, FILE_BY_NAME_COMPARATOR)) { - rootActions.add(new SelectVisibleRootAction(root, rootActions)); + rootActions.add(new SelectVisibleRootAction(root)); } } List structureActions = new ArrayList<>(); @@ -295,16 +297,19 @@ public class StructureFilterPopupComponent extends FilterPopupComponent myAllActions; + private final Icon mySelectedIcon; + private final Icon myDeselectedIcon; - SelectVisibleRootAction(@NotNull VirtualFile root, @NotNull List allActions) { + final VirtualFile myRoot; + + SelectVisibleRootAction(@NotNull VirtualFile root) { super(null, root.getPresentableUrl(), null); getTemplatePresentation().setText(root.getName(), false); myRoot = root; - myAllActions = allActions; - myIcon = CheckboxIcon.createAndScaleCheckbox(myColorManager.getRootColor(myRoot)); + + Color color = myColorManager.getRootColor(myRoot); + mySelectedIcon = CheckboxIcon.createAndScaleCheckbox(color, true); + myDeselectedIcon = CheckboxIcon.createAndScaleCheckbox(color, false); getTemplatePresentation().setIcon(JBUIScale.scaleIcon(EmptyIcon.create(CHECKBOX_ICON_SIZE))); // see PopupFactoryImpl.calcMaxIconSize } @@ -329,9 +334,6 @@ public class StructureFilterPopupComponent extends FilterPopupComponent