]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/EventQueue.java
Duplicate MouseWheelMovedEvent was not actually fixed
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / events / EventQueue.java
index c4bfe82015e9992c03126d15c1acdada68533072..d3ab613557cc874858b40c36d76d4cf6555e57c3 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.scenegraph.g2d.events;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.LinkedList;\r
-\r
-import org.simantics.utils.datastructures.ListenerList;\r
-import org.simantics.utils.threads.IThreadWorkQueue;\r
-import org.simantics.utils.threads.SyncListenerList;\r
-\r
-/**\r
- * @see IEventQueue\r
- * @author Toni Kalajainen\r
- */\r
-public class EventQueue implements IEventQueue, IEventHandler {\r
-\r
-    ListenerList<IEventQueueListener>     listeners    = new ListenerList<IEventQueueListener>(IEventQueueListener.class);\r
-    SyncListenerList<IEventQueueListener> listeners2   = new SyncListenerList<IEventQueueListener>(IEventQueueListener.class);\r
-    ListenerList<EventCoalescer>          coalescers = new ListenerList<EventCoalescer>(EventCoalescer.class);\r
-    LinkedList<Event>                     queue        = new LinkedList<Event>();\r
-\r
-    IEventHandler                         handler;\r
-\r
-    public EventQueue(IEventHandler handler) {\r
-        assert (handler != null);\r
-        this.handler = handler;\r
-    }\r
-\r
-    @Override\r
-    public int getEventMask() {\r
-        return EventTypes.AnyMask;\r
-    }\r
-\r
-    @Override\r
-    public synchronized void queueEvent(Event e) {\r
-        // coalesce with last\r
-        EventCoalescer[] css = coalescers.getListeners();\r
-        if (css.length > 0 && !queue.isEmpty()) {\r
-            Event last = queue.get(queue.size() - 1);\r
-            Event coalesced = null;\r
-            for (EventCoalescer ecs : css) {\r
-                coalesced = ecs.coalesce(last, e);\r
-                if (coalesced != null)\r
-                    break;\r
-            }\r
-            if (coalesced == last)\r
-                return;\r
-            if (coalesced != null) {\r
-                // replace last with coalesced\r
-                queue.remove(queue.size() - 1);\r
-                queue.addLast(coalesced);\r
-                int index = queue.size() - 1;\r
-                fireEventAdded(coalesced, index);\r
-                return;\r
-            }\r
-        }\r
-\r
-        queue.addLast(e);\r
-        int index = queue.size() - 1;\r
-        fireEventAdded(e, index);\r
-    }\r
-\r
-    @Override\r
-    public synchronized void queueFirst(Event e) {\r
-        // coalescale with first\r
-        EventCoalescer[] css = coalescers.getListeners();\r
-        if (css.length > 0 && !queue.isEmpty()) {\r
-            Event first = queue.get(0);\r
-            Event coalesced = null;\r
-            for (EventCoalescer ecs : css) {\r
-                coalesced = ecs.coalesce(e, first);\r
-                if (coalesced != null)\r
-                    break;\r
-            }\r
-            if (coalesced == first)\r
-                return;\r
-            if (coalesced != null) {\r
-                // replace last with coalesced\r
-                queue.remove(0);\r
-                queue.addFirst(coalesced);\r
-                fireEventAdded(coalesced, 0);\r
-                return;\r
-            }\r
-        }\r
-\r
-        queue.addFirst(e);\r
-        fireEventAdded(e, 0);\r
-    }\r
-\r
-    public void handleEvents() {\r
-        int eventsHandled = 0;\r
-        Event[] events = null;\r
-        do {\r
-            synchronized (this) {\r
-                events = queue.toArray(new Event[queue.size()]);\r
-                queue.clear();\r
-            }\r
-            for (Event e : events) {\r
-                if (EventTypes.passes(handler, e))\r
-                    handler.handleEvent(e);\r
-                eventsHandled++;\r
-            }\r
-        } while (events.length > 0);\r
-        if (eventsHandled > 0)\r
-            fireQueueEmpty();\r
-    }\r
-\r
-    @Override\r
-    public void addEventCoalesceler(EventCoalescer coalescaler) {\r
-        coalescers.add(coalescaler);\r
-    }\r
-\r
-    @Override\r
-    public void removeEventCoalesceler(EventCoalescer coalescaler) {\r
-        coalescers.remove(coalescaler);\r
-    }\r
-\r
-    @Override\r
-    public boolean handleEvent(Event e) {\r
-        handleEvents();\r
-        return EventTypes.passes(handler, e) ? handler.handleEvent(e) : false;\r
-    }\r
-\r
-    @Override\r
-    public void addQueueListener(IEventQueueListener listener) {\r
-        listeners.add(listener);\r
-    }\r
-\r
-    @Override\r
-    public synchronized int size() {\r
-        return queue.size();\r
-    }\r
-\r
-    @Override\r
-    public synchronized boolean isEmpty() {\r
-        return queue.isEmpty();\r
-    }\r
-\r
-    @Override\r
-    public void removeQueueListener(IEventQueueListener listener) {\r
-        listeners.remove(listener);\r
-    }\r
-\r
-    Method onEventAdded = SyncListenerList.getMethod(IEventQueueListener.class, "onEventAdded");\r
-\r
-    protected void fireEventAdded(Event e, int index) {\r
-        for (IEventQueueListener eql : listeners.getListeners())\r
-            eql.onEventAdded(this, e, index);\r
-        listeners2.fireEventSync(onEventAdded, this, e, index);\r
-    }\r
-\r
-    Method onQueueEmpty = SyncListenerList.getMethod(IEventQueueListener.class, "onQueueEmpty");\r
-\r
-    protected void fireQueueEmpty() {\r
-        for (IEventQueueListener eql : listeners.getListeners())\r
-            eql.onQueueEmpty(this);\r
-        listeners2.fireEventSync(onQueueEmpty, this);\r
-    }\r
-\r
-    @Override\r
-    public void addQueueListener(IEventQueueListener listener, IThreadWorkQueue thread) {\r
-        listeners2.add(thread, listener);\r
-    }\r
-\r
-    @Override\r
-    public void removeQueueListener(IEventQueueListener listener, IThreadWorkQueue thread) {\r
-        listeners2.remove(thread, listener);\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.scenegraph.g2d.events;
+
+import java.lang.reflect.Method;
+import java.util.LinkedList;
+
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseWheelMovedEvent;
+import org.simantics.utils.datastructures.ListenerList;
+import org.simantics.utils.threads.IThreadWorkQueue;
+import org.simantics.utils.threads.SyncListenerList;
+
+/**
+ * @see IEventQueue
+ * @author Toni Kalajainen
+ */
+public class EventQueue implements IEventQueue, IEventHandler {
+
+    ListenerList<IEventQueueListener>     listeners    = new ListenerList<IEventQueueListener>(IEventQueueListener.class);
+    SyncListenerList<IEventQueueListener> listeners2   = new SyncListenerList<IEventQueueListener>(IEventQueueListener.class);
+    ListenerList<EventCoalescer>          coalescers = new ListenerList<EventCoalescer>(EventCoalescer.class);
+    LinkedList<Event>                     queue        = new LinkedList<Event>();
+
+    IEventHandler                         handler;
+
+    public EventQueue(IEventHandler handler) {
+        assert (handler != null);
+        this.handler = handler;
+    }
+
+    @Override
+    public int getEventMask() {
+        return EventTypes.AnyMask;
+    }
+
+    private static final String DISABLE_DUPLICATE_REMOVAL = "org.simantics.scenegraph.g2d.events.disableDuplicateMouseWheelEvent";
+    private static final boolean IGNORE_DUPLICATE = !Boolean.parseBoolean(System.getProperty(DISABLE_DUPLICATE_REMOVAL));
+    
+    private boolean ignoreDuplicateMouseWheelMovedEvent(Event e) {
+        if (IGNORE_DUPLICATE && e instanceof MouseWheelMovedEvent) {
+            MouseWheelMovedEvent event = (MouseWheelMovedEvent) e;
+            // if (e.time > 0 && (lastMouseWheelMovedEvent != null && lastMouseWheelMovedEvent.time < 0)) {
+            // apparently this is a better way to distinguish between SWT & AWT events
+            // SWT based event constructs the scrollAmount to = 0
+            // See org.simantics.g2d.event.adapter.SWTMouseEventAdapter.mouseScrolled(MouseEvent) L171
+            if (event.scrollAmount != MouseWheelMovedEvent.SCROLL_AMOUNT_ZERO) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    @Override
+    public synchronized void queueEvent(Event e) {
+        if (ignoreDuplicateMouseWheelMovedEvent(e))
+            return;
+        // coalesce with last
+        EventCoalescer[] css = coalescers.getListeners();
+        if (css.length > 0 && !queue.isEmpty()) {
+            Event last = queue.get(queue.size() - 1);
+            Event coalesced = null;
+            for (EventCoalescer ecs : css) {
+                coalesced = ecs.coalesce(last, e);
+                if (coalesced != null)
+                    break;
+            }
+            if (coalesced == last)
+                return;
+            if (coalesced != null) {
+                // replace last with coalesced
+                queue.remove(queue.size() - 1);
+                queue.addLast(coalesced);
+                int index = queue.size() - 1;
+                fireEventAdded(coalesced, index);
+                return;
+            }
+        }
+
+        queue.addLast(e);
+        int index = queue.size() - 1;
+        fireEventAdded(e, index);
+    }
+
+    @Override
+    public synchronized void queueFirst(Event e) {
+        // coalescale with first
+        EventCoalescer[] css = coalescers.getListeners();
+        if (css.length > 0 && !queue.isEmpty()) {
+            Event first = queue.get(0);
+            Event coalesced = null;
+            for (EventCoalescer ecs : css) {
+                coalesced = ecs.coalesce(e, first);
+                if (coalesced != null)
+                    break;
+            }
+            if (coalesced == first)
+                return;
+            if (coalesced != null) {
+                // replace last with coalesced
+                queue.remove(0);
+                queue.addFirst(coalesced);
+                fireEventAdded(coalesced, 0);
+                return;
+            }
+        }
+
+        queue.addFirst(e);
+        fireEventAdded(e, 0);
+    }
+
+    public void handleEvents() {
+        int eventsHandled = 0;
+        Event[] events = null;
+        do {
+            synchronized (this) {
+                events = queue.toArray(new Event[queue.size()]);
+                queue.clear();
+            }
+            for (Event e : events) {
+                if (EventTypes.passes(handler, e))
+                    handler.handleEvent(e);
+                eventsHandled++;
+            }
+        } while (events.length > 0);
+        if (eventsHandled > 0)
+            fireQueueEmpty();
+    }
+
+    @Override
+    public void addEventCoalesceler(EventCoalescer coalescaler) {
+        coalescers.add(coalescaler);
+    }
+
+    @Override
+    public void removeEventCoalesceler(EventCoalescer coalescaler) {
+        coalescers.remove(coalescaler);
+    }
+
+    @Override
+    public boolean handleEvent(Event e) {
+        handleEvents();
+        return EventTypes.passes(handler, e) ? handler.handleEvent(e) : false;
+    }
+
+    @Override
+    public void addQueueListener(IEventQueueListener listener) {
+        listeners.add(listener);
+    }
+
+    @Override
+    public synchronized int size() {
+        return queue.size();
+    }
+
+    @Override
+    public synchronized boolean isEmpty() {
+        return queue.isEmpty();
+    }
+
+    @Override
+    public void removeQueueListener(IEventQueueListener listener) {
+        listeners.remove(listener);
+    }
+
+    Method onEventAdded = SyncListenerList.getMethod(IEventQueueListener.class, "onEventAdded");
+
+    protected void fireEventAdded(Event e, int index) {
+        for (IEventQueueListener eql : listeners.getListeners())
+            eql.onEventAdded(this, e, index);
+        listeners2.fireEventSync(onEventAdded, this, e, index);
+    }
+
+    Method onQueueEmpty = SyncListenerList.getMethod(IEventQueueListener.class, "onQueueEmpty");
+
+    protected void fireQueueEmpty() {
+        for (IEventQueueListener eql : listeners.getListeners())
+            eql.onQueueEmpty(this);
+        listeners2.fireEventSync(onQueueEmpty, this);
+    }
+
+    @Override
+    public void addQueueListener(IEventQueueListener listener, IThreadWorkQueue thread) {
+        listeners2.add(thread, listener);
+    }
+
+    @Override
+    public void removeQueueListener(IEventQueueListener listener, IThreadWorkQueue thread) {
+        listeners2.remove(thread, listener);
+    }
+
+}