From 02fe24c4975681eef63131e1e6cc50bdc2ce5e1c Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 18 Nov 2010 21:18:25 +0300 Subject: [PATCH] navbar in dockable editors - 1 --- .../ide/navigationToolbar/NavBarPanel.java | 3 +- .../NavBarRootPaneExtension.java | 9 +- .../SelectInNavBarTarget.java | 32 +++++--- .../src/com/intellij/openapi/wm/IdeFrame.java | 5 ++ .../wm}/IdeRootPaneNorthExtension.java | 4 +- .../fileEditor/impl/EditorsSplitters.java | 10 ++- .../impl/FileEditorManagerImpl.java | 5 ++ .../com/intellij/openapi/ui/FrameWrapper.java | 31 ++++++- .../openapi/wm/impl/IdeFrameImpl.java | 13 ++- .../intellij/openapi/wm/impl/IdeRootPane.java | 5 +- .../ui/docking/impl/DockManagerImpl.java | 82 ++++++++++++++++++- .../src/META-INF/PlatformExtensionPoints.xml | 2 +- 12 files changed, 172 insertions(+), 29 deletions(-) rename platform/{platform-impl/src/com/intellij/openapi/wm/impl => platform-api/src/com/intellij/openapi/wm}/IdeRootPaneNorthExtension.java (93%) diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java index babae451e25d..18584955cec4 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java @@ -711,7 +711,7 @@ public class NavBarPanel extends OpaquePanel.List implements DataProvider, Popup validate(); } - if (item.isShowing()) { + if (item.isShowing() && step.getValues().size() > 0) { myNodePopup.showUnderneathOf(item); } } @@ -1328,4 +1328,5 @@ public class NavBarPanel extends OpaquePanel.List implements DataProvider, Popup setBackground(selected ? UIUtil.getListSelectionBackground() : UIUtil.getListBackground()); } } + } diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java index 2a946c437975..82f6fd9d5f22 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java @@ -26,7 +26,7 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ComboBoxAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.wm.impl.IdeRootPaneNorthExtension; +import com.intellij.openapi.wm.IdeRootPaneNorthExtension; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.components.panels.OpaquePanel; import com.intellij.util.ui.UIUtil; @@ -54,7 +54,12 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension { public void uiSettingsChanged(UISettings source) { toggleRunPanel(!source.SHOW_MAIN_TOOLBAR); } - }, project); + }, this); + } + + @Override + public IdeRootPaneNorthExtension copy() { + return new NavBarRootPaneExtension(myProject); } public JComponent getComponent() { diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/SelectInNavBarTarget.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/SelectInNavBarTarget.java index fdc7aa0a157e..3f017d143ac7 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/SelectInNavBarTarget.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/SelectInNavBarTarget.java @@ -15,13 +15,18 @@ */ package com.intellij.ide.navigationToolbar; +import com.intellij.ide.DataManager; import com.intellij.ide.SelectInManager; import com.intellij.ide.StandardTargetWeights; import com.intellij.ide.impl.SelectInTargetPsiWrapper; import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.AsyncResult; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.IdeFrame; +import com.intellij.openapi.wm.IdeRootPaneNorthExtension; import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.openapi.wm.impl.IdeFrameImpl; import com.intellij.openapi.wm.impl.IdeRootPane; @@ -62,16 +67,24 @@ public class SelectInNavBarTarget extends SelectInTargetPsiWrapper implements Du } protected void select(final Object selector, VirtualFile virtualFile, final boolean requestFocus) { - final IdeFrameImpl frame = WindowManagerEx.getInstanceEx().getFrame(myProject); - navBar(frame).selectTail(); + selectTail(); } - private static NavBarPanel navBar(IdeFrameImpl frame) { - return ((NavBarPanel)navBarComponent(frame).getClientProperty("NavBarPanel")); - } - - private static JComponent navBarComponent(IdeFrameImpl frame) { - return ((IdeRootPane)frame.getRootPane()).findByName(NavBarRootPaneExtension.NAV_BAR).getComponent(); + private static void selectTail() { + DataManager.getInstance().getDataContextFromFocus().doWhenDone(new AsyncResult.Handler() { + @Override + public void run(DataContext context) { + IdeFrame frame = IdeFrame.KEY.getData(context); + if (frame != null) { + IdeRootPaneNorthExtension navBarExt = frame.getNorthExtension(NavBarRootPaneExtension.NAV_BAR); + if (navBarExt != null) { + JComponent c = navBarExt.getComponent(); + NavBarPanel panel = (NavBarPanel)c.getClientProperty("NavBarPanel"); + panel.selectTail(); + } + } + } + }); } protected boolean canWorkWithCustomObjects() { @@ -79,8 +92,7 @@ public class SelectInNavBarTarget extends SelectInTargetPsiWrapper implements Du } protected void select(PsiElement element, boolean requestFocus) { - final IdeFrameImpl frame = WindowManagerEx.getInstanceEx().getFrame(myProject); - navBar(frame).selectTail(); + selectTail(); } } diff --git a/platform/platform-api/src/com/intellij/openapi/wm/IdeFrame.java b/platform/platform-api/src/com/intellij/openapi/wm/IdeFrame.java index 917590a16740..73fdb6118add 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/IdeFrame.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/IdeFrame.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.wm; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.Nullable; @@ -23,6 +24,8 @@ import java.io.File; public interface IdeFrame { + DataKey KEY = DataKey.create("IdeFrame"); + StatusBar getStatusBar(); Rectangle suggestChildFrameBounds(); @@ -33,6 +36,8 @@ public interface IdeFrame { void setFrameTitle(String title); void setFileTitle(String fileTitle, File ioFile); + IdeRootPaneNorthExtension getNorthExtension(String key); + interface Child extends IdeFrame { IdeFrame getParentFrame(); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPaneNorthExtension.java b/platform/platform-api/src/com/intellij/openapi/wm/IdeRootPaneNorthExtension.java similarity index 93% rename from platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPaneNorthExtension.java rename to platform/platform-api/src/com/intellij/openapi/wm/IdeRootPaneNorthExtension.java index 454b18301f0a..4d516113e24c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPaneNorthExtension.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/IdeRootPaneNorthExtension.java @@ -18,7 +18,7 @@ * User: anna * Date: 12-Nov-2007 */ -package com.intellij.openapi.wm.impl; +package com.intellij.openapi.wm; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.Disposable; @@ -34,4 +34,6 @@ public abstract class IdeRootPaneNorthExtension implements Disposable { public abstract JComponent getComponent(); public abstract void uiSettingsChanged(UISettings settings); + + public abstract IdeRootPaneNorthExtension copy(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java index 0d03a6a7ad0c..6e992b32bbe4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java @@ -425,12 +425,14 @@ public class EditorsSplitters extends JPanel { Project project = myManager.getProject(); final IdeFrame frame = getFrame(project); + if (frame != null) { + VirtualFile file = getCurrentFile(); - VirtualFile file = getCurrentFile(); + File ioFile = file == null ? null : new File(file.getPresentableUrl()); + String fileTitle = file == null ? null : FrameTitleBuilder.getInstance().getFileTitle(project, file); - File ioFile = file == null ? null : new File(file.getPresentableUrl()); - String fileTitle = file == null ? null : FrameTitleBuilder.getInstance().getFileTitle(project, file); - frame.setFileTitle(fileTitle, ioFile); + frame.setFileTitle(fileTitle, ioFile); + } } protected IdeFrame getFrame(Project project) { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java index 3e9a1e2d872d..357b864d2ec9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java @@ -164,6 +164,11 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec Component focusOwner = async ? fm.getFocusOwner() : KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); DockContainer container = DockManager.getInstance(myProject).getContainerFor(focusOwner); + if (container == null && !async) { + focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); + container = DockManager.getInstance(myProject).getContainerFor(focusOwner); + } + if (container instanceof DockableEditorTabbedContainer) { result.setDone(((DockableEditorTabbedContainer)container).getSplitters()); } else { diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java b/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java index 6e6273b5553c..4c92d2f5e44b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java @@ -42,7 +42,7 @@ import java.awt.event.*; import java.io.File; import java.util.Map; -public class FrameWrapper implements Disposable { +public class FrameWrapper implements Disposable, DataProvider { private String myDimensionKey = null; private JComponent myComponent = null; private JComponent myPreferedFocus = null; @@ -178,7 +178,21 @@ public class FrameWrapper implements Disposable { } protected JFrame createJFrame(IdeFrame parent) { - return new MyJFrame(parent); + return new MyJFrame(parent) { + @Override + public IdeRootPaneNorthExtension getNorthExtension(String key) { + return FrameWrapper.this.getNorthExtension(key); + } + }; + } + + protected IdeRootPaneNorthExtension getNorthExtension(String key) { + return null; + } + + @Override + public Object getData(@NonNls String dataId) { + return null; } public void setComponent(JComponent component) { @@ -293,6 +307,12 @@ public class FrameWrapper implements Disposable { updateTitle(); } + @Override + public IdeRootPaneNorthExtension getNorthExtension(String key) { + return null; + } + + private void updateTitle() { IdeFrameImpl.updateTitle(this, myFrameTitle, myFileTitle, myFile); } @@ -327,7 +347,12 @@ public class FrameWrapper implements Disposable { } public Object getData(String dataId) { - return myDatas.get(dataId); + if (IdeFrame.KEY.getName().equals(dataId)) { + return this; + } + + Object data = FrameWrapper.this.getData(dataId); + return data != null ? data : myDatas.get(dataId); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java index 0a5a37174de4..ed0f7c5f5cd0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java @@ -37,6 +37,7 @@ import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.IdeFrame; +import com.intellij.openapi.wm.IdeRootPaneNorthExtension; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt; import com.intellij.openapi.wm.ex.StatusBarEx; @@ -212,6 +213,11 @@ public class IdeFrameImpl extends JFrame implements IdeFrame, DataProvider { updateTitle(); } + @Override + public IdeRootPaneNorthExtension getNorthExtension(String key) { + return myRootPane.findByName(key); + } + private void updateTitle() { updateTitle(this, myTitle, myFileTitle, myCurrentFile); } @@ -248,6 +254,11 @@ public class IdeFrameImpl extends JFrame implements IdeFrame, DataProvider { return myProject.isInitialized() ? myProject : null; } } + + if (IdeFrame.KEY.getName().equals(dataId)) { + return this; + } + return null; } @@ -336,7 +347,7 @@ public class IdeFrameImpl extends JFrame implements IdeFrame, DataProvider { public static Component findNearestModalComponent(@NotNull Component c) { Component eachParent = c; while (eachParent != null) { - if (eachParent instanceof IdeFrameImpl) return eachParent; + if (eachParent instanceof IdeFrame) return eachParent; if (eachParent instanceof JDialog) { if (((JDialog)eachParent).isModal()) return eachParent; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java index b474f9d0b6f0..c9295935cd7a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java @@ -37,10 +37,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.wm.CustomStatusBarWidget; -import com.intellij.openapi.wm.IdeFrame; -import com.intellij.openapi.wm.StatusBar; -import com.intellij.openapi.wm.StatusBarCustomComponentFactory; +import com.intellij.openapi.wm.*; import com.intellij.openapi.wm.impl.status.IdeStatusBarImpl; import com.intellij.openapi.wm.impl.status.MemoryUsagePanel; import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeScreen; diff --git a/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java b/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java index fee71dd0f81c..c15838a16fce 100644 --- a/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java @@ -16,10 +16,15 @@ package com.intellij.ui.docking.impl; import com.intellij.ide.IdeEventQueue; +import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; import com.intellij.openapi.Disposable; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; +import com.intellij.openapi.extensions.ExtensionPointListener; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.extensions.PluginDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.FrameWrapper; import com.intellij.openapi.util.ActionCallback; @@ -27,13 +32,14 @@ import com.intellij.openapi.util.BusyObject; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.MutualMap; import com.intellij.openapi.wm.IdeFrame; -import com.intellij.openapi.wm.StatusBar; +import com.intellij.openapi.wm.IdeRootPaneNorthExtension; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.openapi.wm.impl.IdeFocusManagerImpl; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.awt.RelativeRectangle; import com.intellij.ui.components.panels.NonOpaquePanel; +import com.intellij.ui.components.panels.VerticalBox; import com.intellij.ui.docking.*; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.update.UiNotifyConnector; @@ -379,6 +385,9 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo private String myId; private DockContainer myContainer; + private VerticalBox myNorthPanel = new VerticalBox(); + private Map myNorthExtensions = new LinkedHashMap(); + private DockWindow(String id, Project project, DockContainer container) { super(project); myId = id; @@ -388,7 +397,13 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo setStatusBar(WindowManager.getInstance().getStatusBar(project).createChild()); NonOpaquePanel comp = new NonOpaquePanel(new BorderLayout()); - comp.add(myContainer.getComponent(), BorderLayout.CENTER); + + NonOpaquePanel center = new NonOpaquePanel(new BorderLayout(0, 2)); + center.add(myNorthPanel, BorderLayout.NORTH); + center.add(myContainer.getComponent(), BorderLayout.CENTER); + + comp.add(center, BorderLayout.CENTER); + comp.add(myStatusBar.getComponent(), BorderLayout.SOUTH); setComponent(comp); @@ -409,6 +424,63 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo }); } }, this); + + Extensions.getArea(myProject).getExtensionPoint(IdeRootPaneNorthExtension.EP_NAME).addExtensionPointListener( + new ExtensionPointListener() { + @Override + public void extensionAdded(@NotNull IdeRootPaneNorthExtension extension, @Nullable PluginDescriptor pluginDescriptor) { + updateNorthPanel(); + } + + @Override + public void extensionRemoved(@NotNull IdeRootPaneNorthExtension extension, @Nullable PluginDescriptor pluginDescriptor) { + updateNorthPanel(); + } + + }); + + UISettings.getInstance().addUISettingsListener(new UISettingsListener() { + @Override + public void uiSettingsChanged(UISettings source) { + updateNorthPanel(); + } + }, this); + + updateNorthPanel(); + } + + + @Override + protected IdeRootPaneNorthExtension getNorthExtension(String key) { + return myNorthExtensions.get(key); + } + + private void updateNorthPanel() { + myNorthPanel.setVisible(UISettings.getInstance().SHOW_NAVIGATION_BAR); + + IdeRootPaneNorthExtension[] extensions = Extensions.getArea(myProject).getExtensionPoint(IdeRootPaneNorthExtension.EP_NAME).getExtensions(); + HashSet processedKeys = new HashSet(); + for (IdeRootPaneNorthExtension each : extensions) { + processedKeys.add(each.getKey()); + if (myNorthExtensions.containsKey(each.getKey())) continue; + IdeRootPaneNorthExtension toInstall = each.copy(); + myNorthExtensions.put(toInstall.getKey(), toInstall); + myNorthPanel.add(toInstall.getComponent()); + } + + Iterator existing = myNorthExtensions.keySet().iterator(); + while (existing.hasNext()) { + String each = existing.next(); + if (processedKeys.contains(each)) continue; + + IdeRootPaneNorthExtension toRemove = myNorthExtensions.get(each); + myNorthPanel.remove(toRemove.getComponent()); + existing.remove(); + Disposer.dispose(toRemove); + } + + myNorthPanel.revalidate(); + myNorthPanel.repaint(); } public void setTransparrent(boolean transparrent) { @@ -425,6 +497,11 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo public void dispose() { super.dispose(); myWindows.remove(myContainer); + + for (IdeRootPaneNorthExtension each : myNorthExtensions.values()) { + Disposer.dispose(each); + } + myNorthExtensions.clear(); } @Override @@ -453,6 +530,7 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo } } + @Override public Element getState() { Element root = new Element("DockManager"); diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index 5f68e53c534e..3f7291cee545 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -38,7 +38,7 @@ - +