toolwindow resize for docked windows

This commit is contained in:
Kirill Kalishev
2010-01-15 14:53:07 +03:00
parent d9ad194525
commit 58876eee72
10 changed files with 295 additions and 89 deletions
@@ -13,19 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.actions;
package com.intellij.openapi.wm;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
public interface ToolWindowScrollable {
public class SizeWindowUpAction extends BaseResizeAction {
@Override
protected void update(ToolWindow window, ToolWindowManager mgr) {
}
boolean isHorizontalScrollingNeeded();
int getNextHorizontalScroll();
boolean isVerticalScrollingNeeded();
int getNextVerticalScroll();
@Override
protected void actionPerformed(AnActionEvent e, ToolWindow wnd, ToolWindowManager mgr) {
}
}
@@ -1,77 +0,0 @@
/*
* Copyright 2000-2010 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.ide.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.ToolWindowType;
public abstract class BaseResizeAction extends AnAction implements DumbAware {
private ToolWindow myLastWindow;
private ToolWindowManager myLastManager;
@Override
public final void update(AnActionEvent e) {
Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
if (project == null) {
setDisabled(e);
return;
}
ToolWindowManager mgr = ToolWindowManager.getInstance(project);
String active = mgr.getActiveToolWindowId();
if (active != null) {
ToolWindow window = mgr.getToolWindow(active);
if (!window.isAvailable() || !window.isVisible() || window.getType() == ToolWindowType.FLOATING) {
setDisabled(e);
return;
}
update(window, mgr);
if (e.getPresentation().isEnabled()) {
myLastWindow = window;
myLastManager = mgr;
} else {
setDisabled(e);
}
} else {
setDisabled(e);
}
}
private void setDisabled(AnActionEvent e) {
e.getPresentation().setEnabled(false);
myLastWindow = null;
myLastManager = null;
}
protected abstract void update(ToolWindow window, ToolWindowManager mgr);
@Override
public final void actionPerformed(AnActionEvent e) {
actionPerformed(e, myLastWindow, myLastManager);
}
protected abstract void actionPerformed(AnActionEvent e, ToolWindow wnd, ToolWindowManager mgr);
}
@@ -0,0 +1,210 @@
/*
* Copyright 2000-2010 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.ide.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.ex.ToolWindowEx;
import org.jetbrains.annotations.Nullable;
import sun.swing.SwingUtilities2;
import javax.swing.*;
import java.awt.*;
public abstract class ResizeToolWindowAction extends AnAction implements DumbAware {
private ToolWindow myLastWindow;
private ToolWindowManager myLastManager;
protected JLabel myScrollHelper = new JLabel("W");
@Override
public final void update(AnActionEvent e) {
Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
if (project == null) {
setDisabled(e);
return;
}
ToolWindowManager mgr = ToolWindowManager.getInstance(project);
String active = mgr.getActiveToolWindowId();
if (active != null) {
ToolWindow window = mgr.getToolWindow(active);
if (!window.isAvailable() || !window.isVisible() || window.getType() == ToolWindowType.FLOATING) {
setDisabled(e);
return;
}
update(e, window, mgr);
if (e.getPresentation().isEnabled()) {
myLastWindow = window;
myLastManager = mgr;
}
else {
setDisabled(e);
}
}
else {
setDisabled(e);
}
}
private void setDisabled(AnActionEvent e) {
e.getPresentation().setEnabled(false);
myLastWindow = null;
myLastManager = null;
}
protected abstract void update(AnActionEvent event, ToolWindow window, ToolWindowManager mgr);
@Override
public final void actionPerformed(AnActionEvent e) {
actionPerformed(e, myLastWindow, myLastManager);
}
@Nullable
private ToolWindowScrollable getScrollable(ToolWindow wnd, boolean isHorizontalStretchingOffered) {
KeyboardFocusManager mgr = KeyboardFocusManager.getCurrentKeyboardFocusManager();
Component eachComponent = mgr.getFocusOwner();
ToolWindowScrollable scrollable = null;
while (eachComponent != null) {
if (!SwingUtilities.isDescendingFrom(eachComponent, wnd.getComponent())) break;
if (eachComponent instanceof ToolWindowScrollable) {
ToolWindowScrollable eachScrollable = (ToolWindowScrollable)eachComponent;
if (isHorizontalStretchingOffered) {
if (eachScrollable.isHorizontalScrollingNeeded()) {
scrollable = eachScrollable;
break;
}
} else {
if (eachScrollable.isVerticalScrollingNeeded()) {
scrollable = eachScrollable;
break;
}
}
}
eachComponent = eachComponent.getParent();
}
if (scrollable == null) {
scrollable = new DefaultToolWindowScrollable();
}
if (isHorizontalStretchingOffered && scrollable.isHorizontalScrollingNeeded()) return scrollable;
if (!isHorizontalStretchingOffered && scrollable.isVerticalScrollingNeeded()) return scrollable;
return null;
}
protected abstract void actionPerformed(AnActionEvent e, ToolWindow wnd, ToolWindowManager mgr);
protected void stretch(ToolWindow wnd, boolean isHorizontalStretching, boolean isIncrementAction) {
ToolWindowScrollable scrollable = getScrollable(wnd, isHorizontalStretching);
if (scrollable == null) return;
ToolWindowAnchor anchor = wnd.getAnchor();
if (isHorizontalStretching && !anchor.isHorizontal()) {
incWidth(wnd, scrollable.getNextHorizontalScroll(), (anchor == ToolWindowAnchor.LEFT) == isIncrementAction);
} else if (!isHorizontalStretching && anchor.isHorizontal()) {
incHeight(wnd, scrollable.getNextVerticalScroll(), (anchor == ToolWindowAnchor.TOP) != isIncrementAction);
}
}
private void incWidth(ToolWindow wnd, int value, boolean isPositive) {
((ToolWindowEx)wnd).stretchWidth(isPositive ? value : -value);
}
private void incHeight(ToolWindow wnd, int value, boolean isPositive) {
((ToolWindowEx)wnd).stretchHeight(isPositive ? value : -value);
}
public static class Left extends ResizeToolWindowAction {
@Override
protected void update(AnActionEvent event, ToolWindow window, ToolWindowManager mgr) {
event.getPresentation().setEnabled(!window.getAnchor().isHorizontal());
}
@Override
protected void actionPerformed(AnActionEvent e, ToolWindow wnd, ToolWindowManager mgr) {
stretch(wnd, true, false);
}
}
public static class Right extends ResizeToolWindowAction {
@Override
protected void update(AnActionEvent event, ToolWindow window, ToolWindowManager mgr) {
event.getPresentation().setEnabled(!window.getAnchor().isHorizontal());
}
@Override
protected void actionPerformed(AnActionEvent e, ToolWindow wnd, ToolWindowManager mgr) {
stretch(wnd, true, true);
}
}
public static class Up extends ResizeToolWindowAction {
@Override
protected void update(AnActionEvent event, ToolWindow window, ToolWindowManager mgr) {
event.getPresentation().setEnabled(window.getAnchor().isHorizontal());
}
@Override
protected void actionPerformed(AnActionEvent e, ToolWindow wnd, ToolWindowManager mgr) {
stretch(wnd, false, true);
}
}
public static class Down extends ResizeToolWindowAction {
@Override
protected void update(AnActionEvent event, ToolWindow window, ToolWindowManager mgr) {
event.getPresentation().setEnabled(window.getAnchor().isHorizontal());
}
@Override
protected void actionPerformed(AnActionEvent e, ToolWindow wnd, ToolWindowManager mgr) {
stretch(wnd, false, false);
}
}
private class DefaultToolWindowScrollable implements ToolWindowScrollable {
public boolean isHorizontalScrollingNeeded() {
return true;
}
public int getNextHorizontalScroll() {
return myScrollHelper.getPreferredSize().width * Registry.intValue("ide.windowSystem.hScrollChars");
}
public boolean isVerticalScrollingNeeded() {
return true;
}
public int getNextVerticalScroll() {
return myScrollHelper.getPreferredSize().height * Registry.intValue("ide.windowSystem.vScrollChars");
}
}
}
@@ -40,4 +40,9 @@ public interface ToolWindowEx extends ToolWindow {
*/
ToolWindowType getInternalType();
void stretchWidth(int value);
void stretchHeight(int value);
}
@@ -218,6 +218,14 @@ public final class ToolWindowImpl implements ToolWindowEx {
return myToolWindowManager.getToolWindowInternalType(myId);
}
public void stretchWidth(int value) {
myToolWindowManager.stretchWidth(this, value);
}
public void stretchHeight(int value) {
myToolWindowManager.stretchHeight(this, value);
}
public final void setAvailable(final boolean available, final Runnable runnable) {
ApplicationManager.getApplication().assertIsDispatchThread();
final Boolean oldAvailable = myAvailable ? Boolean.TRUE : Boolean.FALSE;
@@ -1702,6 +1702,18 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
};
}
public void stretchWidth(ToolWindowImpl toolWindow, int value) {
if (!toolWindow.isVisible()) return;
myToolWindowsPane.stretchWidth(toolWindow, value);
}
public void stretchHeight(ToolWindowImpl toolWindow, int value) {
if (!toolWindow.isVisible()) return;
myToolWindowsPane.stretchHeight(toolWindow, value);
}
/**
* This command creates and shows <code>FloatingDecorator</code>.
@@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.ui.ThreeComponentsSplitter;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.impl.commands.FinalizableCommand;
import com.intellij.reference.SoftReference;
@@ -369,6 +370,38 @@ final class ToolWindowsPane extends JPanel{
}
}
public void stretchWidth(ToolWindow wnd, int value) {
JComponent cmp = getComponentAt(wnd.getAnchor());
if (cmp == null) return;
stretch(myHorizontalSplitter, cmp, cmp.getSize().width, value, 0, getSize().width);
}
public void stretchHeight(ToolWindow wnd, int value) {
JComponent cmp = getComponentAt(wnd.getAnchor());
if (cmp == null) return;
stretch(myVerticalSplitter, cmp, cmp.getSize().height, value, 0, getSize().height);
}
private void stretch(ThreeComponentsSplitter splitter, JComponent cmp, int currentValue, int incValue, int minValue, int maxValue) {
int actualSize = currentValue + incValue;
if (actualSize < minValue) {
actualSize = minValue;
}
if (actualSize > maxValue) {
actualSize = maxValue;
}
if (splitter.getFirstComponent() == cmp) {
splitter.setFirstSize(actualSize);
} else if (splitter.getLastComponent() == cmp) {
splitter.setLastSize(actualSize);
}
}
private final class AddDockedComponentCmd extends FinalizableCommand{
private final JComponent myComponent;
private final WindowInfoImpl myInfo;
@@ -26,6 +26,9 @@ ide.forcedShowTooltip=alt
ide.forcedShowTooltip.description=Shortcut for forced show tooltip
ide.popup.dropShadow=false
ide.windowSystem.hScrollChars=15
ide.windowSystem.vScrollChars=5
ide.tree.yeildingUiUpdate=true
ide.tree.showBusyIndicator=true
ide.tree.waitForReadyTimout=250
@@ -677,6 +677,18 @@
<action id="HideAllWindows">
<keyboard-shortcut first-keystroke="control shift F12"/>
</action>
<action id="ResizeToolWindowLeft">
<keyboard-shortcut first-keystroke="control shift LEFT"/>
</action>
<action id="ResizeToolWindowRight">
<keyboard-shortcut first-keystroke="control shift RIGHT"/>
</action>
<action id="ResizeToolWindowUp">
<keyboard-shortcut first-keystroke="control shift UP"/>
</action>
<action id="ResizeToolWindowDown">
<keyboard-shortcut first-keystroke="control shift DOWN"/>
</action>
<action id="HideSideWindows"/>
<action id="ShowPopupMenu">
<keyboard-shortcut first-keystroke="CONTEXT_MENU"/>
@@ -94,6 +94,11 @@
<action id="PinToolwindowTab" class="com.intellij.ui.content.tabs.PinToolwindowTabAction"/>
<action id="ResizeToolWindowLeft" class="com.intellij.ide.actions.ResizeToolWindowAction$Left"/>
<action id="ResizeToolWindowRight" class="com.intellij.ide.actions.ResizeToolWindowAction$Right"/>
<action id="ResizeToolWindowUp" class="com.intellij.ide.actions.ResizeToolWindowAction$Up"/>
<action id="ResizeToolWindowDown" class="com.intellij.ide.actions.ResizeToolWindowAction$Down"/>
<group id="MainMenu">
<group id="FileMenu" popup="true">
<group id="FileOpenGroup">