diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/AdditionalIcon.kt b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/AdditionalIcon.kt index 73764ef3a0ff..99528e9eb2c5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/AdditionalIcon.kt +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/AdditionalIcon.kt @@ -37,6 +37,8 @@ abstract class AdditionalIcon(val myIcon: ActiveIcon) { abstract val rectangle: Rectangle abstract val active: Boolean abstract val available: Boolean + abstract val action: Runnable + open val afterText = true private fun getIconY(): Int { return rectangle.y + rectangle.height / 2 - getIconHeight() / 2 + 1 diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentTabLabel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentTabLabel.java index 1837c0c32386..b4471bb5dc4b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentTabLabel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentTabLabel.java @@ -3,7 +3,10 @@ package com.intellij.openapi.wm.impl.content; import com.intellij.ide.IdeTooltip; import com.intellij.ide.IdeTooltipManager; +import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.ui.popup.ActiveIcon; @@ -12,6 +15,7 @@ import com.intellij.ui.Gray; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentManager; import com.intellij.util.ui.BaseButtonBehavior; +import com.intellij.util.ui.JBEmptyBorder; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.TimedDeadzone; import org.jetbrains.annotations.NotNull; @@ -24,7 +28,10 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; class ContentTabLabel extends BaseLabel { private final ActiveIcon closeIcon = new ActiveIcon(JBUI.CurrentTheme.ToolWindow.closeTabIcon(true), @@ -34,7 +41,7 @@ class ContentTabLabel extends BaseLabel { protected static final int ICONS_GAP = 3; - private final List additionalIcon = new ArrayList<>(); + private final List additionalIcons = new ArrayList<>(); private final AdditionalIcon closeTabIcon = new AdditionalIcon(closeIcon) { private static final String ACTION_NAME = "Close tab"; @@ -55,6 +62,17 @@ class ContentTabLabel extends BaseLabel { return canBeClosed(); } + @NotNull + @Override + public Runnable getAction() { + return () -> contentManager().removeContent(getContent(), true); + } + + @Override + public boolean getAfterText() { + return UISettings.getShadowInstance().getCloseTabButtonOnTheRight() || !UISettings.getShadowInstance().getShowCloseButton(); + } + @Nullable @Override public String getTooltip() { @@ -95,12 +113,17 @@ class ContentTabLabel extends BaseLabel { BaseButtonBehavior behavior = new BaseButtonBehavior(this) { protected void execute(final MouseEvent e) { - if (canBeClosed() && mouseOverIcon(closeTabIcon)) { - contentManager().removeContent(getContent(), true); - } - else { - selectContent(); + + Optional first = additionalIcons.stream() + .filter(icon -> mouseOverIcon(icon)) + .map(icon -> icon.getAction()).findFirst(); + + if (first.isPresent()) { + first.get().run(); + return; } + + selectContent(); } }; @@ -119,7 +142,7 @@ class ContentTabLabel extends BaseLabel { myLayout = layout; myContent = content; - fillIcons(additionalIcon); + fillIcons(additionalIcons); behavior.setActionTrigger(MouseEvent.MOUSE_RELEASED); behavior.setMouseDeadzone(TimedDeadzone.NULL); @@ -133,6 +156,11 @@ class ContentTabLabel extends BaseLabel { } } }); + + ApplicationManager.getApplication().getMessageBus().connect().subscribe(UISettingsListener.TOPIC, uiSettings -> { + revalidate(); + repaint(); + }); } protected void fillIcons(List icons) { @@ -150,7 +178,7 @@ class ContentTabLabel extends BaseLabel { repaint(); } - Optional first = additionalIcon.stream().filter(icon -> mouseOverIcon(icon)).findFirst(); + Optional first = additionalIcons.stream().filter(icon -> mouseOverIcon(icon)).findFirst(); if (first.isPresent()) { showTooltip(first.get()); @@ -162,7 +190,7 @@ class ContentTabLabel extends BaseLabel { } protected boolean invalid() { - return additionalIcon.stream().anyMatch(icon -> icon.getAvailable()); + return additionalIcons.stream().anyMatch(icon -> icon.getAvailable()); } public final boolean canBeClosed() { @@ -182,9 +210,8 @@ class ContentTabLabel extends BaseLabel { setBorder(null); } else { - if (additionalIcon.stream().anyMatch(icon -> icon.getAvailable())) { + if (additionalIcons.stream().anyMatch(icon -> icon.getAvailable())) { setHorizontalAlignment(SwingConstants.LEFT); - setBorder(JBUI.Borders.empty(0, 12, 0, 3)); } else { setHorizontalAlignment(SwingConstants.CENTER); @@ -198,16 +225,39 @@ class ContentTabLabel extends BaseLabel { @Override public Dimension getPreferredSize() { final Dimension size = super.getPreferredSize(); - int w = size.width; + int x = 0; + Map> map = + additionalIcons.stream().filter(icon -> icon.getAvailable()).collect(Collectors.groupingBy(icon -> icon.getAfterText())); - for (AdditionalIcon icon : additionalIcon) { - if (icon.getAvailable()) { - icon.setX(w + ICONS_GAP - getInsets().right); - w += icon.getIconWidth() + ICONS_GAP; + int right = 12; + int left = 12; + + if (map.get(false) != null) { + x = ICONS_GAP; + + for (AdditionalIcon icon : map.get(false)) { + icon.setX(x); + x += icon.getIconWidth() + ICONS_GAP; + } + + left = x; + x = 0; + } + + x += size.width; + + if (map.get(true) != null) { + right = ICONS_GAP + 4; + + for (AdditionalIcon icon : map.get(true)) { + icon.setX(x + ICONS_GAP - right); + x += icon.getIconWidth() + ICONS_GAP; } } - return new Dimension(w, size.height); + setBorder(JBUI.Borders.empty(0, left, 0, right)); + + return new Dimension(x, size.height); } @Override @@ -234,7 +284,7 @@ class ContentTabLabel extends BaseLabel { } private void paintIcons(final Graphics g) { - for (AdditionalIcon icon : additionalIcon) { + for (AdditionalIcon icon : additionalIcons) { if (icon.getAvailable()) { icon.paintIcon(this, g); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabbedContentTabLabel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabbedContentTabLabel.java index e11533872adb..65dfc0f4f9e3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabbedContentTabLabel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabbedContentTabLabel.java @@ -8,6 +8,7 @@ import com.intellij.reference.SoftReference; import com.intellij.ui.content.TabbedContent; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.awt.*; import java.lang.ref.Reference; @@ -78,6 +79,12 @@ public class TabbedContentTabLabel extends ContentTabLabel { public boolean getAvailable() { return hasMultipleTabs(); } + + @Nullable + @Override + public Runnable getAction() { + return () -> selectContent(); + } }); super.fillIcons(icons); }