mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
forbid calling ensureContentInitialized explicitly, reduce usages of isActive
GitOrigin-RevId: 9f446f83a81e5d750d6344cae1a45f0ac8033b6f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d0ac9c47aa
commit
fff4e71169
+5
-18
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.openapi.externalSystem.util;
|
||||
|
||||
import com.intellij.build.*;
|
||||
@@ -86,7 +86,6 @@ import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
|
||||
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
|
||||
import com.intellij.openapi.wm.impl.ToolWindowImpl;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.pom.NonNavigatable;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -107,10 +106,7 @@ import java.util.function.Supplier;
|
||||
import static com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings.SyncType.*;
|
||||
import static com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.doWriteAction;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
*/
|
||||
public class ExternalSystemUtil {
|
||||
public final class ExternalSystemUtil {
|
||||
private static final Logger LOG = Logger.getInstance(ExternalSystemUtil.class);
|
||||
|
||||
@NotNull private static final Map<String, String> RUNNER_IDS = new HashMap<>();
|
||||
@@ -185,16 +181,7 @@ public class ExternalSystemUtil {
|
||||
|
||||
@Nullable
|
||||
public static ToolWindow ensureToolWindowContentInitialized(@NotNull Project project, @NotNull ProjectSystemId externalSystemId) {
|
||||
final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project);
|
||||
if (toolWindowManager == null) return null;
|
||||
|
||||
final ToolWindow toolWindow = toolWindowManager.getToolWindow(externalSystemId.getReadableName());
|
||||
if (toolWindow == null) return null;
|
||||
|
||||
if (toolWindow instanceof ToolWindowImpl) {
|
||||
((ToolWindowImpl)toolWindow).ensureContentInitialized();
|
||||
}
|
||||
return toolWindow;
|
||||
return ToolWindowManager.getInstance(project).getToolWindow(externalSystemId.getReadableName());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,9 +269,9 @@ public class ExternalSystemUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
private static String extractDetails(@NotNull Throwable e) {
|
||||
final Throwable unwrapped = RemoteUtil.unwrap(e);
|
||||
Throwable unwrapped = RemoteUtil.unwrap(e);
|
||||
if (unwrapped instanceof ExternalSystemException) {
|
||||
return ((ExternalSystemException)unwrapped).getOriginalReason();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.openapi.ui;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
@@ -474,18 +474,15 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
*
|
||||
*/
|
||||
public void setFirstComponent(@Nullable JComponent component) {
|
||||
if (myFirstComponent != component) {
|
||||
if (myFirstComponent != null) {
|
||||
remove(myFirstComponent);
|
||||
}
|
||||
myFirstComponent = component;
|
||||
updateComponentTreeUI(myFirstComponent);
|
||||
|
||||
if (myFirstComponent != null) {
|
||||
add(myFirstComponent);
|
||||
myFirstComponent.invalidate();
|
||||
}
|
||||
if (myFirstComponent == component) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (myFirstComponent != null) {
|
||||
remove(myFirstComponent);
|
||||
}
|
||||
myFirstComponent = component;
|
||||
doAddComponent(component);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -493,25 +490,20 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
return myLastComponent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets component which is located as the "second" split area. The method doesn't validate and
|
||||
* repaint the splitter.
|
||||
*
|
||||
*/
|
||||
public void setLastComponent(@Nullable JComponent component) {
|
||||
if (myLastComponent != component) {
|
||||
if (myLastComponent != null) {
|
||||
remove(myLastComponent);
|
||||
}
|
||||
myLastComponent = component;
|
||||
updateComponentTreeUI(myLastComponent);
|
||||
|
||||
if (myLastComponent != null) {
|
||||
add(myLastComponent);
|
||||
myLastComponent.invalidate();
|
||||
}
|
||||
if (myLastComponent == component) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (myLastComponent != null) {
|
||||
remove(myLastComponent);
|
||||
}
|
||||
myLastComponent = component;
|
||||
doAddComponent(component);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -519,10 +511,12 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
return myInnerComponent;
|
||||
}
|
||||
|
||||
private static void updateComponentTreeUI(@Nullable JComponent component) {
|
||||
UIUtil.uiTraverser(component).postOrderDfsTraversal().
|
||||
filter(c -> c instanceof JComponent).
|
||||
forEach(c -> ((JComponent)c).updateUI());
|
||||
private static void updateComponentTreeUI(@Nullable JComponent rootComponent) {
|
||||
for (Component component : UIUtil.uiTraverser(rootComponent).postOrderDfsTraversal()) {
|
||||
if (component instanceof JComponent) {
|
||||
((JComponent)component).updateUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -537,13 +531,15 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
if (myInnerComponent != null) {
|
||||
remove(myInnerComponent);
|
||||
}
|
||||
|
||||
myInnerComponent = component;
|
||||
updateComponentTreeUI(myInnerComponent);
|
||||
doAddComponent(component);
|
||||
}
|
||||
|
||||
if (myInnerComponent != null) {
|
||||
add(myInnerComponent);
|
||||
myInnerComponent.invalidate();
|
||||
private void doAddComponent(@Nullable JComponent component) {
|
||||
if (component != null) {
|
||||
updateComponentTreeUI(component);
|
||||
add(component);
|
||||
component.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,11 +633,6 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
}
|
||||
private void _processMouseMotionEvent(MouseEvent e) {
|
||||
MouseEvent event = getTargetEvent(e);
|
||||
if (event == null) {
|
||||
myGlassPane.setCursor(null, myListener);
|
||||
return;
|
||||
}
|
||||
|
||||
processMouseMotionEvent(event);
|
||||
if (event.isConsumed()) {
|
||||
e.consume();
|
||||
@@ -650,11 +641,6 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
|
||||
private void _processMouseEvent(MouseEvent e) {
|
||||
MouseEvent event = getTargetEvent(e);
|
||||
if (event == null) {
|
||||
myGlassPane.setCursor(null, myListener);
|
||||
return;
|
||||
}
|
||||
|
||||
processMouseEvent(event);
|
||||
if (event.isConsumed()) {
|
||||
e.consume();
|
||||
@@ -664,7 +650,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
|
||||
private final MouseAdapter myListener = new MyMouseAdapter();
|
||||
|
||||
private MouseEvent getTargetEvent(MouseEvent e) {
|
||||
private MouseEvent getTargetEvent(@NotNull MouseEvent e) {
|
||||
return SwingUtilities.convertMouseEvent(e.getComponent(), e, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.content;
|
||||
|
||||
import com.intellij.ide.dnd.DnDTarget;
|
||||
@@ -50,17 +50,16 @@ public interface Content extends UserDataHolder, ComponentContainer {
|
||||
void setTabName(String tabName);
|
||||
String getTabName();
|
||||
|
||||
void setToolwindowTitle(String toolwindowTitle);
|
||||
String getToolwindowTitle();
|
||||
|
||||
void setToolwindowTitle(String toolwindowTitle);
|
||||
|
||||
Disposable getDisposer();
|
||||
|
||||
void setDisposer(@NotNull Disposable disposer);
|
||||
|
||||
void setShouldDisposeContent(boolean value);
|
||||
|
||||
boolean shouldDisposeContent();
|
||||
|
||||
String getDescription();
|
||||
void setDescription(String description);
|
||||
|
||||
|
||||
@@ -7,18 +7,17 @@ import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.ui.Queryable;
|
||||
import com.intellij.openapi.ui.Splitter;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.*;
|
||||
import com.intellij.openapi.wm.impl.content.ToolWindowContentUi;
|
||||
import com.intellij.ui.ComponentWithMnemonics;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentManager;
|
||||
import com.intellij.ui.paint.LinePainter2D;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -41,30 +40,43 @@ import java.util.Map;
|
||||
*/
|
||||
public final class InternalDecorator extends JPanel implements Queryable, DataProvider, ComponentWithMnemonics {
|
||||
private final ToolWindowImpl toolWindow;
|
||||
private final MyDivider myDivider;
|
||||
private final JPanel divider;
|
||||
private IdeGlassPane glassPane;
|
||||
|
||||
private Disposable disposable;
|
||||
private final MouseAdapter myListener = new MyMouseListener();
|
||||
private boolean isDragging;
|
||||
|
||||
/**
|
||||
* Catches all event from tool window and modifies decorator's appearance.
|
||||
*/
|
||||
static final String HIDE_ACTIVE_WINDOW_ACTION_ID = "HideActiveWindow";
|
||||
|
||||
//See ToolWindowViewModeAction and ToolWindowMoveAction
|
||||
// see ToolWindowViewModeAction and ToolWindowMoveAction
|
||||
public static final String TOGGLE_DOCK_MODE_ACTION_ID = "ToggleDockMode";
|
||||
public static final String TOGGLE_FLOATING_MODE_ACTION_ID = "ToggleFloatingMode";
|
||||
public static final String TOGGLE_SIDE_MODE_ACTION_ID = "ToggleSideMode";
|
||||
|
||||
private final ToolWindowHeader header;
|
||||
|
||||
InternalDecorator(@NotNull ToolWindowImpl toolWindow) {
|
||||
InternalDecorator(@NotNull ToolWindowImpl toolWindow, @NotNull ToolWindowContentUi contentUi) {
|
||||
super(new BorderLayout());
|
||||
|
||||
this.toolWindow = toolWindow;
|
||||
myDivider = new MyDivider();
|
||||
divider = new JPanel() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Cursor getCursor() {
|
||||
WindowInfo info = InternalDecorator.this.toolWindow.getWindowInfo();
|
||||
boolean isVerticalCursor = info.getType() == ToolWindowType.DOCKED ? info.getAnchor().isSplitVertically() : info.getAnchor().isHorizontal();
|
||||
return isVerticalCursor ? Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR) : Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
|
||||
}
|
||||
};
|
||||
|
||||
setFocusable(false);
|
||||
setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
|
||||
|
||||
header = new ToolWindowHeader(toolWindow, () -> toolWindow.createPopupGroup(true)) {
|
||||
header = new ToolWindowHeader(toolWindow, contentUi, () -> toolWindow.createPopupGroup(true)) {
|
||||
@Override
|
||||
protected boolean isActive() {
|
||||
return toolWindow.isActive();
|
||||
@@ -83,6 +95,8 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
if (SystemInfo.isMac) {
|
||||
setBackground(new JBColor(Gray._200, Gray._90));
|
||||
}
|
||||
|
||||
setBorder(new InnerPanelBorder(toolWindow));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -90,38 +104,22 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
return toolWindow.getId();
|
||||
}
|
||||
|
||||
public boolean isFocused(@NotNull JFrame frame) {
|
||||
IdeFocusManager focusManager = toolWindow.getToolWindowManager().getFocusManager();
|
||||
JComponent toolWindowComponent = toolWindow.getComponentIfInitialized();
|
||||
if (toolWindowComponent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Component component = focusManager.getFocusedDescendantFor(toolWindowComponent);
|
||||
if (component != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Component owner = focusManager.getLastFocusedFor(frame);
|
||||
return owner != null && SwingUtilities.isDescendingFrom(owner, toolWindowComponent);
|
||||
}
|
||||
|
||||
void applyWindowInfo(@NotNull WindowInfo info) {
|
||||
// Anchor
|
||||
ToolWindowAnchor anchor = info.getAnchor();
|
||||
if (info.isSliding()) {
|
||||
myDivider.invalidate();
|
||||
if (ToolWindowAnchor.TOP == anchor) {
|
||||
add(myDivider, BorderLayout.SOUTH);
|
||||
divider.invalidate();
|
||||
if (anchor == ToolWindowAnchor.TOP) {
|
||||
add(divider, BorderLayout.SOUTH);
|
||||
}
|
||||
else if (ToolWindowAnchor.LEFT == anchor) {
|
||||
add(myDivider, BorderLayout.EAST);
|
||||
else if (anchor == ToolWindowAnchor.LEFT) {
|
||||
add(divider, BorderLayout.EAST);
|
||||
}
|
||||
else if (ToolWindowAnchor.BOTTOM == anchor) {
|
||||
add(myDivider, BorderLayout.NORTH);
|
||||
else if (anchor == ToolWindowAnchor.BOTTOM) {
|
||||
add(divider, BorderLayout.NORTH);
|
||||
}
|
||||
else if (ToolWindowAnchor.RIGHT == anchor) {
|
||||
add(myDivider, BorderLayout.WEST);
|
||||
else if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
add(divider, BorderLayout.WEST);
|
||||
}
|
||||
divider.setPreferredSize(new Dimension(0, 0));
|
||||
}
|
||||
@@ -130,9 +128,6 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
remove(divider);
|
||||
}
|
||||
|
||||
validate();
|
||||
repaint();
|
||||
|
||||
// push "apply" request forward
|
||||
if (info.isFloating()) {
|
||||
FloatingDecorator floatingDecorator = (FloatingDecorator)SwingUtilities.getAncestorOfClass(FloatingDecorator.class, this);
|
||||
@@ -140,9 +135,6 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
floatingDecorator.apply(info);
|
||||
}
|
||||
}
|
||||
|
||||
toolWindow.getContentUI().setType(info.getContentUiType());
|
||||
setBorder(new InnerPanelBorder(toolWindow, info));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -154,14 +146,6 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
return null;
|
||||
}
|
||||
|
||||
void addContentComponent(boolean dumbAware, @NotNull ContentManager contentManager) {
|
||||
JComponent toolWindowComponent = contentManager.getComponent();
|
||||
if (!dumbAware) {
|
||||
toolWindowComponent = DumbService.getInstance(toolWindow.getToolWindowManager().getProject()).wrapGently(toolWindowComponent, toolWindow.getDisposable());
|
||||
}
|
||||
add(toolWindowComponent, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
|
||||
if (condition == WHEN_ANCESTOR_OF_FOCUSED_COMPONENT && pressed) {
|
||||
@@ -185,16 +169,13 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
private static final class InnerPanelBorder implements Border {
|
||||
@NotNull
|
||||
private final ToolWindowImpl window;
|
||||
@NotNull
|
||||
private final WindowInfo windowInfo;
|
||||
|
||||
private InnerPanelBorder(@NotNull ToolWindowImpl window, @NotNull WindowInfo windowInfo) {
|
||||
private InnerPanelBorder(@NotNull ToolWindowImpl window) {
|
||||
this.window = window;
|
||||
this.windowInfo = windowInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) {
|
||||
public void paintBorder(@NotNull Component c, @NotNull Graphics g, int x, int y, int width, int height) {
|
||||
g.setColor(JBColor.border());
|
||||
doPaintBorder(c, g, x, y, width, height);
|
||||
}
|
||||
@@ -227,6 +208,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
@Override
|
||||
public Insets getBorderInsets(@NotNull Component c) {
|
||||
ToolWindowManagerImpl toolWindowManager = window.getToolWindowManager();
|
||||
WindowInfo windowInfo = window.getWindowInfo();
|
||||
if (toolWindowManager.getProject().isDisposed() ||
|
||||
!toolWindowManager.isToolWindowRegistered(window.getId()) || windowInfo.getType() == ToolWindowType.FLOATING || windowInfo.getType() == ToolWindowType.WINDOWED) {
|
||||
return JBUI.emptyInsets();
|
||||
@@ -280,103 +262,95 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
header.setVisible(value);
|
||||
}
|
||||
|
||||
private final class MyDivider extends JPanel {
|
||||
private boolean myDragging;
|
||||
private Disposable myDisposable;
|
||||
private IdeGlassPane myGlassPane;
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
|
||||
private final MouseAdapter myListener = new MyMouseAdapter();
|
||||
glassPane = IdeGlassPaneUtil.find(this);
|
||||
disposable = Disposer.newDisposable();
|
||||
glassPane.addMouseMotionPreprocessor(myListener, disposable);
|
||||
glassPane.addMousePreprocessor(myListener, disposable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
myGlassPane = IdeGlassPaneUtil.find(this);
|
||||
myDisposable = Disposer.newDisposable();
|
||||
myGlassPane.addMouseMotionPreprocessor(myListener, myDisposable);
|
||||
myGlassPane.addMousePreprocessor(myListener, myDisposable);
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
|
||||
Disposable disposable = this.disposable;
|
||||
if (disposable != null && !Disposer.isDisposed(disposable)) {
|
||||
this.disposable = null;
|
||||
Disposer.dispose(disposable);
|
||||
}
|
||||
}
|
||||
|
||||
private final class MyMouseListener extends MouseAdapter {
|
||||
private boolean isInDragZone(@NotNull MouseEvent e) {
|
||||
Point point = new Point(e.getPoint());
|
||||
SwingUtilities.convertPointToScreen(point, e.getComponent());
|
||||
if ((toolWindow.getWindowInfo().getAnchor().isHorizontal() ? point.y : point.x) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SwingUtilities.convertPointFromScreen(point, divider);
|
||||
return Math.abs(toolWindow.getWindowInfo().getAnchor().isHorizontal() ? point.y : point.x) < 6;
|
||||
}
|
||||
|
||||
private void updateCursor(@NotNull MouseEvent event, boolean isInDragZone) {
|
||||
if (isInDragZone) {
|
||||
glassPane.setCursor(divider.getCursor(), divider);
|
||||
event.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
if (myDisposable != null && !Disposer.isDisposed(myDisposable)) {
|
||||
Disposer.dispose(myDisposable);
|
||||
}
|
||||
public void mousePressed(@NotNull MouseEvent e) {
|
||||
isDragging = isInDragZone(e);
|
||||
updateCursor(e, isDragging);
|
||||
}
|
||||
|
||||
boolean isInDragZone(MouseEvent e) {
|
||||
Point p = SwingUtilities.convertMouseEvent(e.getComponent(), e, this).getPoint();
|
||||
return Math.abs(toolWindow.getWindowInfo().getAnchor().isHorizontal() ? p.y : p.x) < 6;
|
||||
}
|
||||
|
||||
private final class MyMouseAdapter extends MouseAdapter {
|
||||
private void updateCursor(MouseEvent e) {
|
||||
if (isInDragZone(e)) {
|
||||
myGlassPane.setCursor(MyDivider.this.getCursor(), MyDivider.this);
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
myDragging = isInDragZone(e);
|
||||
updateCursor(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
updateCursor(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
updateCursor(e);
|
||||
myDragging = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
updateCursor(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
if (!myDragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
MouseEvent event = SwingUtilities.convertMouseEvent(e.getComponent(), e, MyDivider.this);
|
||||
final ToolWindowAnchor anchor = toolWindow.getAnchor();
|
||||
final Point point = event.getPoint();
|
||||
final Container windowPane = InternalDecorator.this.getParent();
|
||||
Point lastPoint = SwingUtilities.convertPoint(MyDivider.this, point, windowPane);
|
||||
lastPoint.x = Math.min(Math.max(lastPoint.x, 0), windowPane.getWidth());
|
||||
lastPoint.y = Math.min(Math.max(lastPoint.y, 0), windowPane.getHeight());
|
||||
|
||||
final Rectangle bounds = InternalDecorator.this.getBounds();
|
||||
if (anchor == ToolWindowAnchor.TOP) {
|
||||
InternalDecorator.this.setBounds(0, 0, bounds.width, lastPoint.y);
|
||||
}
|
||||
else if (anchor == ToolWindowAnchor.LEFT) {
|
||||
InternalDecorator.this.setBounds(0, 0, lastPoint.x, bounds.height);
|
||||
}
|
||||
else if (anchor == ToolWindowAnchor.BOTTOM) {
|
||||
InternalDecorator.this.setBounds(0, lastPoint.y, bounds.width, windowPane.getHeight() - lastPoint.y);
|
||||
}
|
||||
else if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
InternalDecorator.this.setBounds(lastPoint.x, 0, windowPane.getWidth() - lastPoint.x, bounds.height);
|
||||
}
|
||||
InternalDecorator.this.validate();
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Cursor getCursor() {
|
||||
WindowInfo info = toolWindow.getWindowInfo();
|
||||
boolean isVerticalCursor = info.getType() == ToolWindowType.DOCKED ? info.getAnchor().isSplitVertically() : info.getAnchor().isHorizontal();
|
||||
return isVerticalCursor ? Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR) : Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
|
||||
public void mouseClicked(@NotNull MouseEvent e) {
|
||||
updateCursor(e, isInDragZone(e));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(@NotNull MouseEvent e) {
|
||||
updateCursor(e, isInDragZone(e));
|
||||
isDragging = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(@NotNull MouseEvent e) {
|
||||
updateCursor(e, isDragging || isInDragZone(e));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(@NotNull MouseEvent e) {
|
||||
if (!isDragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
ToolWindowAnchor anchor = toolWindow.getAnchor();
|
||||
Container windowPane = InternalDecorator.this.getParent();
|
||||
Point lastPoint = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), windowPane);
|
||||
lastPoint.x = Math.min(Math.max(lastPoint.x, 0), windowPane.getWidth());
|
||||
lastPoint.y = Math.min(Math.max(lastPoint.y, 0), windowPane.getHeight());
|
||||
|
||||
Rectangle bounds = InternalDecorator.this.getBounds();
|
||||
if (anchor == ToolWindowAnchor.TOP) {
|
||||
InternalDecorator.this.setBounds(0, 0, bounds.width, lastPoint.y);
|
||||
}
|
||||
else if (anchor == ToolWindowAnchor.LEFT) {
|
||||
InternalDecorator.this.setBounds(0, 0, lastPoint.x, bounds.height);
|
||||
}
|
||||
else if (anchor == ToolWindowAnchor.BOTTOM) {
|
||||
InternalDecorator.this.setBounds(0, lastPoint.y, bounds.width, windowPane.getHeight() - lastPoint.y);
|
||||
}
|
||||
else if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
InternalDecorator.this.setBounds(lastPoint.x, 0, windowPane.getWidth() - lastPoint.x, bounds.height);
|
||||
}
|
||||
InternalDecorator.this.validate();
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,7 +358,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
public void putInfo(@NotNull Map<String, String> info) {
|
||||
info.put("toolWindowTitle", toolWindow.getTitle());
|
||||
|
||||
final Content selection = toolWindow.getContentManager().getSelectedContent();
|
||||
Content selection = toolWindow.getContentManager().getSelectedContent();
|
||||
if (selection != null) {
|
||||
info.put("toolWindowTab", selection.getTabName());
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.openapi.wm.impl;
|
||||
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
@@ -313,7 +313,7 @@ public final class StripeButton extends AnchoredButton implements DataProvider {
|
||||
}
|
||||
|
||||
void apply(@NotNull WindowInfo info) {
|
||||
setSelected(info.isVisible() || info.isActive());
|
||||
setSelected(info.isVisible());
|
||||
updateState(toolWindow);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.openapi.wm.impl;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
@@ -13,12 +13,14 @@ import com.intellij.openapi.wm.impl.content.ToolWindowContentUi;
|
||||
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.layout.migLayout.MigLayoutBuilderKt;
|
||||
import com.intellij.ui.layout.migLayout.patched.MigLayout;
|
||||
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 net.miginfocom.layout.CC;
|
||||
import net.miginfocom.layout.ConstraintParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -35,6 +37,7 @@ import java.util.function.Supplier;
|
||||
* @author pegov
|
||||
*/
|
||||
public abstract class ToolWindowHeader extends JPanel implements UISettingsListener, DataProvider {
|
||||
@NotNull private final ToolWindowContentUi contentUi;
|
||||
@NotNull private final Supplier<? extends ActionGroup> myGearProducer;
|
||||
|
||||
@NotNull
|
||||
@@ -50,20 +53,19 @@ public abstract class ToolWindowHeader extends JPanel implements UISettingsListe
|
||||
private ActionToolbar myToolbarWest;
|
||||
private final JPanel myWestPanel;
|
||||
|
||||
ToolWindowHeader(@NotNull ToolWindowImpl toolWindow, @NotNull Supplier<? extends ActionGroup> gearProducer) {
|
||||
ToolWindowHeader(@NotNull ToolWindowImpl toolWindow, @NotNull ToolWindowContentUi contentUi, @NotNull Supplier<? extends ActionGroup> gearProducer) {
|
||||
super(new MigLayout(MigLayoutBuilderKt.createLayoutConstraints(0, 0).noVisualPadding().fill(), ConstraintParser.parseColumnConstraints("[grow][pref!]")));
|
||||
|
||||
this.contentUi = contentUi;
|
||||
myGearProducer = gearProducer;
|
||||
|
||||
AccessibleContextUtil.setName(this, "Tool Window Header");
|
||||
|
||||
myToolWindow = toolWindow;
|
||||
|
||||
setLayout(new MigLayout("novisualpadding, ins 0, gap 0, fill", "[grow][pref!]"));
|
||||
myWestPanel = new NonOpaquePanel(new MigLayout("filly, novisualpadding, ins 0, gap 0"));
|
||||
|
||||
add(myWestPanel, "grow");
|
||||
myWestPanel.add(toolWindow.getContentUI().getTabComponent(), "growy");
|
||||
|
||||
ToolWindowContentUi.initMouseListeners(myWestPanel, toolWindow.getContentUI(), true);
|
||||
myWestPanel = contentUi.getTabComponent();
|
||||
add(myWestPanel, new CC().grow());
|
||||
ToolWindowContentUi.initMouseListeners(myWestPanel, contentUi, true);
|
||||
|
||||
ActionManager actionManager = ActionManager.getInstance();
|
||||
AnAction tabListAction = actionManager.getAction("TabList");
|
||||
@@ -83,8 +85,7 @@ public abstract class ToolWindowHeader extends JPanel implements UISettingsListe
|
||||
myWestPanel.addMouseListener(new PopupHandler() {
|
||||
@Override
|
||||
public void invokePopup(final Component comp, final int x, final int y) {
|
||||
toolWindow.getContentUI()
|
||||
.showContextMenu(comp, x, y, toolWindow.getPopupGroup(), toolWindow.getContentManager().getSelectedContent());
|
||||
contentUi.showContextMenu(comp, x, y, toolWindow.getPopupGroup(), contentUi.getContentManager().getSelectedContent());
|
||||
}
|
||||
});
|
||||
myWestPanel.addMouseListener(new MouseAdapter() {
|
||||
@@ -139,7 +140,7 @@ public abstract class ToolWindowHeader extends JPanel implements UISettingsListe
|
||||
@Override
|
||||
public Object getData(@NotNull String dataId) {
|
||||
if (MorePopupAware.KEY.is(dataId) && myToolWindow instanceof ToolWindowImpl) {
|
||||
return ((ToolWindowImpl)myToolWindow).getContentUI().getData(dataId);
|
||||
return contentUi.getData(dataId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.openapi.wm.impl
|
||||
|
||||
import com.intellij.icons.AllIcons
|
||||
@@ -10,10 +10,10 @@ import com.intellij.notification.EventLog
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.actionSystem.*
|
||||
import com.intellij.openapi.actionSystem.ex.ActionUtil
|
||||
import com.intellij.openapi.actionSystem.impl.ActionManagerImpl
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.util.ActionCallback
|
||||
import com.intellij.openapi.util.BusyObject
|
||||
import com.intellij.openapi.util.Disposer
|
||||
@@ -22,18 +22,22 @@ import com.intellij.openapi.wm.ex.ToolWindowEx
|
||||
import com.intellij.openapi.wm.impl.content.ToolWindowContentUi
|
||||
import com.intellij.ui.LayeredIcon
|
||||
import com.intellij.ui.UIBundle
|
||||
import com.intellij.ui.content.Content
|
||||
import com.intellij.ui.content.ContentManager
|
||||
import com.intellij.ui.content.ContentManagerListener
|
||||
import com.intellij.ui.content.impl.ContentImpl
|
||||
import com.intellij.ui.content.impl.ContentManagerImpl
|
||||
import com.intellij.ui.scale.JBUIScale
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import com.intellij.util.ui.update.Activatable
|
||||
import com.intellij.util.ui.update.UiNotifyConnector
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Component
|
||||
import java.awt.Rectangle
|
||||
import java.awt.event.ComponentAdapter
|
||||
import java.awt.event.ComponentEvent
|
||||
import java.awt.event.InputEvent
|
||||
import java.util.*
|
||||
import javax.swing.Icon
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JLabel
|
||||
@@ -45,7 +49,7 @@ private val LOG = logger<ToolWindowImpl>()
|
||||
class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManagerImpl,
|
||||
val id: String,
|
||||
private val canCloseContent: Boolean,
|
||||
private val canWorkInDumbMode: Boolean,
|
||||
private val dumbAware: Boolean,
|
||||
component: JComponent?,
|
||||
private val parentDisposable: Disposable,
|
||||
windowInfo: WindowInfo,
|
||||
@@ -56,16 +60,14 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
var windowInfo: WindowInfo = windowInfo
|
||||
private set
|
||||
|
||||
private val contentUi by lazy {
|
||||
ToolWindowContentUi(this)
|
||||
}
|
||||
private var contentUi: ToolWindowContentUi? = null
|
||||
|
||||
private var decorator: InternalDecorator? = null
|
||||
|
||||
private var hideOnEmptyContent = false
|
||||
var isPlaceholderMode = false
|
||||
|
||||
private val pendingContentManagerListeners: List<ContentManagerListener>? = null
|
||||
private var pendingContentManagerListeners: MutableList<ContentManagerListener>? = null
|
||||
|
||||
private val showing = object : BusyObject.Impl() {
|
||||
override fun isReady(): Boolean {
|
||||
@@ -82,36 +84,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
internal var icon: ToolWindowIcon? = null
|
||||
|
||||
private val contentManager = lazy {
|
||||
val contentManager = ContentManagerImpl(contentUi, canCloseContent, toolWindowManager.project, parentDisposable)
|
||||
|
||||
val contentComponent = contentManager.component
|
||||
InternalDecorator.installFocusTraversalPolicy(contentComponent, LayoutFocusTraversalPolicy())
|
||||
Disposer.register(parentDisposable, UiNotifyConnector(contentComponent, object : Activatable {
|
||||
override fun showNotify() {
|
||||
showing.onReady()
|
||||
}
|
||||
}))
|
||||
|
||||
val decorator = InternalDecorator(this)
|
||||
this.decorator = decorator
|
||||
decorator.applyWindowInfo(windowInfo)
|
||||
decorator.addComponentListener(object : ComponentAdapter() {
|
||||
override fun componentResized(e: ComponentEvent) {
|
||||
toolWindowManager.resized(e.component as InternalDecorator)
|
||||
}
|
||||
})
|
||||
decorator.addContentComponent(canWorkInDumbMode, contentManager)
|
||||
|
||||
toolWindowFocusWatcher = ToolWindowManagerImpl.ToolWindowFocusWatcher(this, contentManager.component)
|
||||
|
||||
// after init, as it was before contentManager creation was changed to be lazy
|
||||
pendingContentManagerListeners?.let { list ->
|
||||
for (listener in list) {
|
||||
contentManager.addContentManagerListener(listener)
|
||||
}
|
||||
}
|
||||
|
||||
contentManager
|
||||
createContentManager()
|
||||
}
|
||||
|
||||
init {
|
||||
@@ -123,13 +96,67 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
}
|
||||
}
|
||||
|
||||
internal fun getOrCreateDecoratorComponent(): JComponent {
|
||||
ensureContentManagerInitialized()
|
||||
return decorator!!
|
||||
}
|
||||
|
||||
private fun createContentManager(): ContentManagerImpl {
|
||||
val contentUi = ToolWindowContentUi(this, windowInfo.contentUiType)
|
||||
this.contentUi = contentUi
|
||||
val contentManager = ContentManagerImpl(contentUi, canCloseContent, toolWindowManager.project, parentDisposable)
|
||||
|
||||
addContentNotInHierarchyComponents(contentUi)
|
||||
|
||||
val contentComponent = contentManager.component
|
||||
InternalDecorator.installFocusTraversalPolicy(contentComponent, LayoutFocusTraversalPolicy())
|
||||
Disposer.register(parentDisposable, UiNotifyConnector(contentComponent, object : Activatable {
|
||||
override fun showNotify() {
|
||||
showing.onReady()
|
||||
}
|
||||
}))
|
||||
|
||||
val decorator = InternalDecorator(this, contentUi)
|
||||
this.decorator = decorator
|
||||
|
||||
var decoratorChild = contentManager.component
|
||||
if (!dumbAware) {
|
||||
decoratorChild = DumbService.getInstance(toolWindowManager.project).wrapGently(decoratorChild, parentDisposable)
|
||||
}
|
||||
decorator.add(decoratorChild, BorderLayout.CENTER)
|
||||
decorator.applyWindowInfo(windowInfo)
|
||||
decorator.addComponentListener(object : ComponentAdapter() {
|
||||
override fun componentResized(e: ComponentEvent) {
|
||||
toolWindowManager.resized(e.component as InternalDecorator)
|
||||
}
|
||||
})
|
||||
|
||||
toolWindowFocusWatcher = ToolWindowManagerImpl.ToolWindowFocusWatcher(this, contentComponent)
|
||||
|
||||
// after init, as it was before contentManager creation was changed to be lazy
|
||||
pendingContentManagerListeners?.let { list ->
|
||||
pendingContentManagerListeners = null
|
||||
for (listener in list) {
|
||||
contentManager.addContentManagerListener(listener)
|
||||
}
|
||||
}
|
||||
|
||||
return contentManager
|
||||
}
|
||||
|
||||
internal fun applyWindowInfo(info: WindowInfo) {
|
||||
if (windowInfo == info) {
|
||||
return
|
||||
}
|
||||
|
||||
windowInfo = info
|
||||
decorator?.applyWindowInfo(info)
|
||||
val decorator = decorator
|
||||
contentUi?.setType(info.contentUiType)
|
||||
if (decorator != null) {
|
||||
decorator.applyWindowInfo(info)
|
||||
decorator.validate()
|
||||
decorator.repaint()
|
||||
}
|
||||
}
|
||||
|
||||
val decoratorComponent: JComponent?
|
||||
@@ -142,6 +169,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
toolWindowFocusWatcher?.setFocusedComponentImpl(component)
|
||||
}
|
||||
|
||||
@Deprecated(message = "Do not use.", level = DeprecationLevel.ERROR)
|
||||
fun getContentUI() = contentUi
|
||||
|
||||
override fun getDisposable() = parentDisposable
|
||||
@@ -164,19 +192,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
|
||||
override fun isActive(): Boolean {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread()
|
||||
val frameHelper = toolWindowManager.getFrame() ?: return false
|
||||
val frame = frameHelper.frame
|
||||
if (!frame.isActive || toolWindowManager.isEditorComponentActive) {
|
||||
return false
|
||||
}
|
||||
|
||||
val actionManager = ActionManager.getInstance()
|
||||
if (actionManager is ActionManagerImpl && !actionManager.isActionPopupStackEmpty && !actionManager.isToolWindowContextMenuVisible) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
return windowInfo.isActive || (windowInfo.isVisible && (decorator?.isFocused(frameHelper.frame) ?: false))
|
||||
}
|
||||
return windowInfo.isVisible && decorator != null && toolWindowManager.activeToolWindowId == id
|
||||
}
|
||||
|
||||
override fun getReady(requestor: Any): ActionCallback {
|
||||
@@ -262,27 +278,22 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
|
||||
override fun getDecorator() = decorator!!
|
||||
|
||||
val isFocused: Boolean
|
||||
get() {
|
||||
return decorator?.isFocused(toolWindowManager.getFrame()?.frame ?: return false) ?: false
|
||||
}
|
||||
|
||||
override fun setAdditionalGearActions(value: ActionGroup?) {
|
||||
additionalGearActions = value
|
||||
}
|
||||
|
||||
override fun setTitleActions(vararg actions: AnAction) {
|
||||
contentManager.value
|
||||
createContentIfNeeded()
|
||||
decorator!!.setTitleActions(actions)
|
||||
}
|
||||
|
||||
override fun setTabActions(vararg actions: AnAction) {
|
||||
contentManager.value
|
||||
createContentIfNeeded()
|
||||
decorator!!.setTabActions(actions)
|
||||
}
|
||||
|
||||
fun setTabDoubleClickActions(vararg actions: AnAction) {
|
||||
contentUi.setTabDoubleClickActions(*actions)
|
||||
contentUi?.setTabDoubleClickActions(*actions)
|
||||
}
|
||||
|
||||
override fun setAvailable(available: Boolean, runnable: Runnable?) {
|
||||
@@ -321,7 +332,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
}
|
||||
|
||||
override fun getContentManager(): ContentManager {
|
||||
ensureContentInitialized()
|
||||
createContentIfNeeded()
|
||||
return contentManager.value
|
||||
}
|
||||
|
||||
@@ -329,6 +340,12 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
if (contentManager.isInitialized()) {
|
||||
contentManager.value.addContentManagerListener(listener)
|
||||
}
|
||||
else {
|
||||
if (pendingContentManagerListeners == null) {
|
||||
pendingContentManagerListeners = arrayListOf()
|
||||
}
|
||||
pendingContentManagerListeners!!.add(listener)
|
||||
}
|
||||
}
|
||||
|
||||
fun canCloseContents() = canCloseContent
|
||||
@@ -414,19 +431,36 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
|
||||
override fun isDisposed() = contentManager.isInitialized() && contentManager.value.isDisposed
|
||||
|
||||
fun ensureContentInitialized() {
|
||||
val currentContentFactory = contentFactory
|
||||
if (currentContentFactory != null) {
|
||||
// clear it first to avoid SOE
|
||||
this.contentFactory = null
|
||||
if (contentManager.isInitialized()) {
|
||||
contentManager.value.removeAllContents(false)
|
||||
}
|
||||
contentManager.value
|
||||
currentContentFactory.createToolWindowContent(toolWindowManager.project, this)
|
||||
private fun ensureContentManagerInitialized() {
|
||||
contentManager.value
|
||||
}
|
||||
|
||||
internal fun scheduleContentInitializationIfNeeded() {
|
||||
if (contentFactory != null) {
|
||||
// todo use lazy loading (e.g. JBLoadingPanel)
|
||||
createContentIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DeprecatedCallableAddReplaceWith")
|
||||
@Deprecated("Do not use. Tool window content will be initialized automatically.", level = DeprecationLevel.ERROR)
|
||||
fun ensureContentInitialized() {
|
||||
createContentIfNeeded()
|
||||
}
|
||||
|
||||
internal fun createContentIfNeeded() {
|
||||
val currentContentFactory = contentFactory ?: return
|
||||
// clear it first to avoid SOE
|
||||
this.contentFactory = null
|
||||
if (contentManager.isInitialized()) {
|
||||
contentManager.value.removeAllContents(false)
|
||||
}
|
||||
else {
|
||||
ensureContentManagerInitialized()
|
||||
}
|
||||
currentContentFactory.createToolWindowContent(toolWindowManager.project, this)
|
||||
}
|
||||
|
||||
override fun getHelpId() = helpId
|
||||
|
||||
override fun setHelpId(value: String) {
|
||||
@@ -434,9 +468,8 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
}
|
||||
|
||||
override fun showContentPopup(inputEvent: InputEvent) {
|
||||
// create before access contentUi
|
||||
val contentManager = contentManager.value
|
||||
ToolWindowContentUi.toggleContentPopup(contentUi, contentManager)
|
||||
// called only when tool window is already opened, so, content should be already created
|
||||
ToolWindowContentUi.toggleContentPopup(contentUi!!, contentManager.value)
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
@@ -524,7 +557,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
private inner class ResizeActionGroup : ActionGroup(ActionsBundle.groupText("ResizeToolWindowGroup"), true), DumbAware {
|
||||
private val children by lazy<Array<AnAction>> {
|
||||
// force creation
|
||||
contentManager.value
|
||||
createContentIfNeeded()
|
||||
val component = decorator
|
||||
val toolWindow = this@ToolWindowImpl
|
||||
arrayOf(
|
||||
@@ -558,7 +591,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
hadSeveralContents = hadSeveralContents || getContentManager().contentCount > 1
|
||||
hadSeveralContents = hadSeveralContents || (contentManager.isInitialized() && contentManager.value.contentCount > 1)
|
||||
super.update(e)
|
||||
e.presentation.isVisible = hadSeveralContents
|
||||
}
|
||||
@@ -596,4 +629,31 @@ private fun addSorted(main: DefaultActionGroup, group: ActionGroup) {
|
||||
if (children.isNotEmpty() && !separatorText.isNullOrEmpty()) {
|
||||
main.addAction(Separator(separatorText), Constraints.FIRST)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addContentNotInHierarchyComponents(contentUi: ToolWindowContentUi) {
|
||||
UIUtil.putClientProperty(contentUi.component, UIUtil.NOT_IN_HIERARCHY_COMPONENTS, object : Iterable<JComponent> {
|
||||
override fun iterator(): Iterator<JComponent> {
|
||||
val contentManager = contentUi.contentManager ?: return Collections.emptyIterator()
|
||||
if (contentManager.contentCount == 0) {
|
||||
return Collections.emptyIterator()
|
||||
}
|
||||
|
||||
return contentManager.contents
|
||||
.asSequence()
|
||||
.mapNotNull { content: Content ->
|
||||
var last: JComponent? = null
|
||||
var parent: Component? = content.component
|
||||
while (parent != null) {
|
||||
if (parent === contentUi.component || parent !is JComponent) {
|
||||
return@mapNotNull null
|
||||
}
|
||||
last = parent
|
||||
parent = parent.getParent()
|
||||
}
|
||||
last
|
||||
}
|
||||
.iterator()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -50,7 +50,6 @@ import com.intellij.openapi.wm.ex.ToolWindowManagerEx
|
||||
import com.intellij.openapi.wm.ex.ToolWindowManagerListener
|
||||
import com.intellij.openapi.wm.ex.WindowManagerEx
|
||||
import com.intellij.openapi.wm.impl.commands.RequestFocusInToolWindowCommand
|
||||
import com.intellij.openapi.wm.impl.content.ToolWindowContentUi
|
||||
import com.intellij.ui.BalloonImpl
|
||||
import com.intellij.ui.ComponentUtil
|
||||
import com.intellij.ui.GuiUtils
|
||||
@@ -628,9 +627,6 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(),
|
||||
if (parent is InternalDecorator) {
|
||||
return parent.toolWindow.id
|
||||
}
|
||||
else if (parent is ToolWindowContentUi) {
|
||||
return parent.toolWindowId
|
||||
}
|
||||
|
||||
parent = parent.parent
|
||||
}
|
||||
@@ -781,7 +777,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(),
|
||||
|
||||
private fun doHide(entry: ToolWindowEntry, info: WindowInfoImpl, dirtyMode: Boolean, hideSide: Boolean = false, moveFocus: Boolean = true): Boolean {
|
||||
// info.isActive is not reliable (not set to false on focus lost)
|
||||
val wasActive = entry.toolWindow.isFocused
|
||||
val wasActive = entry.toolWindow.isActive
|
||||
|
||||
if (!wasActive && !info.isVisible) {
|
||||
return false
|
||||
@@ -862,8 +858,6 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(),
|
||||
}
|
||||
|
||||
private fun doShowWindow(entry: ToolWindowEntry, info: WindowInfo, dirtyMode: Boolean) {
|
||||
entry.toolWindow.ensureContentInitialized()
|
||||
|
||||
if (entry.readOnlyWindowInfo.type == ToolWindowType.FLOATING) {
|
||||
addFloatingDecorator(entry, info)
|
||||
}
|
||||
@@ -906,12 +900,14 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(),
|
||||
}
|
||||
}
|
||||
|
||||
toolWindowPane!!.addDecorator(entry.toolWindow.decoratorComponent!!, info, dirtyMode, this)
|
||||
toolWindowPane!!.addDecorator(entry.toolWindow.getOrCreateDecoratorComponent(), info, dirtyMode, this)
|
||||
// remove tool window from the SideStack
|
||||
if (isStackEnabled) {
|
||||
sideStack.remove(entry.id)
|
||||
}
|
||||
}
|
||||
|
||||
entry.toolWindow.scheduleContentInitializationIfNeeded()
|
||||
}
|
||||
|
||||
override fun registerToolWindow(task: RegisterToolWindowTask): ToolWindowImpl {
|
||||
@@ -1388,7 +1384,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(),
|
||||
|
||||
private fun hideIfNeededAndShowAfterTask(entry: ToolWindowEntry, info: WindowInfoImpl, task: () -> Unit) {
|
||||
val wasVisible = entry.readOnlyWindowInfo.isVisible
|
||||
val wasFocused = entry.toolWindow.isFocused
|
||||
val wasFocused = entry.toolWindow.isActive
|
||||
if (wasVisible) {
|
||||
doHide(entry, info, dirtyMode = true, moveFocus = false)
|
||||
}
|
||||
|
||||
+6
-9
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.openapi.wm.impl.content;
|
||||
|
||||
import com.intellij.openapi.ui.popup.ListPopup;
|
||||
@@ -34,7 +34,7 @@ final class ComboContentLayout extends ContentLayout {
|
||||
|
||||
@Override
|
||||
public void layout() {
|
||||
Rectangle bounds = myUi.getBounds();
|
||||
Rectangle bounds = myUi.getTabComponent().getBounds();
|
||||
Dimension idSize = isIdVisible() ? myIdLabel.getPreferredSize() : JBUI.emptySize();
|
||||
|
||||
int eachX = 0;
|
||||
@@ -70,9 +70,6 @@ final class ComboContentLayout extends ContentLayout {
|
||||
g.drawLine(r.width - 1, 0, r.width - 1, r.height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintChildren(Graphics g) { }
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
updateIdLabel(myIdLabel);
|
||||
@@ -81,17 +78,17 @@ final class ComboContentLayout extends ContentLayout {
|
||||
|
||||
@Override
|
||||
public void rebuild() {
|
||||
myUi.removeAll();
|
||||
myUi.getTabComponent().removeAll();
|
||||
|
||||
myUi.add(myIdLabel);
|
||||
myUi.getTabComponent().add(myIdLabel);
|
||||
ToolWindowContentUi.initMouseListeners(myIdLabel, myUi, true);
|
||||
|
||||
myUi.add(myComboLabel);
|
||||
myUi.getTabComponent().add(myComboLabel);
|
||||
ToolWindowContentUi.initMouseListeners(myComboLabel, myUi, false);
|
||||
}
|
||||
|
||||
boolean isToDrawCombo() {
|
||||
ContentManager manager = myUi.contentManager;
|
||||
ContentManager manager = myUi.getContentManager();
|
||||
return manager != null && manager.getContentCount() > 1;
|
||||
}
|
||||
|
||||
|
||||
+7
-5
@@ -1,8 +1,9 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.openapi.wm.impl.content;
|
||||
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentManager;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.accessibility.ScreenReader;
|
||||
@@ -44,7 +45,7 @@ final class ContentComboLabel extends BaseLabel {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getModifiers() == 0 && e.getKeyCode() == KeyEvent.VK_SPACE) {
|
||||
ToolWindowContentUi.toggleContentPopup(myUi, myUi.contentManager);
|
||||
ToolWindowContentUi.toggleContentPopup(myUi, myUi.getContentManager());
|
||||
}
|
||||
super.keyPressed(e);
|
||||
}
|
||||
@@ -57,7 +58,7 @@ final class ContentComboLabel extends BaseLabel {
|
||||
super.processMouseEvent(e);
|
||||
|
||||
if (UIUtil.isActionClick(e)) {
|
||||
ToolWindowContentUi.toggleContentPopup(myUi, myUi.contentManager);
|
||||
ToolWindowContentUi.toggleContentPopup(myUi, myUi.getContentManager());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +110,8 @@ final class ContentComboLabel extends BaseLabel {
|
||||
@Nullable
|
||||
@Override
|
||||
public Content getContent() {
|
||||
return myUi.contentManager == null ? null : myUi.contentManager.getSelectedContent();
|
||||
ContentManager contentManager = myUi.getContentManager();
|
||||
return contentManager == null ? null : contentManager.getSelectedContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,7 +147,7 @@ final class ContentComboLabel extends BaseLabel {
|
||||
@Override
|
||||
public boolean doAccessibleAction(int index) {
|
||||
if (index == 0) {
|
||||
ToolWindowContentUi.toggleContentPopup(myUi, myUi.contentManager);
|
||||
ToolWindowContentUi.toggleContentPopup(myUi, myUi.getContentManager());
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.openapi.wm.impl.content;
|
||||
|
||||
import com.intellij.openapi.ui.popup.ListPopup;
|
||||
@@ -13,8 +13,6 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
abstract class ContentLayout {
|
||||
static final int TAB_ARC = 2;
|
||||
|
||||
ToolWindowContentUi myUi;
|
||||
BaseLabel myIdLabel;
|
||||
|
||||
@@ -30,8 +28,6 @@ abstract class ContentLayout {
|
||||
|
||||
public abstract void paintComponent(Graphics g);
|
||||
|
||||
public abstract void paintChildren(Graphics g);
|
||||
|
||||
public abstract void update();
|
||||
|
||||
public abstract void rebuild();
|
||||
@@ -54,7 +50,7 @@ abstract class ContentLayout {
|
||||
}
|
||||
|
||||
private String getTitleSuffix() {
|
||||
ContentManager manager = myUi.contentManager;
|
||||
ContentManager manager = myUi.getContentManager();
|
||||
switch (manager == null ? 0 : manager.getContentCount()) {
|
||||
case 0:
|
||||
return null;
|
||||
|
||||
+9
-15
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.openapi.wm.impl.content;
|
||||
|
||||
import com.intellij.ide.DataManager;
|
||||
@@ -23,7 +23,6 @@ import com.intellij.util.ui.TimedDeadzone;
|
||||
import com.intellij.util.ui.UIUtilities;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
@@ -105,7 +104,6 @@ class ContentTabLabel extends BaseLabel {
|
||||
}
|
||||
|
||||
String toolText = icon.getTooltip();
|
||||
|
||||
if (toolText != null && !toolText.isEmpty()) {
|
||||
IdeTooltip tooltip = new IdeTooltip(this, icon.getCenterPoint(), new JLabel(toolText));
|
||||
currentIconTooltip = new CurrentTooltip(IdeTooltipManager.getInstance().show(tooltip, false, false), icon);
|
||||
@@ -118,7 +116,6 @@ class ContentTabLabel extends BaseLabel {
|
||||
IdeTooltip tooltip = new IdeTooltip(this, getMousePosition(), new JLabel(myText));
|
||||
currentIconTooltip = new CurrentTooltip(IdeTooltipManager.getInstance().show(tooltip, false, false), null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void hideCurrentTooltip() {
|
||||
@@ -130,15 +127,12 @@ class ContentTabLabel extends BaseLabel {
|
||||
|
||||
private final BaseButtonBehavior behavior = new BaseButtonBehavior(this) {
|
||||
@Override
|
||||
protected void execute(final MouseEvent e) {
|
||||
|
||||
Optional<Runnable> first = myAdditionalIcons.stream()
|
||||
.filter(icon -> mouseOverIcon(icon))
|
||||
.map(icon -> icon.getAction()).findFirst();
|
||||
|
||||
if (first.isPresent()) {
|
||||
first.get().run();
|
||||
return;
|
||||
protected void execute(@NotNull MouseEvent e) {
|
||||
for (AdditionalIcon icon : myAdditionalIcons) {
|
||||
if (mouseOverIcon(icon)) {
|
||||
icon.getAction().run();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
selectContent();
|
||||
@@ -358,10 +352,10 @@ class ContentTabLabel extends BaseLabel {
|
||||
|
||||
@NotNull
|
||||
private ContentManager getContentManager() {
|
||||
return myUi.myWindow.getContentManager();
|
||||
return myUi.getContentManager();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
@Override
|
||||
public Content getContent() {
|
||||
return myContent;
|
||||
|
||||
+25
-30
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.openapi.wm.impl.content;
|
||||
|
||||
import com.intellij.ide.dnd.DnDSupport;
|
||||
@@ -39,10 +39,10 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
|
||||
List<AnAction> myDoubleClickActions = new ArrayList<>();
|
||||
|
||||
TabContentLayout(ToolWindowContentUi ui) {
|
||||
TabContentLayout(@NotNull ToolWindowContentUi ui) {
|
||||
super(ui);
|
||||
|
||||
new BaseButtonBehavior(myUi) {
|
||||
new BaseButtonBehavior(myUi.getTabComponent()) {
|
||||
@Override
|
||||
protected void execute(final MouseEvent e) {
|
||||
if (!myUi.isCurrent(TabContentLayout.this)) return;
|
||||
@@ -65,7 +65,7 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
}
|
||||
};
|
||||
|
||||
ContentManager contentManager = myUi.contentManager;
|
||||
ContentManager contentManager = myUi.getContentManager();
|
||||
for (int i = 0; i < contentManager.getContentCount(); i++) {
|
||||
contentAdded(new ContentManagerEvent(this, contentManager.getContent(i), i));
|
||||
}
|
||||
@@ -99,14 +99,14 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
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);
|
||||
RelativePoint point = new RelativePoint(myUi, new Point(rect.x, rect.y + rect.height));
|
||||
RelativePoint point = new RelativePoint(myUi.getTabComponent(), new Point(rect.x, rect.y + rect.height));
|
||||
JBPopupFactory.getInstance().createListPopup(step).show(point);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layout() {
|
||||
Rectangle bounds = myUi.getBounds();
|
||||
ContentManager manager = myUi.contentManager;
|
||||
Rectangle bounds = myUi.getTabComponent().getBounds();
|
||||
ContentManager manager = myUi.getContentManager();
|
||||
LayoutData data = new LayoutData(myUi);
|
||||
|
||||
data.eachX = TAB_LAYOUT_START;
|
||||
@@ -137,7 +137,6 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (data.fullLayout) {
|
||||
for (ContentTabLabel eachTab : myTabs) {
|
||||
final Dimension eachSize = eachTab.getPreferredSize();
|
||||
@@ -200,8 +199,7 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
data.moreRect = null;
|
||||
}
|
||||
|
||||
final Rectangle moreRect = data.moreRect == null ? null : new Rectangle(data.eachX, 0, /*getMoreToolbarWidth()*/16+MORE_ICON_BORDER, bounds.height);
|
||||
|
||||
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;
|
||||
if (toolbarUpdateNeeded) {
|
||||
@@ -220,7 +218,7 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
}
|
||||
}
|
||||
|
||||
ContentManager contentManager = myUi.contentManager;
|
||||
ContentManager contentManager = myUi.getContentManager();
|
||||
Content selected = contentManager.getSelectedContent();
|
||||
if (selected == null && contentManager.getContents().length > 0) {
|
||||
selected = contentManager.getContents()[0];
|
||||
@@ -237,14 +235,16 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
}
|
||||
|
||||
boolean isToDrawTabs() {
|
||||
if(myTabs.size() > 1) return true;
|
||||
|
||||
if(myTabs.size() == 1) {
|
||||
String title = myTabs.get(0).getContent().getToolwindowTitle();
|
||||
return !StringUtil.isEmpty(title);
|
||||
}
|
||||
|
||||
int size = myTabs.size();
|
||||
if (size > 1) {
|
||||
return true;
|
||||
}
|
||||
else if (size == 1) {
|
||||
return !StringUtil.isEmpty(myTabs.get(0).getContent().getToolwindowTitle());
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static class LayoutData {
|
||||
@@ -263,12 +263,12 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
public int contentCount;
|
||||
|
||||
LayoutData(ToolWindowContentUi ui) {
|
||||
layoutSize = ui.getSize();
|
||||
contentCount = ui.contentManager.getContentCount();
|
||||
layoutSize = ui.getTabComponent().getSize();
|
||||
contentCount = ui.getContentManager().getContentCount();
|
||||
}
|
||||
}
|
||||
|
||||
private JBTabPainter tabPainter = JBTabPainter.getTOOL_WINDOW();
|
||||
private final JBTabPainter tabPainter = JBTabPainter.getTOOL_WINDOW();
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
@@ -292,11 +292,6 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintChildren(Graphics g) {
|
||||
if (!isToDrawTabs()) return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
for (ContentTabLabel each : myTabs) {
|
||||
@@ -308,13 +303,13 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
|
||||
@Override
|
||||
public void rebuild() {
|
||||
myUi.removeAll();
|
||||
myUi.getTabComponent().removeAll();
|
||||
|
||||
myUi.add(myIdLabel);
|
||||
myUi.getTabComponent().add(myIdLabel);
|
||||
ToolWindowContentUi.initMouseListeners(myIdLabel, myUi, true);
|
||||
|
||||
for (ContentTabLabel each : myTabs) {
|
||||
myUi.add(each);
|
||||
myUi.getTabComponent().add(each);
|
||||
ToolWindowContentUi.initMouseListeners(each, myUi, false);
|
||||
}
|
||||
}
|
||||
@@ -359,7 +354,7 @@ final class TabContentLayout extends ContentLayout implements MorePopupAware {
|
||||
|
||||
@Override
|
||||
public void showContentPopup(ListPopup listPopup) {
|
||||
Content selected = myUi.contentManager.getSelectedContent();
|
||||
Content selected = myUi.getContentManager().getSelectedContent();
|
||||
if (selected != null) {
|
||||
ContentTabLabel tab = myContent2Tabs.get(selected);
|
||||
listPopup.showUnderneathOf(tab);
|
||||
|
||||
+4
-6
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.openapi.wm.impl.content;
|
||||
|
||||
import com.intellij.ide.IdeEventQueue;
|
||||
@@ -8,7 +8,6 @@ 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;
|
||||
@@ -18,8 +17,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class TabbedContentTabLabel extends ContentTabLabel {
|
||||
|
||||
public final class TabbedContentTabLabel extends ContentTabLabel {
|
||||
private final TabbedContent myContent;
|
||||
private Reference<JBPopup> myPopupReference = null;
|
||||
|
||||
@@ -80,7 +78,7 @@ public class TabbedContentTabLabel extends ContentTabLabel {
|
||||
return hasMultipleTabs();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
@Override
|
||||
public Runnable getAction() {
|
||||
return () -> selectContent();
|
||||
@@ -99,7 +97,7 @@ public class TabbedContentTabLabel extends ContentTabLabel {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
@Override
|
||||
public TabbedContent getContent() {
|
||||
return myContent;
|
||||
|
||||
+93
-98
@@ -13,22 +13,21 @@ import com.intellij.openapi.ui.Splitter;
|
||||
import com.intellij.openapi.ui.ThreeComponentsSplitter;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.ListPopup;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.wm.*;
|
||||
import com.intellij.openapi.wm.impl.ToolWindowImpl;
|
||||
import com.intellij.openapi.wm.impl.ToolWindowManagerImpl;
|
||||
import com.intellij.ui.ComponentUtil;
|
||||
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.layout.migLayout.MigLayoutBuilderKt;
|
||||
import com.intellij.ui.layout.migLayout.patched.MigLayout;
|
||||
import com.intellij.ui.tabs.impl.MorePopupAware;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ContentUtilEx;
|
||||
import com.intellij.util.containers.JBIterable;
|
||||
import com.intellij.util.containers.Predicate;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.LocationOnDragTracker;
|
||||
@@ -44,62 +43,48 @@ import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public final class ToolWindowContentUi extends JPanel implements ContentUI, DataProvider, UISettingsListener {
|
||||
public final class ToolWindowContentUi implements ContentUI, DataProvider {
|
||||
// when client property is put in toolwindow component, hides toolwindow label
|
||||
public static final String HIDE_ID_LABEL = "HideIdLabel";
|
||||
private static final String TOOLWINDOW_UI_INSTALLED = "ToolWindowUiInstalled";
|
||||
|
||||
ContentManager contentManager;
|
||||
private ContentManager contentManager;
|
||||
|
||||
final JPanel myContent = new JPanel(new BorderLayout());
|
||||
ToolWindowImpl myWindow;
|
||||
public ContentManager getContentManager() {
|
||||
return contentManager;
|
||||
}
|
||||
|
||||
TabbedContentAction.CloseAllAction myCloseAllAction;
|
||||
TabbedContentAction.MyNextTabAction myNextTabAction;
|
||||
TabbedContentAction.MyPreviousTabAction myPreviousTabAction;
|
||||
private final JPanel myContent = new JPanel(new BorderLayout());
|
||||
final ToolWindowImpl myWindow;
|
||||
|
||||
ShowContentAction myShowContent;
|
||||
private TabbedContentAction.CloseAllAction myCloseAllAction;
|
||||
private TabbedContentAction.MyNextTabAction myNextTabAction;
|
||||
private TabbedContentAction.MyPreviousTabAction myPreviousTabAction;
|
||||
|
||||
TabContentLayout myTabsLayout = new TabContentLayout(this);
|
||||
ContentLayout myComboLayout = new ComboContentLayout(this);
|
||||
private ShowContentAction myShowContent;
|
||||
|
||||
private ToolWindowContentUiType myType = ToolWindowContentUiType.TABBED;
|
||||
private final TabContentLayout myTabsLayout;
|
||||
private ContentLayout myComboLayout;
|
||||
|
||||
private ToolWindowContentUiType myType;
|
||||
|
||||
public Predicate<Point> isResizableArea = p -> true;
|
||||
|
||||
public ToolWindowContentUi(@NotNull ToolWindowImpl window) {
|
||||
private final JPanel tabComponent = new TabPanel();
|
||||
|
||||
@NotNull
|
||||
public JPanel getTabComponent() {
|
||||
return tabComponent;
|
||||
}
|
||||
|
||||
public ToolWindowContentUi(@NotNull ToolWindowImpl window, @NotNull ToolWindowContentUiType contentUiType) {
|
||||
myType = contentUiType;
|
||||
myTabsLayout = new TabContentLayout(this);
|
||||
myWindow = window;
|
||||
myContent.setOpaque(false);
|
||||
myContent.setFocusable(false);
|
||||
setOpaque(false);
|
||||
|
||||
setBorder(JBUI.Borders.emptyRight(2));
|
||||
|
||||
// InternalDecorator adds myContent right after "this" (via ToolWindowHeader)
|
||||
// also myContent is never removed (can be invisible due to DumbAwareHider)
|
||||
ComponentUtil.putClientProperty(myContent, UIUtil.NOT_IN_HIERARCHY_COMPONENTS, new Iterable<JComponent>() {
|
||||
@Override
|
||||
public Iterator<JComponent> iterator() {
|
||||
if (contentManager == null || contentManager.getContentCount() == 0) {
|
||||
return Collections.emptyIterator();
|
||||
}
|
||||
return JBIterable.of(contentManager.getContents())
|
||||
.map(content -> {
|
||||
JComponent last = null;
|
||||
for (Component c : UIUtil.uiParents(content.getComponent(), false)) {
|
||||
if (c == contentManager.getComponent() || !(c instanceof JComponent)) return null;
|
||||
last = (JComponent)c;
|
||||
}
|
||||
return last;
|
||||
})
|
||||
.filter(Conditions.notNull())
|
||||
.iterator();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -107,12 +92,6 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data
|
||||
return myWindow.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uiSettingsChanged(@NotNull UISettings uiSettings) {
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private boolean isResizeable() {
|
||||
if (myWindow.getType() == ToolWindowType.FLOATING || myWindow.getType() == ToolWindowType.WINDOWED) {
|
||||
return false;
|
||||
@@ -158,7 +137,15 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data
|
||||
|
||||
@NotNull
|
||||
private ContentLayout getCurrentLayout() {
|
||||
return myType == ToolWindowContentUiType.TABBED ? myTabsLayout : myComboLayout;
|
||||
if (myType == ToolWindowContentUiType.TABBED) {
|
||||
return myTabsLayout;
|
||||
}
|
||||
else {
|
||||
if (myComboLayout == null) {
|
||||
myComboLayout = new ComboContentLayout(this);
|
||||
}
|
||||
return myComboLayout;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -166,10 +153,6 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data
|
||||
return myContent;
|
||||
}
|
||||
|
||||
public JComponent getTabComponent() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setManager(@NotNull ContentManager manager) {
|
||||
if (contentManager != null) {
|
||||
@@ -214,7 +197,7 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data
|
||||
}
|
||||
});
|
||||
|
||||
initMouseListeners(this, this, true);
|
||||
initMouseListeners(tabComponent, this, true);
|
||||
|
||||
rebuild();
|
||||
|
||||
@@ -249,57 +232,19 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data
|
||||
getCurrentLayout().rebuild();
|
||||
getCurrentLayout().update();
|
||||
|
||||
revalidate();
|
||||
repaint();
|
||||
tabComponent.revalidate();
|
||||
tabComponent.repaint();
|
||||
|
||||
if (contentManager != null && contentManager.getContentCount() == 0 && myWindow.isToHideOnEmptyContent()) {
|
||||
myWindow.hide(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doLayout() {
|
||||
getCurrentLayout().layout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(final Graphics g) {
|
||||
super.paintComponent(g);
|
||||
getCurrentLayout().paintComponent(g);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintChildren(final Graphics g) {
|
||||
super.paintChildren(g);
|
||||
getCurrentLayout().paintChildren(g);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
Insets insets = getInsets();
|
||||
return new Dimension(insets.left + insets.right + getCurrentLayout().getMinimumWidth(), super.getMinimumSize().height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension size = new Dimension();
|
||||
size.height = 0;
|
||||
size.width = TabContentLayout.TAB_LAYOUT_START + getInsets().left + getInsets().right;
|
||||
for (int i = 0; i < getComponentCount(); i++) {
|
||||
final Component each = getComponent(i);
|
||||
size.height = Math.max(each.getPreferredSize().height, size.height);
|
||||
size.width += each.getPreferredSize().width;
|
||||
}
|
||||
|
||||
size.width = Math.max(size.width, getMinimumSize().width);
|
||||
return size;
|
||||
}
|
||||
|
||||
private void update() {
|
||||
getCurrentLayout().update();
|
||||
|
||||
revalidate();
|
||||
repaint();
|
||||
tabComponent.revalidate();
|
||||
tabComponent.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -363,7 +308,9 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data
|
||||
final Ref<LocationOnDragTracker> myDragTracker = Ref.create();
|
||||
|
||||
private Component getActualSplitter() {
|
||||
if (!allowResize || !ui.isResizeable()) return null;
|
||||
if (!allowResize || !ui.isResizeable()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Component component = c;
|
||||
Component parent = component.getParent();
|
||||
@@ -628,7 +575,8 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data
|
||||
}
|
||||
else if (CloseAction.CloseTarget.KEY.is(dataId)) {
|
||||
return computeCloseTarget();
|
||||
} else if (MorePopupAware.KEY.is(dataId)) {
|
||||
}
|
||||
else if (MorePopupAware.KEY.is(dataId)) {
|
||||
ContentLayout layout = getCurrentLayout();
|
||||
return (layout instanceof TabContentLayout) ? layout : null;
|
||||
}
|
||||
@@ -685,4 +633,51 @@ public final class ToolWindowContentUi extends JPanel implements ContentUI, Data
|
||||
new Alarm(Alarm.ThreadToUse.SWING_THREAD, popup).addRequest(() -> popup.handleSelect(false), 50);
|
||||
}
|
||||
}
|
||||
|
||||
private final class TabPanel extends JPanel implements UISettingsListener {
|
||||
private TabPanel() {
|
||||
super(new MigLayout(MigLayoutBuilderKt.createLayoutConstraints(0, 0).noVisualPadding().fillY()));
|
||||
|
||||
setOpaque(false);
|
||||
setBorder(JBUI.Borders.emptyRight(2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uiSettingsChanged(@NotNull UISettings uiSettings) {
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doLayout() {
|
||||
getCurrentLayout().layout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
getCurrentLayout().paintComponent(g);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
Insets insets = getInsets();
|
||||
return new Dimension(insets.left + insets.right + getCurrentLayout().getMinimumWidth(), super.getMinimumSize().height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension size = new Dimension();
|
||||
size.height = 0;
|
||||
size.width = TabContentLayout.TAB_LAYOUT_START + getInsets().left + getInsets().right;
|
||||
for (int i = 0; i < getComponentCount(); i++) {
|
||||
final Component each = getComponent(i);
|
||||
size.height = Math.max(each.getPreferredSize().height, size.height);
|
||||
size.width += each.getPreferredSize().width;
|
||||
}
|
||||
|
||||
size.width = Math.max(size.width, getMinimumSize().width);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.content.impl;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
@@ -153,8 +153,7 @@ public class ContentImpl extends UserDataHolderBase implements Content {
|
||||
|
||||
@Override
|
||||
public String getToolwindowTitle() {
|
||||
if (myToolwindowTitle != null) return myToolwindowTitle;
|
||||
return myDisplayName;
|
||||
return myToolwindowTitle == null ? myDisplayName : myToolwindowTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,11 +171,6 @@ public class ContentImpl extends UserDataHolderBase implements Content {
|
||||
myShouldDisposeContent = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDisposeContent() {
|
||||
return myShouldDisposeContent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return myDescription;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.content.impl;
|
||||
|
||||
import com.intellij.ide.DataManager;
|
||||
@@ -169,7 +169,7 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene
|
||||
|
||||
@Override
|
||||
public boolean removeContent(@NotNull Content content, boolean dispose) {
|
||||
boolean wasFocused = content.getComponent() != null && UIUtil.isFocusAncestor(content.getComponent());
|
||||
boolean wasFocused = UIUtil.isFocusAncestor(content.getComponent());
|
||||
return removeContent(content, dispose, wasFocused, false).isDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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 org.jetbrains.plugins.terminal;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
@@ -161,11 +161,9 @@ public class TerminalView {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JBTerminalWidget createNewSession(@NotNull AbstractTerminalRunner terminalRunner, @Nullable TerminalTabState tabState, boolean requestFocus) {
|
||||
private JBTerminalWidget createNewSession(@NotNull AbstractTerminalRunner<?> terminalRunner, @Nullable TerminalTabState tabState, boolean requestFocus) {
|
||||
ToolWindow window = ToolWindowManager.getInstance(myProject).getToolWindow(TerminalToolWindowFactory.TOOL_WINDOW_ID);
|
||||
if (window != null && window.isAvailable()) {
|
||||
// ensure TerminalToolWindowFactory.createToolWindowContent gets called
|
||||
((ToolWindowImpl)window).ensureContentInitialized();
|
||||
Content content = createNewTab(null, terminalRunner, myToolWindow, tabState, requestFocus);
|
||||
window.activate(null);
|
||||
return Objects.requireNonNull(getWidgetByContent(content));
|
||||
@@ -350,16 +348,16 @@ public class TerminalView {
|
||||
|
||||
public void openTerminalIn(@Nullable VirtualFile fileToOpen) {
|
||||
ToolWindow window = ToolWindowManager.getInstance(myProject).getToolWindow(TerminalToolWindowFactory.TOOL_WINDOW_ID);
|
||||
if (window != null && window.isAvailable()) {
|
||||
// ensure TerminalToolWindowFactory.createToolWindowContent gets called
|
||||
((ToolWindowImpl)window).ensureContentInitialized();
|
||||
TerminalTabState state = new TerminalTabState();
|
||||
if (fileToOpen != null) {
|
||||
state.myWorkingDirectory = fileToOpen.getPath();
|
||||
}
|
||||
createNewSession(myTerminalRunner, state);
|
||||
window.activate(null);
|
||||
if (window == null || !window.isAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TerminalTabState state = new TerminalTabState();
|
||||
if (fileToOpen != null) {
|
||||
state.myWorkingDirectory = fileToOpen.getPath();
|
||||
}
|
||||
createNewSession(myTerminalRunner, state);
|
||||
window.activate(null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user