From cbb06d5993eef9428f6944dabe0b31a552f1edfb Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 16 Aug 2013 00:56:06 +0200 Subject: [PATCH] use mouse dispatcher for sensitive mouse detection --- .../wm/impl/status/IdeStatusBarImpl.java | 46 ++--- .../wm/impl/status/ToolWindowsWidget.java | 168 ++++++++++-------- 2 files changed, 118 insertions(+), 96 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java index 5942f087391a..993259056821 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java @@ -72,7 +72,7 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx { private final List myCustomComponentIds = new ArrayList(); private final Set myChildren = new HashSet(); - private ToolWindowsWidget myToolWindowWidget; + //private ToolWindowsWidget myToolWindowWidget; private static class WidgetBean { JComponent component; @@ -164,7 +164,7 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx { } if (master == null) { - addWidget(myToolWindowWidget = new ToolWindowsWidget(this), Position.LEFT); + addWidget(new ToolWindowsWidget(this), Position.LEFT); } enableEvents(AWTEvent.MOUSE_EVENT_MASK); @@ -254,28 +254,28 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx { myCustomComponentIds.add(customId); } - @Override - protected void processMouseMotionEvent(MouseEvent e) { - final Point point = e.getPoint(); - if (myToolWindowWidget != null) { - if(point.x < 42 && 0 <= point.y && point.y <= getHeight()) { - myToolWindowWidget.mouseEntered(); - } else { - myToolWindowWidget.mouseExited(); - } - } - super.processMouseMotionEvent(e); - } + //@Override + //protected void processMouseMotionEvent(MouseEvent e) { + // final Point point = e.getPoint(); + // if (myToolWindowWidget != null) { + // if(point.x < 42 && 0 <= point.y && point.y <= getHeight()) { + // myToolWindowWidget.mouseEntered(); + // } else { + // myToolWindowWidget.mouseExited(); + // } + // } + // super.processMouseMotionEvent(e); + //} - @Override - protected void processMouseEvent(MouseEvent e) { - if (e.getID() == MouseEvent.MOUSE_EXITED && myToolWindowWidget != null) { - if (!new Rectangle(0,0,22, getHeight()).contains(e.getPoint())) { - myToolWindowWidget.mouseExited(); - } - } - super.processMouseEvent(e); - } + //@Override + //protected void processMouseEvent(MouseEvent e) { + // if (e.getID() == MouseEvent.MOUSE_EXITED && myToolWindowWidget != null) { + // if (!new Rectangle(0,0,22, getHeight()).contains(e.getPoint())) { + // myToolWindowWidget.mouseExited(); + // } + // } + // super.processMouseEvent(e); + //} @Override public void removeCustomIndicationComponent(@NotNull final JComponent c) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java index 7680bebc0a22..6abb0fe1eafb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java @@ -16,6 +16,7 @@ package com.intellij.openapi.wm.impl.status; import com.intellij.icons.AllIcons; +import com.intellij.ide.IdeEventQueue; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.UISettingsListener; import com.intellij.openapi.Disposable; @@ -38,7 +39,6 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -52,6 +52,7 @@ class ToolWindowsWidget extends JLabel implements CustomStatusBarWidget, StatusB private final Alarm myAlarm; private StatusBar myStatusBar; private JBPopup popup; + private boolean wasExited = false; ToolWindowsWidget(Disposable parent) { new BaseButtonBehavior(this, TimedDeadzone.NULL) { @@ -61,95 +62,116 @@ class ToolWindowsWidget extends JLabel implements CustomStatusBarWidget, StatusB } }.setActionTrigger(MouseEvent.MOUSE_PRESSED); + IdeEventQueue.getInstance().addDispatcher(new IdeEventQueue.EventDispatcher() { + @Override + public boolean dispatch(AWTEvent e) { + if (e instanceof MouseEvent) { + if (e.getID() == MouseEvent.MOUSE_MOVED && isVisible()) { + Point p = ((MouseEvent)e).getLocationOnScreen(); + Point screen = ToolWindowsWidget.this.getLocationOnScreen(); + if (new Rectangle(screen.x - 4, screen.y - 2, getWidth() + 4, getHeight() + 4).contains(p)) { + mouseEntered(); + wasExited = false; + } else { + if (!wasExited) { + wasExited = mouseExited(p); + } + } + } + } + return false; + } + }, parent); + UISettings.getInstance().addUISettingsListener(this, this); KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("focusOwner", this); myAlarm = new Alarm(parent); } - public void mouseExited() { + public boolean mouseExited(Point currentLocationOnScreen) { myAlarm.cancelAllRequests(); + if (popup != null && popup.isVisible()) { + final Point screen = popup.getLocationOnScreen(); + final Rectangle popupScreenRect = new Rectangle(screen.x, screen.y, popup.getSize().width, popup.getSize().height); + if (! popupScreenRect.contains(currentLocationOnScreen)) { + myAlarm.cancelAllRequests(); + myAlarm.addRequest(new Runnable() { + @Override + public void run() { + if (popup != null && popup.isVisible()) { + popup.cancel(); + } + } + }, 150); + return true; + } + } + return false; } public void mouseEntered() { - if (myAlarm.getActiveRequestCount() == 0) - myAlarm.addRequest(new Runnable() { - @Override - public void run() { - DefaultListModel model = new DefaultListModel(); - final IdeFrameImpl frame = UIUtil.getParentOfType(IdeFrameImpl.class, ToolWindowsWidget.this); - if (frame == null) return; - final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(frame.getProject()); - for (String id : toolWindowManager.getToolWindowIds()) { - final ToolWindow tw = toolWindowManager.getToolWindow(id); - if (tw.isAvailable()) { - model.addElement(tw); - } - } - - final JBList list = new JBList(model); - list.addMouseListener(new MouseAdapter() { - @Override - public void mouseEntered(MouseEvent e) { - myAlarm.cancelAllRequests(); + if (myAlarm.getActiveRequestCount() == 0) { + myAlarm.addRequest(new Runnable() { + @Override + public void run() { + DefaultListModel model = new DefaultListModel(); + final IdeFrameImpl frame = UIUtil.getParentOfType(IdeFrameImpl.class, ToolWindowsWidget.this); + if (frame == null) return; + final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(frame.getProject()); + for (String id : toolWindowManager.getToolWindowIds()) { + final ToolWindow tw = toolWindowManager.getToolWindow(id); + if (tw.isAvailable()) { + model.addElement(tw); + } } - @Override - public void mouseExited(MouseEvent e) { - myAlarm.addRequest(new Runnable() { + final JBList list = new JBList(model); + list.setCellRenderer(new ListCellRenderer() { + final JBLabel label = new JBLabel(); + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + final ToolWindow toolWindow = (ToolWindow)value; + label.setText(toolWindow instanceof ToolWindowImpl ? ((ToolWindowImpl)toolWindow).getId() : toolWindow.getTitle()); + label.setIcon(toolWindow.getIcon()); + label.setBorder(IdeBorderFactory.createEmptyBorder(4, 10, 4, 10)); + label.setForeground(UIUtil.getListForeground(isSelected)); + label.setBackground(UIUtil.getListBackground(isSelected)); + final JPanel panel = new JPanel(new BorderLayout()); + panel.add(label, BorderLayout.CENTER); + panel.setBackground(UIUtil.getListBackground(isSelected)); + return panel; + } + }); + + final Dimension size = list.getPreferredSize(); + final JComponent c = ToolWindowsWidget.this; + final RelativePoint point = new RelativePoint(c, new Point(-4, -4 - size.height)); + + + if (popup != null && popup.isVisible()) { + return; + } + + list.setSelectedIndex(list.getItemsCount() - 1); + popup = JBPopupFactory.getInstance().createListPopupBuilder(list) + .setAutoselectOnMouseMove(true) + .setItemChoosenCallback(new Runnable() { @Override public void run() { - if (popup != null && popup.isVisible()) { - popup.cancel(); + if (popup != null) popup.closeOk(null); + final Object value = list.getSelectedValue(); + if (value instanceof ToolWindow) { + ((ToolWindow)value).activate(null, true, true); } } - }, 300); - } - }); - list.setCellRenderer(new ListCellRenderer() { - final JBLabel label = new JBLabel(); + }) + .createPopup(); - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - final ToolWindow toolWindow = (ToolWindow)value; - label.setText(toolWindow instanceof ToolWindowImpl ? ((ToolWindowImpl)toolWindow).getId() : toolWindow.getTitle()); - label.setIcon(toolWindow.getIcon()); - label.setBorder(IdeBorderFactory.createEmptyBorder(4, 10, 4, 10)); - label.setForeground(UIUtil.getListForeground(isSelected)); - label.setBackground(UIUtil.getListBackground(isSelected)); - final JPanel panel = new JPanel(new BorderLayout()); - panel.add(label, BorderLayout.CENTER); - panel.setBackground(UIUtil.getListBackground(isSelected)); - return panel; - } - }); - - final Dimension size = list.getPreferredSize(); - final JComponent c = ToolWindowsWidget.this; - final RelativePoint point = new RelativePoint(c, new Point(-4, -10 - size.height)); - - - if (popup != null && popup.isVisible()) { - return; + popup.show(point); } - - list.setSelectedIndex(list.getItemsCount() - 1); - popup = JBPopupFactory.getInstance().createListPopupBuilder(list) - .setAutoselectOnMouseMove(true) - .setItemChoosenCallback(new Runnable() { - @Override - public void run() { - if (popup != null) popup.closeOk(null); - final Object value = list.getSelectedValue(); - if (value instanceof ToolWindow) { - ((ToolWindow)value).activate(null, true, true); - } - } - }) - .createPopup(); - - popup.show(point); - } - }, 300); + }, 300); + } } @Override