mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-112485 Shortcut to maximize toolwindow
This commit is contained in:
@@ -37,6 +37,8 @@ import java.awt.event.MouseEvent;
|
||||
* @author Vladimir Kondratyev
|
||||
*/
|
||||
public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
public static final int MIN_SIZE = 48;
|
||||
|
||||
private int myDividerWidth;
|
||||
/**
|
||||
* /------/
|
||||
@@ -189,14 +191,22 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
else {
|
||||
firstCompontSize = getFirstSize();
|
||||
lastComponentSize = getLastSize();
|
||||
int sizeLack = firstCompontSize + lastComponentSize - (componentSize - dividersCount * dividerWidth);
|
||||
int sizeLack = firstCompontSize + lastComponentSize - (componentSize - dividersCount * dividerWidth - MIN_SIZE);
|
||||
if (sizeLack > 0) {
|
||||
// Lacking size. Reduce first component's size, inner -> empty
|
||||
firstCompontSize -= sizeLack;
|
||||
innerComponentSize = 0;
|
||||
// Lacking size. Reduce first & last component's size, inner -> MIN_SIZE
|
||||
double firstSizeRatio = (double)firstCompontSize / (firstCompontSize + lastComponentSize);
|
||||
if (firstCompontSize > 0) {
|
||||
firstCompontSize -= sizeLack * firstSizeRatio;
|
||||
firstCompontSize = Math.max(MIN_SIZE, firstCompontSize);
|
||||
}
|
||||
if (lastComponentSize > 0) {
|
||||
lastComponentSize -= sizeLack * (1 - firstSizeRatio);
|
||||
lastComponentSize = Math.max(MIN_SIZE, lastComponentSize);
|
||||
}
|
||||
innerComponentSize = MIN_SIZE;
|
||||
}
|
||||
else {
|
||||
innerComponentSize = componentSize - dividersCount * dividerWidth - getFirstSize() - getLastSize();
|
||||
innerComponentSize = Math.max(MIN_SIZE, componentSize - dividersCount * dividerWidth - getFirstSize() - getLastSize());
|
||||
}
|
||||
|
||||
if (!innerVisible()) {
|
||||
@@ -395,6 +405,29 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
return lastVisible() ? myLastSize : 0;
|
||||
}
|
||||
|
||||
public int getMinSize(boolean first) {
|
||||
return getMinSize(first? myFirstComponent : myLastComponent);
|
||||
}
|
||||
|
||||
public int getMaxSize(boolean first) {
|
||||
final int size = getOrientation() ? this.getHeight() : this.getWidth();
|
||||
return size - (first? myLastSize: myFirstSize) - MIN_SIZE;
|
||||
}
|
||||
|
||||
private int getMinSize(JComponent component) {
|
||||
if (isHonorMinimumSize()) {
|
||||
if (component != null && myFirstComponent != null && myFirstComponent.isVisible() && myLastComponent != null && myLastComponent.isVisible()) {
|
||||
if (getOrientation()) {
|
||||
return component.getMinimumSize().height;
|
||||
}
|
||||
else {
|
||||
return component.getMinimumSize().width;
|
||||
}
|
||||
}
|
||||
}
|
||||
return MIN_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
myLastComponent = null;
|
||||
@@ -633,23 +666,24 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
myGlassPane.setCursor(getResizeCursor(), myListener);
|
||||
|
||||
myPoint = SwingUtilities.convertPoint(this, e.getPoint(), ThreeComponentsSplitter.this);
|
||||
final int size = getOrientation() ? ThreeComponentsSplitter.this.getHeight() : ThreeComponentsSplitter.this.getWidth();
|
||||
if (getOrientation()) {
|
||||
if (getHeight() > 0 || myDividerZone > 0) {
|
||||
if (size > 0 || myDividerZone > 0) {
|
||||
if (myIsFirst) {
|
||||
setFirstSize(Math.max(getMinSize(myFirstComponent), myPoint.y));
|
||||
setFirstSize(Math.min(size - myLastSize - MIN_SIZE, Math.max(getMinSize(myFirstComponent), myPoint.y)));
|
||||
}
|
||||
else {
|
||||
setLastSize(Math.max(getMinSize(myLastComponent), ThreeComponentsSplitter.this.getHeight() - myPoint.y - getDividerWidth()));
|
||||
setLastSize(Math.min(size - myFirstSize - MIN_SIZE, Math.max(getMinSize(myLastComponent), size - myPoint.y - getDividerWidth())));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (getWidth() > 0 || myDividerZone > 0) {
|
||||
if (size > 0 || myDividerZone > 0) {
|
||||
if (myIsFirst) {
|
||||
setFirstSize(Math.max(getMinSize(myFirstComponent), myPoint.x));
|
||||
setFirstSize(Math.min(size - myLastSize - MIN_SIZE, Math.max(getMinSize(myFirstComponent), myPoint.x)));
|
||||
}
|
||||
else {
|
||||
setLastSize(Math.max(getMinSize(myLastComponent), ThreeComponentsSplitter.this.getWidth() - myPoint.x - getDividerWidth()));
|
||||
setLastSize(Math.min(size - myFirstSize - MIN_SIZE, Math.max(getMinSize(myLastComponent), size - myPoint.x - getDividerWidth())));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -670,20 +704,6 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private int getMinSize(JComponent component) {
|
||||
if (isHonorMinimumSize()) {
|
||||
if (component != null && myFirstComponent != null && myFirstComponent.isVisible() && myLastComponent != null && myLastComponent.isVisible()) {
|
||||
if (getOrientation()) {
|
||||
return component.getMinimumSize().height;
|
||||
}
|
||||
else {
|
||||
return component.getMinimumSize().width;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected void processMouseEvent(MouseEvent e) {
|
||||
super.processMouseEvent(e);
|
||||
if (!isShowing()) {
|
||||
|
||||
@@ -154,4 +154,8 @@ public abstract class ToolWindowManager {
|
||||
|
||||
@Nullable
|
||||
public abstract Balloon getToolWindowBalloon(String id);
|
||||
|
||||
public abstract boolean isMaximized(@NotNull ToolWindow wnd);
|
||||
|
||||
public abstract void setMaximized(@NotNull ToolWindow wnd, boolean maximized);
|
||||
}
|
||||
|
||||
@@ -402,6 +402,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
resize.add(new ResizeToolWindowAction.Right(myToolWindow, this));
|
||||
resize.add(new ResizeToolWindowAction.Up(myToolWindow, this));
|
||||
resize.add(new ResizeToolWindowAction.Down(myToolWindow, this));
|
||||
resize.add(ActionManager.getInstance().getAction("MaximizeToolWindow"));
|
||||
|
||||
group.add(resize);
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.wm.impl;
|
||||
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class MaximizeToolWindowAction extends AnAction {
|
||||
public MaximizeToolWindowAction() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
Project project = e.getProject();
|
||||
if (project == null || project.isDisposed()) return;
|
||||
ToolWindow toolWindow = e.getData(PlatformDataKeys.TOOL_WINDOW);
|
||||
if (toolWindow == null) return;
|
||||
ToolWindowManager manager = ToolWindowManager.getInstance(project);
|
||||
manager.setMaximized(toolWindow, !manager.isMaximized(toolWindow));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(true);
|
||||
Project project = e.getProject();
|
||||
if (project == null || project.isDisposed()) {
|
||||
e.getPresentation().setEnabled(false);
|
||||
return;
|
||||
}
|
||||
ToolWindow toolWindow = e.getData(PlatformDataKeys.TOOL_WINDOW);
|
||||
if (toolWindow == null) {
|
||||
e.getPresentation().setEnabled(false);
|
||||
return;
|
||||
}
|
||||
ToolWindowManager manager = ToolWindowManager.getInstance(project);
|
||||
e.getPresentation().setText(manager.isMaximized(toolWindow) ?
|
||||
ActionsBundle.message("action.ResizeToolWindowMaximize.text.alternative") :
|
||||
ActionsBundle.message("action.ResizeToolWindowMaximize.text"));
|
||||
}
|
||||
}
|
||||
@@ -25,9 +25,11 @@ import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
|
||||
import com.intellij.openapi.actionSystem.impl.*;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowAnchor;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.openapi.wm.ToolWindowType;
|
||||
import com.intellij.openapi.wm.impl.content.ToolWindowContentUi;
|
||||
import com.intellij.ui.InplaceButton;
|
||||
@@ -210,6 +212,12 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
};
|
||||
}
|
||||
|
||||
void switchMaximizedState(Project project) {
|
||||
if (project == null || project.isDisposed()) return;
|
||||
ToolWindowManager mgr = ToolWindowManager.getInstance(project);
|
||||
mgr.setMaximized(myToolWindow, !mgr.isMaximized(myToolWindow));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uiSettingsChanged(UISettings source) {
|
||||
clearCaches();
|
||||
|
||||
+9
@@ -198,6 +198,15 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMaximized(@NotNull ToolWindow wnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaximized(@NotNull ToolWindow wnd, boolean maximized) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initToolWindow(@NotNull ToolWindowEP bean) {
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
private final FileEditorManager myFileEditorManager;
|
||||
private final LafManager myLafManager;
|
||||
private final Map<String, Balloon> myWindow2Balloon = new HashMap<String, Balloon>();
|
||||
private Pair<String, Integer> myMaximizedToolwindowSize = null;
|
||||
|
||||
private KeyState myCurrentState = KeyState.waiting;
|
||||
private final Alarm myWaiterForSecondPress = new Alarm();
|
||||
@@ -1982,6 +1983,16 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
myToolWindowsPane.stretchWidth(toolWindow, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMaximized(@NotNull ToolWindow wnd) {
|
||||
return myToolWindowsPane.isMaximized(wnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaximized(@NotNull ToolWindow wnd, boolean maximized) {
|
||||
myToolWindowsPane.setMaximized(wnd, maximized);
|
||||
}
|
||||
|
||||
public void stretchHeight(ToolWindowImpl toolWindow, int value) {
|
||||
myToolWindowsPane.stretchHeight(toolWindow, value);
|
||||
}
|
||||
|
||||
@@ -22,20 +22,27 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Splitter;
|
||||
import com.intellij.openapi.ui.ThreeComponentsSplitter;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.wm.IdeGlassPaneUtil;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowAnchor;
|
||||
import com.intellij.openapi.wm.ToolWindowType;
|
||||
import com.intellij.openapi.wm.ex.ToolWindowEx;
|
||||
import com.intellij.openapi.wm.impl.commands.FinalizableCommand;
|
||||
import com.intellij.ui.ScreenUtil;
|
||||
import com.intellij.ui.components.JBLayeredPane;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.ui.FadeInFadeOut;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
@@ -58,6 +65,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
|
||||
private final HashMap<StripeButton, WindowInfoImpl> myButton2Info;
|
||||
private final HashMap<InternalDecorator, WindowInfoImpl> myDecorator2Info;
|
||||
private final HashMap<String, Float> myId2SplitProportion;
|
||||
private Pair<ToolWindow, Integer> myMaximizedProportion = null;
|
||||
/**
|
||||
* This panel is the layered pane where all sliding tool windows are located. The DEFAULT
|
||||
* layer contains splitters. The PALETTE layer contains all sliding tool windows.
|
||||
@@ -192,6 +200,24 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
|
||||
super.addNotify();
|
||||
if (ScreenUtil.isStandardAddRemoveNotify(this)) {
|
||||
UISettings.getInstance().addUISettingsListener(myUISettingsListener, myDisposable);
|
||||
IdeGlassPaneUtil.find(this).addMousePreprocessor(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2 && e.getModifiersEx() == 0) {
|
||||
e = SwingUtilities.convertMouseEvent(e.getComponent(), e, ToolWindowsPane.this);
|
||||
Component component = SwingUtilities.getDeepestComponentAt(ToolWindowsPane.this, e.getX(), e.getY());
|
||||
Component header = component == null ? null : UIUtil.findParentByCondition((JComponent)component, new Condition<Component>() {
|
||||
@Override
|
||||
public boolean value(Component component) {
|
||||
return component instanceof ToolWindowHeader;
|
||||
}
|
||||
});
|
||||
if (header instanceof ToolWindowHeader) {
|
||||
((ToolWindowHeader)header).switchMaximizedState(myFrame.getProject());
|
||||
}
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,7 +516,21 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
|
||||
}
|
||||
|
||||
private void stretch(ToolWindow wnd, int value) {
|
||||
if (!wnd.isVisible()) return;
|
||||
Pair<Resizer, Component> pair = findResizerAndComponent(wnd);
|
||||
if (pair == null) return;
|
||||
|
||||
boolean vertical = wnd.getAnchor() == ToolWindowAnchor.TOP || wnd.getAnchor() == ToolWindowAnchor.BOTTOM;
|
||||
int actualSize = (vertical ? pair.second.getHeight() : pair.second.getWidth()) + value;
|
||||
boolean first = wnd.getAnchor() == ToolWindowAnchor.LEFT || wnd.getAnchor() == ToolWindowAnchor.TOP;
|
||||
int maxValue = vertical ? myVerticalSplitter.getMaxSize(first) : myHorizontalSplitter.getMaxSize(first);
|
||||
int minValue = vertical ? myVerticalSplitter.getMinSize(first) : myHorizontalSplitter.getMinSize(first);;
|
||||
|
||||
pair.first.setSize(Math.max(minValue, Math.min(maxValue, actualSize)));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Pair<Resizer, Component> findResizerAndComponent(ToolWindow wnd) {
|
||||
if (!wnd.isVisible()) return null;
|
||||
|
||||
Resizer resizer = null;
|
||||
Component cmp = null;
|
||||
@@ -534,26 +574,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
if (resizer == null) return;
|
||||
|
||||
int currentValue = wnd.getAnchor().isHorizontal() ? cmp.getHeight() : cmp.getWidth();
|
||||
|
||||
int actualSize = currentValue + value;
|
||||
|
||||
int minValue =
|
||||
wnd.getAnchor().isHorizontal() ? ((ToolWindowEx)wnd).getDecorator().getHeaderHeight() : 16 + myHorizontalSplitter.getDividerWidth();
|
||||
int maxValue = wnd.getAnchor().isHorizontal() ? myLayeredPane.getHeight() : myLayeredPane.getWidth();
|
||||
|
||||
|
||||
if (actualSize < minValue) {
|
||||
actualSize = minValue;
|
||||
}
|
||||
|
||||
if (actualSize > maxValue) {
|
||||
actualSize = maxValue;
|
||||
}
|
||||
|
||||
resizer.setSize(actualSize);
|
||||
return resizer != null ? Pair.create(resizer, cmp) : null;
|
||||
}
|
||||
|
||||
private void updateLayout() {
|
||||
@@ -598,6 +619,27 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMaximized(@NotNull ToolWindow wnd) {
|
||||
return myMaximizedProportion != null && myMaximizedProportion.first == wnd;
|
||||
}
|
||||
|
||||
public void setMaximized(@NotNull ToolWindow wnd, boolean maximized) {
|
||||
Pair<Resizer, Component> resizerAndComponent = findResizerAndComponent(wnd);
|
||||
if (resizerAndComponent == null) return;
|
||||
|
||||
if (!maximized) {
|
||||
ToolWindow maximizedWindow = myMaximizedProportion.first;
|
||||
assert maximizedWindow == wnd;
|
||||
resizerAndComponent.first.setSize(myMaximizedProportion.second);
|
||||
myMaximizedProportion = null;
|
||||
} else {
|
||||
int size = wnd.getAnchor().isHorizontal() ? resizerAndComponent.second.getHeight() : resizerAndComponent.second.getWidth();
|
||||
stretch(wnd, Short.MAX_VALUE);
|
||||
myMaximizedProportion = Pair.create(wnd, size);
|
||||
}
|
||||
doLayout();
|
||||
}
|
||||
|
||||
|
||||
interface Resizer {
|
||||
void setSize(int size);
|
||||
|
||||
@@ -842,6 +842,9 @@ action.ResizeToolWindowUp.text=Stretch to Top
|
||||
action.ResizeToolWindowUp.description=Resize active tool window to the top
|
||||
action.ResizeToolWindowDown.text=Stretch to Bottom
|
||||
action.ResizeToolWindowDown.description=Resize active tool window to the bottom
|
||||
action.ResizeToolWindowMaximize.text=Maximize tool window
|
||||
action.ResizeToolWindowMaximize.text.alternative=Restore tool window size
|
||||
action.ResizeToolWindowMaximize.description=Maximize tool widow
|
||||
action.IncrementWindowWidth.text=Increment Width
|
||||
action.DecrementWindowWidth.text=Decrement Width
|
||||
action.IncrementWindowHeight.text=Increment Height
|
||||
|
||||
@@ -774,6 +774,9 @@
|
||||
<action id="ResizeToolWindowDown">
|
||||
<keyboard-shortcut first-keystroke="control shift DOWN"/>
|
||||
</action>
|
||||
<action id="MaximizeToolWindow">
|
||||
<keyboard-shortcut first-keystroke="control shift QUOTE"/>
|
||||
</action>
|
||||
<action id="HideSideWindows"/>
|
||||
<action id="ShowPopupMenu">
|
||||
<keyboard-shortcut first-keystroke="CONTEXT_MENU"/>
|
||||
|
||||
@@ -355,6 +355,7 @@
|
||||
<action id="HideAllWindows" class="com.intellij.ide.actions.HideAllToolWindowsAction"/>
|
||||
<action id="CloseActiveTab" class="com.intellij.ide.actions.CloseActiveTabAction"/>
|
||||
<action id="JumpToLastWindow" class="com.intellij.ide.actions.JumpToLastWindowAction"/>
|
||||
<action id="MaximizeToolWindow" class="com.intellij.openapi.wm.impl.MaximizeToolWindowAction"/>
|
||||
<separator/>
|
||||
<action id="TogglePinnedMode" class="com.intellij.ide.actions.TogglePinnedModeAction"/>
|
||||
<action id="ToggleDockMode" class="com.intellij.ide.actions.ToggleDockModeAction"/>
|
||||
|
||||
@@ -654,6 +654,15 @@ public class Mock {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMaximized(@NotNull ToolWindow wnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaximized(@NotNull ToolWindow wnd, boolean maximized) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyByBalloon(@NotNull final String toolWindowId, @NotNull final MessageType type, @NotNull final String htmlBody) {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user