From 8e5dcb7d80cce7a77df75beb1b1f9f15ad49dee7 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 3 Feb 2012 19:32:38 +0100 Subject: [PATCH] Escape cancels editor tab drag --- .../ui/layout/impl/RunnerContentUi.java | 6 +++ .../src/com/intellij/ui/MouseDragHelper.java | 51 ++++++++++++++++--- .../com/intellij/ui/docking/DragSession.java | 1 + .../src/com/intellij/ui/tabs/TabInfo.java | 1 + .../com/intellij/ui/tabs/impl/DragHelper.java | 14 +++++ .../impl/EditorTabbedContainer.java | 11 ++++ .../ui/docking/impl/DockManagerImpl.java | 17 ++++--- 7 files changed, 89 insertions(+), 12 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java index 81f6cb266d6b..d7cdcf4eb107 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java @@ -1606,6 +1606,12 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac mySession.process(event); mySession = null; } + + @Override + public void dragOutCancelled(TabInfo source) { + mySession.cancel(); + mySession = null; + } } class DockableGrid implements DockableContent> { diff --git a/platform/platform-api/src/com/intellij/ui/MouseDragHelper.java b/platform/platform-api/src/com/intellij/ui/MouseDragHelper.java index 49f2dc3eba38..0d8a3aac1c45 100644 --- a/platform/platform-api/src/com/intellij/ui/MouseDragHelper.java +++ b/platform/platform-api/src/com/intellij/ui/MouseDragHelper.java @@ -26,11 +26,12 @@ import com.intellij.util.ui.update.UiNotifyConnector; import javax.swing.*; import java.awt.*; +import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; -public abstract class MouseDragHelper implements MouseListener, MouseMotionListener { +public abstract class MouseDragHelper implements MouseListener, MouseMotionListener, KeyEventDispatcher { public static final int DRAG_START_DEADZONE = 7; @@ -47,6 +48,7 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe private boolean myDetachPostponed; private boolean myDetachingMode; + private boolean myCancelled; public MouseDragHelper(Disposable parent, final JComponent dragComponent) { myDragComponent = dragComponent; @@ -82,6 +84,13 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe myGlassPane = IdeGlassPaneUtil.find(myDragComponent); myGlassPane.addMousePreprocessor(this, myParentDisposable); myGlassPane.addMouseMotionPreprocessor(this, myParentDisposable); + KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this); + Disposer.register(myParentDisposable, new Disposable() { + @Override + public void dispose() { + KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(MouseDragHelper.this); + } + }); } public void stop() { @@ -96,6 +105,7 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe if (myGlassPane != null) { myGlassPane.removeMousePreprocessor(this); myGlassPane.removeMouseMotionPreprocessor(this); + KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this); myGlassPane = null; } } @@ -115,6 +125,10 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe } public void mouseReleased(final MouseEvent e) { + if (myCancelled) { + myCancelled = false; + return; + } boolean wasDragging = myDraggingNow; myPressPointScreen = null; myDraggingNow = false; @@ -129,10 +143,7 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe } } finally { - myDraggingNow = false; - myPressPointComponent = null; - myPressPointScreen = null; - myDetachingMode = false; + resetDragState(); e.consume(); if (myDetachPostponed) { myDetachPostponed = false; @@ -142,8 +153,16 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe } } + private void resetDragState() { + myDraggingNow = false; + myDragJustStarted = false; + myPressPointComponent = null; + myPressPointScreen = null; + myDetachingMode = false; + } + public void mouseDragged(final MouseEvent e) { - if (myPressPointScreen == null) return; + if (myPressPointScreen == null || myCancelled) return; final boolean deadZone = isWithinDeadZone(e); if (!myDraggingNow && !deadZone) { @@ -190,6 +209,8 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe return true; } + protected void processDragCancel() { + } protected void processDragFinish(final MouseEvent event, boolean willDragOutStart) { } @@ -197,6 +218,9 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe protected void processDragOutFinish(final MouseEvent event) { } + protected void processDragOutCancel() { + } + public final boolean isDragJustStarted() { return myDragJustStarted; } @@ -229,4 +253,19 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe public void mouseMoved(final MouseEvent e) { } + @Override + public boolean dispatchKeyEvent(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE && e.getID() == KeyEvent.KEY_PRESSED) { + myCancelled = true; + if (myDetachingMode) { + processDragOutCancel(); + } + else { + processDragCancel(); + } + resetDragState(); + return true; + } + return false; + } } diff --git a/platform/platform-api/src/com/intellij/ui/docking/DragSession.java b/platform/platform-api/src/com/intellij/ui/docking/DragSession.java index 1704cebf8574..b8ab3005fb2a 100644 --- a/platform/platform-api/src/com/intellij/ui/docking/DragSession.java +++ b/platform/platform-api/src/com/intellij/ui/docking/DragSession.java @@ -20,5 +20,6 @@ import java.awt.event.MouseEvent; public interface DragSession { void process(MouseEvent e); + void cancel(); } diff --git a/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java b/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java index 169ed6b514f6..56e646ab8f4d 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java @@ -376,6 +376,7 @@ public final class TabInfo implements Queryable, PlaceProvider { void dragOutStarted(MouseEvent mouseEvent, TabInfo info); void processDragOut(MouseEvent event, TabInfo source); void dragOutFinished(MouseEvent event, TabInfo source); + void dragOutCancelled(TabInfo source); } } diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java index b38d2821aa59..c67151d77509 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java @@ -76,6 +76,11 @@ class DragHelper extends MouseDragHelper { myDragOutSource.getDragOutDelegate().dragOutFinished(event, myDragOutSource); } + @Override + protected void processDragOutCancel() { + myDragOutSource.getDragOutDelegate().dragOutCancelled(myDragOutSource); + } + protected void processDrag(MouseEvent event, Point targetScreenPoint, Point startPointScreen) { if (!myTabs.isTabDraggingEnabled()) return; @@ -245,6 +250,10 @@ class DragHelper extends MouseDragHelper { protected void processDragFinish(MouseEvent event, boolean willDragOutStart) { super.processDragFinish(event, willDragOutStart); + endDrag(willDragOutStart); + } + + private void endDrag(boolean willDragOutStart) { if (willDragOutStart) { myDragOutSource = myDragSource; } @@ -261,6 +270,11 @@ class DragHelper extends MouseDragHelper { myTabs.revalidate(); } + @Override + protected void processDragCancel() { + endDrag(false); + } + public TabInfo getDragSource() { return myDragSource; } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java index b7e486b158dc..a5e49d3bacb1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java @@ -581,6 +581,17 @@ final class EditorTabbedContainer implements Disposable, CloseAction.CloseTarget mySession = null; } + @Override + public void dragOutCancelled(TabInfo source) { + source.setHidden(false); + if (mySession != null) { + mySession.cancel(); + } + + myFile = null; + mySession = null; + } + class DockableEditor implements DockableContent { final Image myImg; private DockableEditorTabbedContainer myContainer; 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 2329cd55ef6c..8bc0890a0264 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 @@ -168,7 +168,7 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo if (each.isEmpty() && each.isDisposeWhenEmpty()) { DockWindow window = myWindows.getValue(each); if (window != null) { - window.setTransparrent(true); + window.setTransparent(true); } } } @@ -178,9 +178,9 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo } - private void stopCurrentDragSession() { + public void stopCurrentDragSession() { if (myCurrentDragSession != null) { - myCurrentDragSession.cancel(); + myCurrentDragSession.cancelSession(); myCurrentDragSession = null; myBusyObject.onReady(); @@ -188,7 +188,7 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo if (!each.isEmpty()) { DockWindow window = myWindows.getValue(each); if (window != null) { - window.setTransparrent(false); + window.setTransparent(false); } } } @@ -325,7 +325,12 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo } } + @Override public void cancel() { + stopCurrentDragSession(); + } + + private void cancelSession() { myWindow.dispose(); if (myCurrentOverContainer != null) { @@ -512,8 +517,8 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo myNorthPanel.repaint(); } - public void setTransparrent(boolean transparrent) { - if (transparrent) { + public void setTransparent(boolean transparent) { + if (transparent) { WindowManagerEx.getInstanceEx().setAlphaModeEnabled(getFrame(), true); WindowManagerEx.getInstanceEx().setAlphaModeRatio(getFrame(), 0.5f); } else {