diff --git a/platform/execution-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java b/platform/execution-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java index 2e6f878f73c1..aadef89e1c93 100644 --- a/platform/execution-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java +++ b/platform/execution-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java @@ -36,9 +36,12 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.popup.NumericMnemonicItem; import com.intellij.ui.popup.WizardPopup; import com.intellij.ui.popup.list.ListPopupImpl; +import com.intellij.ui.popup.list.PopupListElementRenderer; import com.intellij.ui.speedSearch.SpeedSearch; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.GridBag; +import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -758,6 +761,30 @@ public final class ChooseRunConfigurationPopup implements ExecutorProvider { return false; } + @Override + protected ListCellRenderer getListElementRenderer() { + return new PopupListElementRenderer<>(this){ + @Override + protected JComponent createIconBar(JList list, Object value, boolean selected) { + JPanel res = new JPanel(new GridBagLayout()); + res.setOpaque(false); + res.setBorder(JBUI.Borders.emptyRight(JBUI.CurrentTheme.ActionsList.elementIconGap())); + + GridBag gbc = new GridBag() + .setDefaultAnchor(GridBagConstraints.CENTER) + .setDefaultWeightX(1) + .setDefaultInsets(0, 0, 0, 0) + .setDefaultFill(GridBagConstraints.BOTH); + + res.add(myMnemonicLabel, gbc.next()); + res.add(Box.createHorizontalStrut(JBUI.CurrentTheme.ActionsList.MNEMONIC_ICON_GAP), gbc.next()); + res.add(myIconLabel, gbc.next()); + + return res; + } + }; + } + @Override public void handleSelect(boolean handleFinalChoices, InputEvent e) { if (e instanceof MouseEvent && e.isShiftDown()) { diff --git a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java index df67e76a09d4..4fc5b5415f1e 100644 --- a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java +++ b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java @@ -50,9 +50,7 @@ public abstract class GroupedElementsRenderer implements Accessible { AccessibleContextUtil.setName(myRendererComponent, myTextLabel); AccessibleContextUtil.setDescription(myRendererComponent, myTextLabel); - myTextLabel.setIcon(icon); - myTextLabel.setDisabledIcon(disabledIcon); - myTextLabel.setIconTextGap(JBUI.CurrentTheme.ActionsList.elementIconGap()); + setComponentIcon(icon, disabledIcon); setSelected(myComponent, isSelected); setSelected(myTextLabel, isSelected); @@ -62,6 +60,12 @@ public abstract class GroupedElementsRenderer implements Accessible { return myRendererComponent; } + protected void setComponentIcon(Icon icon, Icon disabledIcon) { + myTextLabel.setIcon(icon); + myTextLabel.setDisabledIcon(disabledIcon); + myTextLabel.setIconTextGap(JBUI.CurrentTheme.ActionsList.elementIconGap()); + } + protected final void setSelected(JComponent aComponent) { setSelected(aComponent, true); } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula_linux.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula_linux.properties index 4a3920cde809..9d8e61236425 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula_linux.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula_linux.properties @@ -18,4 +18,4 @@ OptionPane.informationIcon=AllIcons.General.InformationDialog OptionPane.questionIcon=AllIcons.General.QuestionDialog ActionsList.mnemonicsBorderInsets=0,8,1,8 -ActionsList.icon.gap=8 \ No newline at end of file +ActionsList.icon.gap=6 \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_linux.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_linux.properties index c4eefb67e41d..c050f521b13f 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_linux.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_linux.properties @@ -21,4 +21,4 @@ OptionPane.informationIcon=AllIcons.General.InformationDialog OptionPane.questionIcon=AllIcons.General.QuestionDialog ActionsList.mnemonicsBorderInsets=0,8,1,8 -ActionsList.icon.gap=8 \ No newline at end of file +ActionsList.icon.gap=6 \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java b/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java index e7ecbf784164..e906f9677578 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java @@ -33,10 +33,12 @@ public class PopupListElementRenderer extends GroupedItemsListRenderer { private JLabel myShortcutLabel; private @Nullable JLabel myValueLabel; protected JLabel myMnemonicLabel; + protected JLabel myIconLabel; - protected JComponent myRightPart; - protected JComponent myLeftPart; + protected JComponent myButtonPane; + protected JComponent myMainPane; protected JComponent myNextStepButtonSeparator; + protected JComponent myIconBar; public PopupListElementRenderer(final ListPopupImpl aPopup) { super(new ListItemDescriptorAdapter<>() { @@ -117,6 +119,8 @@ public class PopupListElementRenderer extends GroupedItemsListRenderer { myMnemonicLabel.setBorder(new JBEmptyBorder(insets)); myMnemonicLabel.setFont(JBUI.CurrentTheme.ActionsList.applyStylesForNumberMnemonic(myMnemonicLabel.getFont())); + myIconLabel = new JLabel(); + return layoutComponent(panel); } @@ -157,12 +161,18 @@ public class PopupListElementRenderer extends GroupedItemsListRenderer { result.add(left, gbc.next()); result.add(right, gbc.next()); - myLeftPart = left; - myRightPart = right; + myMainPane = left; + myButtonPane = right; return result; } + @Override + protected void setComponentIcon(Icon icon, Icon disabledIcon) { + myIconLabel.setIcon(icon); + myIconLabel.setDisabledIcon(disabledIcon); + } + @NotNull protected static JComponent createNextStepButtonSeparator() { SeparatorComponent separator = new SeparatorComponent(JBColor.namedColor("Menu.separatorColor", JBColor.lightGray), SeparatorOrientation.VERTICAL); @@ -194,8 +204,8 @@ public class PopupListElementRenderer extends GroupedItemsListRenderer { setSelected(myComponent, isSelected && isSelectable); setSelected(myTextLabel, isSelected && isSelectable); - myLeftPart.setOpaque(false); - myRightPart.setOpaque(false); + myMainPane.setOpaque(false); + myButtonPane.setOpaque(false); myNextStepButtonSeparator.setVisible(false); boolean nextStepButtonSelected = false; @@ -203,14 +213,14 @@ public class PopupListElementRenderer extends GroupedItemsListRenderer { myNextStepLabel.setVisible(isSelectable); if (Registry.is("ide.list.popup.separate.next.step.button") && step.isFinal(value)) { - myLeftPart.setOpaque(true); - myRightPart.setOpaque(true); + myMainPane.setOpaque(true); + myButtonPane.setOpaque(true); setSelected(myComponent, false, isSelected); nextStepButtonSelected = isNextStepButtonSelected(list); - setSelected(myLeftPart, isSelected && !nextStepButtonSelected, isSelected); + setSelected(myMainPane, isSelected && !nextStepButtonSelected, isSelected); setSelected(myTextLabel, isSelected && !nextStepButtonSelected, isSelected); - setSelected(myRightPart, isSelected && nextStepButtonSelected, isSelected); + setSelected(myButtonPane, isSelected && nextStepButtonSelected, isSelected); myNextStepLabel.setIcon(isSelectable & isSelected && nextStepButtonSelected ? AllIcons.Icons.Ide.MenuArrowSelected : AllIcons.Icons.Ide.MenuArrow); myNextStepButtonSeparator.setVisible(!isSelected); } @@ -240,7 +250,6 @@ public class PopupListElementRenderer extends GroupedItemsListRenderer { Character mnemonic = ((NumericMnemonicItem)value).getMnemonicChar(); myMnemonicLabel.setText(mnemonic != null ? String.valueOf(mnemonic) : ""); myMnemonicLabel.setForeground(isSelected && isSelectable && !nextStepButtonSelected ? getSelectionForeground() : JBUI.CurrentTheme.ActionsList.MNEMONIC_FOREGROUND); - myLeftPart.add(myMnemonicLabel, BorderLayout.WEST); } if (step.isMnemonicsNavigationEnabled()) { @@ -287,6 +296,24 @@ public class PopupListElementRenderer extends GroupedItemsListRenderer { myValueLabel.setText(step instanceof ListPopupStepEx ? ((ListPopupStepEx)step).getValueFor(value) : null); setSelected(myValueLabel, isSelected && isSelectable && !nextStepButtonSelected, isSelected); } + + if (myIconBar != null) myMainPane.remove(myIconBar); + myIconBar = createIconBar(list, value, isSelected); + if (myIconBar != null) myMainPane.add(myIconBar, BorderLayout.WEST); + } + + @Nullable + protected JComponent createIconBar(JList list, E value, boolean selected) { + boolean mnemonicShown = value instanceof NumericMnemonicItem && ((NumericMnemonicItem)value).digitMnemonicsEnabled(); + boolean iconShown = myIconLabel.getIcon() != null; + if (!mnemonicShown && !iconShown) return null; + + Box res = Box.createHorizontalBox(); + res.setBorder(JBUI.Borders.emptyRight(JBUI.CurrentTheme.ActionsList.elementIconGap())); + if (iconShown) res.add(myIconLabel); + if (mnemonicShown) res.add(myMnemonicLabel); + + return res; } private void setSelected(JComponent component, boolean selected, boolean hovered) { diff --git a/platform/util/ui/src/com/intellij/util/ui/JBUI.java b/platform/util/ui/src/com/intellij/util/ui/JBUI.java index 3ce4bbcf3335..84f39688a2bf 100644 --- a/platform/util/ui/src/com/intellij/util/ui/JBUI.java +++ b/platform/util/ui/src/com/intellij/util/ui/JBUI.java @@ -421,6 +421,7 @@ public class JBUI { public static final class ActionsList { public static final Color MNEMONIC_FOREGROUND = JBColor.namedColor("Label.infoForeground", new JBColor(Gray.x78, Gray.x8C)); + public static final int MNEMONIC_ICON_GAP = scale(4); @NotNull public static Insets numberMnemonicInsets() { @@ -434,7 +435,7 @@ public class JBUI { @NotNull public static int elementIconGap() { - return new JBValue.UIInteger("ActionsList.icon.gap", scale(8)).get(); + return new JBValue.UIInteger("ActionsList.icon.gap", scale(6)).get(); } @NotNull diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/PopupListElementRendererWithIcon.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/PopupListElementRendererWithIcon.java index 35f02a092c1a..d3e6d6615155 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/PopupListElementRendererWithIcon.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/PopupListElementRendererWithIcon.java @@ -10,6 +10,7 @@ import com.intellij.ui.popup.list.PopupListElementRenderer; import com.intellij.util.IconUtil; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.Border; @@ -37,11 +38,20 @@ public class PopupListElementRendererWithIcon extends PopupListElementRenderer list, Object value, boolean isSelected) { super.customizeComponent(list, value, isSelected); - myTextLabel.setIcon(null); - myTextLabel.setDisabledIcon(null); myIconLabel.setIcon(isSelected ? IconUtil.wrapToSelectionAwareIcon(myDescriptor.getSelectedIconFor(value)) : myDescriptor.getIconFor(value)); } + @Override + protected void setComponentIcon(Icon icon, Icon disabledIcon) { + myIconLabel.setIcon(icon); + myIconLabel.setDisabledIcon(disabledIcon); + } + + @Override + protected @Nullable JComponent createIconBar(JList list, Object value, boolean selected) { + return myIconLabel; + } + @Override protected JComponent createItemComponent() { myTextLabel = new ErrorLabel();