| /* |
| * 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.ActionManager; |
| import com.intellij.openapi.actionSystem.AnAction; |
| import com.intellij.openapi.actionSystem.AnActionEvent; |
| import com.intellij.openapi.actionSystem.CommonDataKeys; |
| import com.intellij.openapi.project.DumbAware; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.project.ProjectManager; |
| import com.intellij.openapi.project.ProjectManagerAdapter; |
| import com.intellij.openapi.ui.ShadowAction; |
| 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 javax.swing.*; |
| import java.awt.*; |
| |
| public abstract class ResizeToolWindowAction extends AnAction implements DumbAware { |
| |
| private ToolWindow myLastWindow; |
| private ToolWindowManager myLastManager; |
| |
| protected JLabel myScrollHelper; |
| |
| private ToolWindow myToolWindow; |
| |
| private boolean myListenerInstalled; |
| |
| protected ResizeToolWindowAction() { |
| } |
| |
| protected ResizeToolWindowAction(String text) { |
| super(text); |
| } |
| |
| protected ResizeToolWindowAction(String text, String description, Icon icon) { |
| super(text, description, icon); |
| } |
| |
| protected ResizeToolWindowAction(ToolWindow toolWindow, String originalAction, JComponent c) { |
| myToolWindow = toolWindow; |
| new ShadowAction(this, ActionManager.getInstance().getAction(originalAction), c); |
| } |
| |
| @Override |
| public final void update(AnActionEvent e) { |
| Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); |
| if (project == null) { |
| setDisabled(e); |
| return; |
| } |
| |
| if (!myListenerInstalled) { |
| myListenerInstalled = true; |
| ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerAdapter() { |
| @Override |
| public void projectClosed(Project project) { |
| setDisabled(null); |
| } |
| }); |
| } |
| |
| Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); |
| if (owner == null) { |
| setDisabled(e); |
| return; |
| } |
| |
| final Window windowAncestor = SwingUtilities.getWindowAncestor(owner); |
| if (!(windowAncestor instanceof IdeFrame) || windowAncestor instanceof IdeFrame.Child) { |
| setDisabled(e); |
| return; |
| } |
| |
| |
| ToolWindowManager mgr = ToolWindowManager.getInstance(project); |
| |
| ToolWindow window = myToolWindow; |
| |
| if (window != null || mgr.getActiveToolWindowId() != null) { |
| if (window == null) { |
| window = mgr.getToolWindow(mgr.getActiveToolWindowId()); |
| } |
| |
| if (window == null || !window.isAvailable() || !window.isVisible() || window.getType() == ToolWindowType.FLOATING || !window.isActive()) { |
| setDisabled(e); |
| return; |
| } |
| |
| update(e, window, mgr); |
| if (e.getPresentation().isEnabled()) { |
| myLastWindow = window; |
| myLastManager = mgr; |
| } |
| else { |
| setDisabled(e); |
| } |
| } |
| else { |
| setDisabled(e); |
| } |
| } |
| |
| private void setDisabled(@Nullable AnActionEvent e) { |
| if (e != null) { |
| e.getPresentation().setEnabled(false); |
| } |
| |
| myLastWindow = null; |
| myLastManager = null; |
| myToolWindow = 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 static void incWidth(ToolWindow wnd, int value, boolean isPositive) { |
| ((ToolWindowEx)wnd).stretchWidth(isPositive ? value : -value); |
| } |
| |
| private static void incHeight(ToolWindow wnd, int value, boolean isPositive) { |
| ((ToolWindowEx)wnd).stretchHeight(isPositive ? value : -value); |
| } |
| |
| public static class Left extends ResizeToolWindowAction { |
| |
| public Left() { |
| } |
| |
| public Left(String text) { |
| super(text); |
| } |
| |
| public Left(String text, String description, Icon icon) { |
| super(text, description, icon); |
| } |
| |
| public Left(ToolWindow toolWindow, JComponent c) { |
| super(toolWindow, "ResizeToolWindowLeft", c); |
| } |
| |
| @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 { |
| |
| public Right() { |
| } |
| |
| public Right(String text) { |
| super(text); |
| } |
| |
| public Right(String text, String description, Icon icon) { |
| super(text, description, icon); |
| } |
| |
| public Right(ToolWindow toolWindow, JComponent c) { |
| super(toolWindow, "ResizeToolWindowRight", c); |
| } |
| |
| @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 { |
| |
| public Up() { |
| } |
| |
| public Up(String text) { |
| super(text); |
| } |
| |
| public Up(String text, String description, Icon icon) { |
| super(text, description, icon); |
| } |
| |
| public Up(ToolWindow toolWindow, JComponent c) { |
| super(toolWindow, "ResizeToolWindowUp", c); |
| } |
| |
| @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 { |
| |
| public Down() { |
| } |
| |
| public Down(String text) { |
| super(text); |
| } |
| |
| public Down(String text, String description, Icon icon) { |
| super(text, description, icon); |
| } |
| |
| public Down(ToolWindow toolWindow, JComponent c) { |
| super(toolWindow, "ResizeToolWindowDown", c); |
| } |
| |
| @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 getReferenceSize().width * Registry.intValue("ide.windowSystem.hScrollChars"); |
| } |
| |
| public boolean isVerticalScrollingNeeded() { |
| return true; |
| } |
| |
| public int getNextVerticalScroll() { |
| return getReferenceSize().height * Registry.intValue("ide.windowSystem.vScrollChars"); |
| } |
| } |
| |
| private Dimension getReferenceSize() { |
| if (myScrollHelper == null) { |
| if (SwingUtilities.isEventDispatchThread()) { |
| myScrollHelper = new JLabel("W"); |
| } else { |
| return new Dimension(1, 1); |
| } |
| } |
| |
| return myScrollHelper.getPreferredSize(); |
| } |
| } |