From 459b455ac8d1bcd4a76908aa9eb13d6fe3b692b4 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 3 Mar 2011 18:09:23 +0300 Subject: [PATCH] IDEA-65902 Enable horizontal Scrolling with Mouse --- .../keymap/impl/IdeMouseEventDispatcher.java | 175 +++++++++++------- 1 file changed, 106 insertions(+), 69 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java index 397f38d26538..8bfba8722de3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java @@ -21,74 +21,71 @@ import com.intellij.openapi.actionSystem.ex.ActionManagerEx; import com.intellij.openapi.actionSystem.impl.PresentationFactory; import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.wm.impl.IdeGlassPaneImpl; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; import java.util.ArrayList; import java.util.Map; /** - * TODO[vova] rewrite comments * Current implementation of the dispatcher is intended to filter mouse event addressed to * the editor. Also it allows to map middle mouse's button to some action. * * @author Vladimir Kondratyev + * @author Konstantin Bulenkov */ -public final class IdeMouseEventDispatcher{ - private final PresentationFactory myPresentationFactory; - private final ArrayList myActions; - +public final class IdeMouseEventDispatcher { + private final PresentationFactory myPresentationFactory = new PresentationFactory(); + private final ArrayList myActions = new ArrayList(1); private final Map myRootPane2BlockedId = new HashMap(); - public IdeMouseEventDispatcher(){ - myPresentationFactory=new PresentationFactory(); - myActions=new ArrayList(1); + public IdeMouseEventDispatcher() { } - private void fillActionsList(Component component,MouseShortcut shortcut,boolean isModalContext){ + private void fillActionsList(Component component, MouseShortcut mouseShortcut, boolean isModalContext) { myActions.clear(); // here we try to find "local" shortcuts - - if(component instanceof JComponent){ - ArrayList listOfActions = (ArrayList)((JComponent)component).getClientProperty(AnAction.ourClientProperty); + if (component instanceof JComponent) { + final ArrayList listOfActions = (ArrayList)((JComponent)component).getClientProperty(AnAction.ourClientProperty); if (listOfActions != null) { for (AnAction action : listOfActions) { - Shortcut[] shortcuts = action.getShortcutSet().getShortcuts(); - for (Shortcut shortcut1 : shortcuts) { - if (shortcut.equals(shortcut1) && !myActions.contains(action)) { + final Shortcut[] shortcuts = action.getShortcutSet().getShortcuts(); + for (Shortcut shortcut : shortcuts) { + if (mouseShortcut.equals(shortcut) && !myActions.contains(action)) { myActions.add(action); } } } // once we've found a proper local shortcut(s), we exit - if (!myActions.isEmpty()) { + if (! myActions.isEmpty()) { return; } } } // search in main keymap - if (KeymapManagerImpl.ourKeymapManagerInitialized) { - KeymapManager keymapManager = KeymapManager.getInstance(); + final KeymapManager keymapManager = KeymapManager.getInstance(); if (keymapManager != null) { - Keymap keymap = keymapManager.getActiveKeymap(); - String[] actionIds=keymap.getActionIds(shortcut); + final Keymap keymap = keymapManager.getActiveKeymap(); + final String[] actionIds = keymap.getActionIds(mouseShortcut); ActionManager actionManager = ActionManager.getInstance(); for (String actionId : actionIds) { AnAction action = actionManager.getAction(actionId); - if (action == null) { - continue; - } - if (isModalContext && !action.isEnabledInModalContext()) { - continue; - } + + if (action == null) continue; + + if (isModalContext && !action.isEnabledInModalContext()) continue; + if (!myActions.contains(action)) { myActions.add(action); } @@ -99,84 +96,87 @@ public final class IdeMouseEventDispatcher{ /** * @return true if and only if the passed event is already dispatched by the - * IdeMouseEventDispatcher and there is no need for any other processing of the event. - * If the method returns false then it means that the event should be delivered - * to normal event dispatching. + * IdeMouseEventDispatcher and there is no need for any other processing of the event. + * If the method returns false then it means that the event should be delivered + * to normal event dispatching. */ - public boolean dispatchMouseEvent(MouseEvent e){ - boolean toIgnore = false; + public boolean dispatchMouseEvent(MouseEvent e) { + boolean ignore = false; if (!(e.getID() == MouseEvent.MOUSE_PRESSED || e.getID() == MouseEvent.MOUSE_RELEASED || e.getID() == MouseEvent.MOUSE_CLICKED)) { - toIgnore = true; + ignore = true; } - if( - e.isConsumed()|| - e.isPopupTrigger()|| - MouseEvent.MOUSE_RELEASED!=e.getID()|| - e.getClickCount()<1 ||// TODO[vova,anton] is it possible. it seems that yes! but how??? - e.getButton() == MouseEvent.NOBUTTON // See #16995. It did happen - ){ - toIgnore = true; + if (e.isConsumed() + || e.isPopupTrigger() + || MouseEvent.MOUSE_RELEASED != e.getID() + || e.getClickCount() < 1 // TODO[vova,anton] is it possible. it seems that yes! but how??? + || e.getButton() == MouseEvent.NOBUTTON) { // See #16995. It did happen + ignore = true; } - - JRootPane root = findRoot(e); - + final JRootPane root = findRoot(e); if (root != null) { final Integer lastId = myRootPane2BlockedId.get(root); if (lastId != null) { if (e.getID() <= lastId.intValue()) { myRootPane2BlockedId.remove(root); - } else { + } + else { myRootPane2BlockedId.put(root, e.getID()); return true; } } } - if (toIgnore) return false; - Component component=e.getComponent(); - if(component==null){ + Component component = e.getComponent(); + if (component == null) { throw new IllegalStateException("component cannot be null"); } - component=SwingUtilities.getDeepestComponentAt(component,e.getX(),e.getY()); + component = SwingUtilities.getDeepestComponentAt(component, e.getX(), e.getY()); if (component instanceof IdeGlassPaneImpl) { component = ((IdeGlassPaneImpl)component).getTargetComponentFor(e); } - if(component==null){ // do nothing if component doesn't contains specified point + if (component == null) { // do nothing if component doesn't contains specified point return false; } + if (isHorizontalScrolling(component, e)) { + boolean done = doHorizontalScrolling(component, (MouseWheelEvent)e); + if (done) return true; + } + + if (ignore) return false; + // avoid "cyclic component initialization error" in case of dialogs shown because of component initialization failure if (!KeymapManagerImpl.ourKeymapManagerInitialized) { return false; } - MouseShortcut shortcut=new MouseShortcut(e.getButton(),e.getModifiersEx(),e.getClickCount()); - fillActionsList(component,shortcut,IdeKeyEventDispatcher.isModalContext(component)); - ActionManagerEx actionManager=ActionManagerEx.getInstanceEx(); + final MouseShortcut shortcut = new MouseShortcut(e.getButton(), e.getModifiersEx(), e.getClickCount()); + fillActionsList(component, shortcut, IdeKeyEventDispatcher.isModalContext(component)); + ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); if (actionManager != null) { - for(int i=0;i