mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-222013 Redesign "More" popup in editor tabs
GitOrigin-RevId: 47fb19e63a152ef25bfff2d62c058d5f062fd779
This commit is contained in:
committed by
intellij-monorepo-bot
parent
982f04a240
commit
22501defbe
@@ -29,6 +29,7 @@ public abstract class ActionPlaces {
|
||||
public static final String EDITOR_TOOLBAR = "EditorToolbar";
|
||||
public static final String EDITOR_TAB_POPUP = "EditorTabPopup";
|
||||
public static final String EDITOR_TAB = "EditorTab";
|
||||
public static final String TABS_MORE_TOOLBAR = "TabsMoreToolbar";
|
||||
public static final String EDITOR_GUTTER = "ICON_NAVIGATION";
|
||||
public static final String EDITOR_GUTTER_POPUP = "ICON_NAVIGATION_SECONDARY_BUTTON";
|
||||
public static final String RIGHT_EDITOR_GUTTER_POPUP = "RightEditorGutterPopup";
|
||||
@@ -150,7 +151,7 @@ public abstract class ActionPlaces {
|
||||
|
||||
private static final Set<String> ourCommonPlaces = ContainerUtil.newHashSet(
|
||||
UNKNOWN, KEYBOARD_SHORTCUT, MOUSE_SHORTCUT, FORCE_TOUCH,
|
||||
TOOLBAR, MAIN_MENU, MAIN_TOOLBAR, EDITOR_TOOLBAR, EDITOR_TAB, COMMANDER_TOOLBAR, CONTEXT_TOOLBAR, TOOLWINDOW_TITLE,
|
||||
TOOLBAR, MAIN_MENU, MAIN_TOOLBAR, EDITOR_TOOLBAR, TABS_MORE_TOOLBAR, EDITOR_TAB, COMMANDER_TOOLBAR, CONTEXT_TOOLBAR, TOOLWINDOW_TITLE,
|
||||
PROJECT_VIEW_TOOLBAR, STATUS_BAR_PLACE, ACTION_SEARCH, TESTTREE_VIEW_TOOLBAR, TYPE_HIERARCHY_VIEW_TOOLBAR,
|
||||
METHOD_HIERARCHY_VIEW_TOOLBAR, CALL_HIERARCHY_VIEW_TOOLBAR, RUNNER_TOOLBAR, DEBUGGER_TOOLBAR, USAGE_VIEW_TOOLBAR,
|
||||
STRUCTURE_VIEW_TOOLBAR, NAVIGATION_BAR_TOOLBAR, TODO_VIEW_TOOLBAR, COMPILER_MESSAGES_TOOLBAR,
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.intellij.openapi.util.ActionCallback;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
@@ -19,10 +18,6 @@ public interface JBTabsEx extends JBTabs {
|
||||
|
||||
void updateTabActions(boolean validateNow);
|
||||
|
||||
boolean canShowMorePopup();
|
||||
|
||||
void showMorePopup(@Nullable MouseEvent e);
|
||||
|
||||
TabInfo addTabSilently(TabInfo info, int index);
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.rd.RdIdeaKt;
|
||||
import com.intellij.openapi.ui.*;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
@@ -52,7 +53,7 @@ import static com.intellij.openapi.wm.IdeFocusManager.getGlobalInstance;
|
||||
|
||||
public class JBTabsImpl extends JComponent
|
||||
implements JBTabsEx, PropertyChangeListener, TimerListener, DataProvider, PopupMenuListener, Disposable, JBTabsPresentation, Queryable,
|
||||
UISettingsListener, QuickActionProvider, Accessible {
|
||||
UISettingsListener, QuickActionProvider, MorePopupAware, Accessible {
|
||||
|
||||
public static final Key<Integer> SIDE_TABS_SIZE_LIMIT_KEY = Key.create("SIDE_TABS_SIZE_LIMIT_KEY");
|
||||
static final int MIN_TAB_WIDTH = JBUIScale.scale(75);
|
||||
@@ -69,6 +70,7 @@ public class JBTabsImpl extends JComponent
|
||||
private TabInfo mySelectedInfo;
|
||||
public final Map<TabInfo, TabLabel> myInfo2Label = new HashMap<>();
|
||||
public final Map<TabInfo, Toolbar> myInfo2Toolbar = new HashMap<>();
|
||||
public final ActionToolbar myMoreToolbar;
|
||||
public Dimension myHeaderFitSize;
|
||||
|
||||
private Insets myInnerInsets = JBUI.emptyInsets();
|
||||
@@ -243,17 +245,13 @@ public class JBTabsImpl extends JComponent
|
||||
disposePopupListener();
|
||||
}
|
||||
};
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(final MouseEvent e) {
|
||||
if (mySingleRowLayout.myLastSingRowLayout != null &&
|
||||
mySingleRowLayout.myLastSingRowLayout.moreRect != null &&
|
||||
mySingleRowLayout.myLastSingRowLayout.moreRect.contains(e.getPoint())) {
|
||||
showMorePopup(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
AnAction tabListAction = myActionManager.getAction("TabList");
|
||||
myMoreToolbar = myActionManager
|
||||
.createActionToolbar(ActionPlaces.TABS_MORE_TOOLBAR, new DefaultActionGroup(tabListAction), true);
|
||||
myMoreToolbar.getComponent().setBorder(JBUI.Borders.empty());
|
||||
myMoreToolbar.getComponent().setOpaque(false);
|
||||
myMoreToolbar.setLayoutPolicy(ActionToolbar.NOWRAP_LAYOUT_POLICY);
|
||||
add(myMoreToolbar.getComponent());
|
||||
addMouseWheelListener(event -> {
|
||||
int units = event.getUnitsToScroll();
|
||||
if (units == 0) return;
|
||||
@@ -332,7 +330,7 @@ public class JBTabsImpl extends JComponent
|
||||
myGlassPane = gp;
|
||||
|
||||
UIUtil.addAwtListener(__ -> {
|
||||
if (mySingleRowLayout.myMorePopup != null) return;
|
||||
if (!JBPopupFactory.getInstance().getChildPopups(JBTabsImpl.this).isEmpty()) return;
|
||||
processFocusChange();
|
||||
}, AWTEvent.FOCUS_EVENT_MASK, child);
|
||||
|
||||
@@ -712,53 +710,35 @@ public class JBTabsImpl extends JComponent
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canShowMorePopup() {
|
||||
final SingleRowPassInfo lastLayout = mySingleRowLayout.myLastSingRowLayout;
|
||||
return lastLayout != null && lastLayout.moreRect != null;
|
||||
private Rectangle getMoreRect() {
|
||||
SingleRowPassInfo lastLayout = mySingleRowLayout.myLastSingRowLayout;
|
||||
return lastLayout != null ? lastLayout.moreRect : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMorePopup(@Nullable final MouseEvent e) {
|
||||
final SingleRowPassInfo lastLayout = mySingleRowLayout.myLastSingRowLayout;
|
||||
if (lastLayout == null) {
|
||||
return;
|
||||
}
|
||||
mySingleRowLayout.myMorePopup = new JBPopupMenu();
|
||||
public boolean canShowMorePopup() {
|
||||
return getMoreRect() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMorePopup() {
|
||||
Rectangle rect = getMoreRect();
|
||||
if (rect == null) return;
|
||||
|
||||
JBPopupMenu menu = new JBPopupMenu();
|
||||
for (final TabInfo each : getVisibleInfos()) {
|
||||
if (!mySingleRowLayout.isTabHidden(each)) continue;
|
||||
final JBMenuItem item = new JBMenuItem(each.getText(), each.getIcon());
|
||||
item.setForeground(each.getDefaultForeground());
|
||||
item.setBackground(each.getTabColor());
|
||||
mySingleRowLayout.myMorePopup.add(item);
|
||||
item.addActionListener(__ -> select(each, true));
|
||||
menu.add(createMenuItem(each));
|
||||
}
|
||||
menu.show(this, rect.x, rect.y + rect.height);
|
||||
}
|
||||
|
||||
mySingleRowLayout.myMorePopup.addPopupMenuListener(new PopupMenuListener() {
|
||||
@Override
|
||||
public void popupMenuWillBecomeVisible(final PopupMenuEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuWillBecomeInvisible(final PopupMenuEvent e) {
|
||||
mySingleRowLayout.myMorePopup = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuCanceled(final PopupMenuEvent e) {
|
||||
mySingleRowLayout.myMorePopup = null;
|
||||
}
|
||||
});
|
||||
|
||||
if (e != null) {
|
||||
mySingleRowLayout.myMorePopup.show(this, e.getX(), e.getY());
|
||||
}
|
||||
else {
|
||||
final Rectangle rect = lastLayout.moreRect;
|
||||
if (rect != null) {
|
||||
mySingleRowLayout.myMorePopup.show(this, rect.x, rect.y + rect.height);
|
||||
}
|
||||
}
|
||||
private JBMenuItem createMenuItem(@NotNull TabInfo tabInfo) {
|
||||
final JBMenuItem item = new JBMenuItem(tabInfo.getText(), tabInfo.getIcon());
|
||||
item.setForeground(tabInfo.getDefaultForeground());
|
||||
item.setBackground(tabInfo.getTabColor());
|
||||
item.addActionListener(__ -> select(tabInfo, true));
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
@@ -1512,6 +1492,20 @@ public class JBTabsImpl extends JComponent
|
||||
if (isSingleRow()) {
|
||||
mySingleRowLayout.scrollSelectionInView();
|
||||
myLastLayoutPass = mySingleRowLayout.layoutSingleRow(visible);
|
||||
Rectangle moreRect = getMoreRect();
|
||||
if (moreRect != null) {
|
||||
Dimension preferredSize = myMoreToolbar.getComponent().getPreferredSize();
|
||||
Rectangle bounds = new Rectangle(moreRect);
|
||||
int xDiff = (bounds.width - preferredSize.width) / 2;
|
||||
int yDiff = (bounds.height - preferredSize.height) / 2;
|
||||
bounds.x += xDiff + 1;
|
||||
bounds.width -= 2 * xDiff;
|
||||
bounds.y += yDiff;
|
||||
bounds.height -= 2* yDiff;
|
||||
myMoreToolbar.getComponent().setBounds(bounds);
|
||||
} else {
|
||||
myMoreToolbar.getComponent().setBounds(new Rectangle());
|
||||
}
|
||||
myTableLayout.myLastTableLayout = null;
|
||||
OnePixelDivider divider = mySplitter.getDivider();
|
||||
if (divider.getParent() == this) {
|
||||
@@ -1716,12 +1710,6 @@ public class JBTabsImpl extends JComponent
|
||||
return JBSwingUtilities.runGlobalCGTransform(this, super.getComponentGraphics(graphics));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintChildren(final Graphics g) {
|
||||
super.paintChildren(g);
|
||||
mySingleRowLayout.myMoreIcon.paintIcon(this, g);
|
||||
}
|
||||
|
||||
protected void drawBorder(Graphics g) {
|
||||
if (!isHideTabs()) {
|
||||
myBorder.paintBorder(this, g, 0, 0, getWidth(), getHeight());
|
||||
@@ -2530,6 +2518,9 @@ public class JBTabsImpl extends JComponent
|
||||
if (QuickActionProvider.KEY.getName().equals(dataId)) {
|
||||
return this;
|
||||
}
|
||||
if (MorePopupAware.KEY.is(dataId)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return NAVIGATION_ACTIONS_KEY.is(dataId) ? this : null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.tabs.impl;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
|
||||
public interface MorePopupAware {
|
||||
DataKey<MorePopupAware> KEY = DataKey.create("MorePopupAware");
|
||||
|
||||
boolean canShowMorePopup();
|
||||
void showMorePopup();
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.tabs.impl.singleRow;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* @author pegov
|
||||
*/
|
||||
public abstract class MoreTabsIcon {
|
||||
private final Icon icon = AllIcons.General.MoreTabs;
|
||||
private int myCounter;
|
||||
|
||||
public void paintIcon(final Component c, Graphics graphics) {
|
||||
if (myCounter <= 0)
|
||||
return;
|
||||
final Rectangle moreRect = getIconRec();
|
||||
|
||||
if (moreRect == null) return;
|
||||
|
||||
int iconY = getIconY(moreRect);
|
||||
int iconX = getIconX(moreRect);
|
||||
graphics.setFont(UIUtil.getLabelFont().deriveFont((float)Math.min(8, UIUtil.getButtonFont().getSize())));
|
||||
int width = graphics.getFontMetrics().stringWidth(String.valueOf(myCounter));
|
||||
iconX -= width / 2 + 1;
|
||||
|
||||
icon.paintIcon(c, graphics, iconX, iconY);
|
||||
Graphics g = graphics.create();
|
||||
try {
|
||||
UISettings.setupAntialiasing(g);
|
||||
UIUtil.drawStringWithHighlighting(g, String.valueOf(myCounter),
|
||||
iconX + getIconWidth() + 2,
|
||||
iconY + getIconHeight() - 5,
|
||||
JBColor.BLACK,
|
||||
ColorUtil.withPreAlpha(JBColor.WHITE, .9));
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public int getIconWidth() {
|
||||
return icon.getIconWidth();
|
||||
}
|
||||
|
||||
public int getIconHeight() {
|
||||
return icon.getIconHeight();
|
||||
}
|
||||
|
||||
protected int getIconX(final Rectangle iconRec) {
|
||||
return iconRec.x + iconRec.width / 2 - (getIconWidth()) / 2;
|
||||
}
|
||||
|
||||
protected int getIconY(final Rectangle iconRec) {
|
||||
return iconRec.y + iconRec.height / 2 - getIconHeight() / 2;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract Rectangle getIconRec();
|
||||
|
||||
public void updateCounter(int counter) {
|
||||
myCounter = counter;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import com.intellij.ui.tabs.impl.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
@@ -21,15 +20,6 @@ public abstract class SingleRowLayout extends TabLayout {
|
||||
private final SingleRowLayoutStrategy myBottom;
|
||||
private final SingleRowLayoutStrategy myRight;
|
||||
|
||||
public final MoreTabsIcon myMoreIcon = new MoreTabsIcon() {
|
||||
@Override
|
||||
@Nullable
|
||||
protected Rectangle getIconRec() {
|
||||
return myLastSingRowLayout != null ? myLastSingRowLayout.moreRect : null;
|
||||
}
|
||||
};
|
||||
public JPopupMenu myMorePopup;
|
||||
|
||||
@Override
|
||||
public boolean isSideComponentOnTabs() {
|
||||
return getStrategy().isSideComponentOnTabs();
|
||||
@@ -135,8 +125,6 @@ public abstract class SingleRowLayout extends TabLayout {
|
||||
getStrategy().layoutComp(data);
|
||||
}
|
||||
|
||||
updateMoreIconVisibility(data);
|
||||
|
||||
data.tabRectangle = new Rectangle();
|
||||
|
||||
if (data.toLayout.size() > 0) {
|
||||
@@ -173,11 +161,6 @@ public abstract class SingleRowLayout extends TabLayout {
|
||||
data.toFitLength = getStrategy().getToFitLength(data);
|
||||
}
|
||||
|
||||
protected void updateMoreIconVisibility(SingleRowPassInfo data) {
|
||||
int counter = (int)data.myVisibleInfos.stream().filter(this::isTabHidden).count();
|
||||
myMoreIcon.updateCounter(counter);
|
||||
}
|
||||
|
||||
protected void layoutMoreButton(SingleRowPassInfo data) {
|
||||
if (data.toDrop.size() > 0) {
|
||||
data.moreRect = getStrategy().getMoreRect(data);
|
||||
|
||||
+4
-5
@@ -1,7 +1,7 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.tabs.impl.singleRow;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.ActionToolbar;
|
||||
import com.intellij.ui.tabs.impl.JBTabsImpl;
|
||||
import com.intellij.ui.tabs.impl.ShapeTransform;
|
||||
import com.intellij.ui.tabs.impl.TabLabel;
|
||||
@@ -89,7 +89,7 @@ public abstract class SingleRowLayoutStrategy {
|
||||
|
||||
@Override
|
||||
public int getMoreRectAxisSize() {
|
||||
return AllIcons.General.MoreTabs.getIconWidth() + 15;
|
||||
return ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE.width + 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -173,8 +173,7 @@ public abstract class SingleRowLayoutStrategy {
|
||||
else {
|
||||
x = data.position;
|
||||
}
|
||||
return new Rectangle(x, data.insets.top + JBTabsImpl.getSelectionTabVShift(),
|
||||
data.moreRectAxisSize - 1, myTabs.myHeaderFitSize.height);
|
||||
return new Rectangle(x, 1, data.moreRectAxisSize - 1, myTabs.myHeaderFitSize.height);
|
||||
}
|
||||
|
||||
|
||||
@@ -268,7 +267,7 @@ public abstract class SingleRowLayoutStrategy {
|
||||
|
||||
@Override
|
||||
int getMoreRectAxisSize() {
|
||||
return AllIcons.General.MoreTabs.getIconHeight() + 4;
|
||||
return ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE.width + 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.ui.tabs.JBTabsEx;
|
||||
import com.intellij.ui.tabs.impl.MorePopupAware;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -14,22 +16,21 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class TabListAction extends AnAction {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
JBTabsEx tabs = e.getData(JBTabsEx.NAVIGATION_ACTIONS_KEY);
|
||||
if (tabs != null) {
|
||||
tabs.showMorePopup(null);
|
||||
MorePopupAware morePopupAware = e.getData(MorePopupAware.KEY);
|
||||
if (morePopupAware != null) {
|
||||
morePopupAware.showMorePopup();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(isTabListAvailable(e));
|
||||
e.getPresentation().setIcon(AllIcons.Actions.FindAndShowNextMatches);
|
||||
boolean available = isTabListAvailable(e) || e.getPlace() == ActionPlaces.TABS_MORE_TOOLBAR;
|
||||
e.getPresentation().setEnabledAndVisible(available);
|
||||
}
|
||||
|
||||
private static boolean isTabListAvailable(@NotNull AnActionEvent e) {
|
||||
JBTabsEx tabs = e.getData(JBTabsEx.NAVIGATION_ACTIONS_KEY);
|
||||
if (tabs == null || !tabs.isEditorTabs()) {
|
||||
return false;
|
||||
}
|
||||
return tabs.canShowMorePopup();
|
||||
MorePopupAware morePopupAware = e.getData(MorePopupAware.KEY);
|
||||
return morePopupAware != null && morePopupAware.canShowMorePopup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,13 @@ import com.intellij.ui.DoubleClickListener;
|
||||
import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.ui.UIBundle;
|
||||
import com.intellij.ui.components.panels.NonOpaquePanel;
|
||||
import com.intellij.ui.tabs.impl.MorePopupAware;
|
||||
import com.intellij.ui.tabs.impl.SingleHeightTabs;
|
||||
import com.intellij.util.ui.*;
|
||||
import com.intellij.util.ui.accessibility.AccessibleContextUtil;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.PanelUI;
|
||||
@@ -32,7 +34,7 @@ import java.util.function.Supplier;
|
||||
/**
|
||||
* @author pegov
|
||||
*/
|
||||
public abstract class ToolWindowHeader extends JPanel implements UISettingsListener {
|
||||
public abstract class ToolWindowHeader extends JPanel implements UISettingsListener, DataProvider {
|
||||
@NotNull private final Supplier<? extends ActionGroup> myGearProducer;
|
||||
|
||||
@NotNull
|
||||
@@ -63,9 +65,11 @@ public abstract class ToolWindowHeader extends JPanel implements UISettingsListe
|
||||
|
||||
ToolWindowContentUi.initMouseListeners(myWestPanel, toolWindow.getContentUI(), true);
|
||||
|
||||
myToolbar = ActionManager.getInstance().createActionToolbar(
|
||||
ActionManager actionManager = ActionManager.getInstance();
|
||||
AnAction tabListAction = actionManager.getAction("TabList");
|
||||
myToolbar = actionManager.createActionToolbar(
|
||||
ActionPlaces.TOOLWINDOW_TITLE,
|
||||
new DefaultActionGroup(myActionGroup, new ShowOptionsAction(), new HideAction()),
|
||||
new DefaultActionGroup(tabListAction, myActionGroup, new ShowOptionsAction(), new HideAction()),
|
||||
true);
|
||||
myToolbar.setTargetComponent(this);
|
||||
myToolbar.setLayoutPolicy(ActionToolbar.NOWRAP_LAYOUT_POLICY);
|
||||
@@ -131,6 +135,15 @@ public abstract class ToolWindowHeader extends JPanel implements UISettingsListe
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData(@NotNull String dataId) {
|
||||
if (MorePopupAware.KEY.is(dataId) && myToolWindow instanceof ToolWindowImpl) {
|
||||
return ((ToolWindowImpl)myToolWindow).getContentUI().getData(dataId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void initWestToolBar(JPanel westPanel) {
|
||||
myToolbarWest =
|
||||
ActionManager.getInstance().createActionToolbar(ActionPlaces.TOOLWINDOW_TITLE, new DefaultActionGroup(myActionGroupWest),
|
||||
|
||||
+33
-37
@@ -4,6 +4,7 @@ package com.intellij.openapi.wm.impl.content;
|
||||
import com.intellij.ide.dnd.DnDSupport;
|
||||
import com.intellij.ide.dnd.DnDTarget;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.ListPopup;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -16,7 +17,7 @@ import com.intellij.ui.content.TabbedContent;
|
||||
import com.intellij.ui.scale.JBUIScale;
|
||||
import com.intellij.ui.tabs.JBTabPainter;
|
||||
import com.intellij.ui.tabs.JBTabsPosition;
|
||||
import com.intellij.ui.tabs.impl.singleRow.MoreTabsIcon;
|
||||
import com.intellij.ui.tabs.impl.MorePopupAware;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.BaseButtonBehavior;
|
||||
@@ -28,7 +29,7 @@ import java.awt.event.MouseEvent;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
final class TabContentLayout extends ContentLayout {
|
||||
final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
static final int MORE_ICON_BORDER = 6;
|
||||
public static final int TAB_LAYOUT_START = 4;
|
||||
LayoutData myLastLayout;
|
||||
@@ -36,13 +37,6 @@ final class TabContentLayout extends ContentLayout {
|
||||
ArrayList<ContentTabLabel> myTabs = new ArrayList<>();
|
||||
final Map<Content, ContentTabLabel> myContent2Tabs = new HashMap<>();
|
||||
|
||||
private final MoreTabsIcon myMoreIcon = new MoreTabsIcon() {
|
||||
@Override
|
||||
@Nullable
|
||||
protected Rectangle getIconRec() {
|
||||
return myLastLayout.moreRect;
|
||||
}
|
||||
};
|
||||
List<AnAction> myDoubleClickActions = new ArrayList<>();
|
||||
|
||||
TabContentLayout(ToolWindowContentUi ui) {
|
||||
@@ -52,12 +46,9 @@ final class TabContentLayout extends ContentLayout {
|
||||
@Override
|
||||
protected void execute(final MouseEvent e) {
|
||||
if (!myUi.isCurrent(TabContentLayout.this)) return;
|
||||
|
||||
if (myLastLayout != null) {
|
||||
final Rectangle moreRect = myLastLayout.moreRect;
|
||||
if (moreRect != null && moreRect.contains(e.getPoint())) {
|
||||
showPopup(e, ContainerUtil.filter(myTabs, myLastLayout.toDrop::contains));
|
||||
}
|
||||
Rectangle moreRect = getMoreRect();
|
||||
if (moreRect != null) {
|
||||
showMorePopup();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -91,10 +82,25 @@ final class TabContentLayout extends ContentLayout {
|
||||
myDoubleClickActions = ContainerUtil.newArrayList(actions);
|
||||
}
|
||||
|
||||
private static void showPopup(MouseEvent e, List<? extends ContentTabLabel> tabs) {
|
||||
private Rectangle getMoreRect() {
|
||||
if (myLastLayout == null) return null;
|
||||
return myLastLayout.moreRect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canShowMorePopup() {
|
||||
return getMoreRect() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMorePopup() {
|
||||
Rectangle rect = getMoreRect();
|
||||
if (rect == null) return;
|
||||
List<? extends ContentTabLabel> tabs = ContainerUtil.filter(myTabs, myLastLayout.toDrop::contains);
|
||||
final List<Content> contentsToShow = ContainerUtil.map(tabs, ContentTabLabel::getContent);
|
||||
final SelectContentStep step = new SelectContentStep(contentsToShow);
|
||||
JBPopupFactory.getInstance().createListPopup(step).show(new RelativePoint(e));
|
||||
RelativePoint point = new RelativePoint(myUi, new Point(rect.x, rect.y + rect.height));
|
||||
JBPopupFactory.getInstance().createListPopup(step).show(point);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -140,7 +146,6 @@ final class TabContentLayout extends ContentLayout {
|
||||
}
|
||||
|
||||
|
||||
data.moreRectWidth = calcMoreIconWidth();
|
||||
data.toFitWidth = bounds.getSize().width - data.eachX;
|
||||
|
||||
final ContentTabLabel selectedTab = myContent2Tabs.get(selected);
|
||||
@@ -170,7 +175,7 @@ final class TabContentLayout extends ContentLayout {
|
||||
}
|
||||
else {
|
||||
if (!reachedBounds) {
|
||||
final int width = bounds.width - data.eachX - data.moreRectWidth;
|
||||
final int width = bounds.width - data.eachX;
|
||||
each.setBounds(data.eachX, data.eachY, width, bounds.height - data.eachY);
|
||||
data.eachX += width;
|
||||
}
|
||||
@@ -185,23 +190,23 @@ final class TabContentLayout extends ContentLayout {
|
||||
each.setBounds(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
boolean toolbarUpdateNeeded;
|
||||
if (data.toDrop.size() > 0) {
|
||||
data.moreRect = new Rectangle(data.eachX + MORE_ICON_BORDER, 0, myMoreIcon.getIconWidth(), bounds.height);
|
||||
myMoreIcon.updateCounter(data.toDrop.size());
|
||||
toolbarUpdateNeeded = myLastLayout != null && myLastLayout.moreRect == null;
|
||||
data.moreRect = new Rectangle(data.eachX + MORE_ICON_BORDER, 0, /*getMoreToolbarWidth()*/16, bounds.height);
|
||||
}
|
||||
else {
|
||||
toolbarUpdateNeeded = myLastLayout != null && myLastLayout.moreRect != null;
|
||||
data.moreRect = null;
|
||||
}
|
||||
|
||||
final Rectangle moreRect = data.moreRect == null ? null : new Rectangle(data.eachX, 0, myMoreIcon.getIconWidth()+MORE_ICON_BORDER, bounds.height);
|
||||
final Rectangle moreRect = data.moreRect == null ? null : new Rectangle(data.eachX, 0, /*getMoreToolbarWidth()*/16+MORE_ICON_BORDER, bounds.height);
|
||||
|
||||
myUi.isResizableArea = p -> moreRect == null || !moreRect.contains(p);
|
||||
myLastLayout = data;
|
||||
}
|
||||
|
||||
private int calcMoreIconWidth() {
|
||||
return myMoreIcon.getIconWidth() + MORE_ICON_BORDER * TAB_ARC;
|
||||
if (toolbarUpdateNeeded) {
|
||||
ActionToolbarImpl.updateAllToolbarsImmediately();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -221,7 +226,7 @@ final class TabContentLayout extends ContentLayout {
|
||||
selected = contentManager.getContents()[0];
|
||||
}
|
||||
|
||||
result += selected != null ? myContent2Tabs.get(selected).getMinimumSize().width + (myTabs.size() > 1 ? calcMoreIconWidth() : 0) : 0;
|
||||
result += selected != null ? myContent2Tabs.get(selected).getMinimumSize().width : 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -229,9 +234,6 @@ final class TabContentLayout extends ContentLayout {
|
||||
static void dropTab(final LayoutData data, final ContentTabLabel toDropLabel) {
|
||||
data.requiredWidth -= (toDropLabel.getPreferredSize().width + 1);
|
||||
data.toDrop.add(toDropLabel);
|
||||
if (data.toDrop.size() == 1) {
|
||||
data.toFitWidth -= data.moreRectWidth;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isToDrawTabs() {
|
||||
@@ -251,8 +253,6 @@ final class TabContentLayout extends ContentLayout {
|
||||
Dimension layoutSize;
|
||||
boolean fullLayout = true;
|
||||
|
||||
int moreRectWidth;
|
||||
|
||||
ArrayList<ContentTabLabel> toLayout = new ArrayList<>();
|
||||
Collection<ContentTabLabel> toDrop = new HashSet<>();
|
||||
|
||||
@@ -295,10 +295,6 @@ final class TabContentLayout extends ContentLayout {
|
||||
@Override
|
||||
public void paintChildren(Graphics g) {
|
||||
if (!isToDrawTabs()) return;
|
||||
|
||||
if (myLastLayout != null && myLastLayout.moreRect != null) {
|
||||
myMoreIcon.paintIcon(myUi, g);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
@@ -24,6 +24,7 @@ import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.ui.content.*;
|
||||
import com.intellij.ui.content.tabs.PinToolwindowTabAction;
|
||||
import com.intellij.ui.content.tabs.TabbedContentAction;
|
||||
import com.intellij.ui.tabs.impl.MorePopupAware;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ContentUtilEx;
|
||||
import com.intellij.util.containers.JBIterable;
|
||||
@@ -621,6 +622,9 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data
|
||||
}
|
||||
else if (CloseAction.CloseTarget.KEY.is(dataId)) {
|
||||
return computeCloseTarget();
|
||||
} else if (MorePopupAware.KEY.is(dataId)) {
|
||||
ContentLayout layout = getCurrentLayout();
|
||||
return (layout instanceof TabContentLayout) ? layout : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user