X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scenegraph%2Fsrc%2Forg%2Fsimantics%2Fscenegraph%2Fg2d%2Fevents%2FEventQueue.java;h=d3ab613557cc874858b40c36d76d4cf6555e57c3;hb=refs%2Fchanges%2F59%2F2659%2F2;hp=c4bfe82015e9992c03126d15c1acdada68533072;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/EventQueue.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/EventQueue.java index c4bfe8201..d3ab61355 100644 --- a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/EventQueue.java +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/EventQueue.java @@ -1,180 +1,200 @@ -/******************************************************************************* - * 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.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 listeners = new ListenerList(IEventQueueListener.class); - SyncListenerList listeners2 = new SyncListenerList(IEventQueueListener.class); - ListenerList coalescers = new ListenerList(EventCoalescer.class); - LinkedList queue = new LinkedList(); - - IEventHandler handler; - - public EventQueue(IEventHandler handler) { - assert (handler != null); - this.handler = handler; - } - - @Override - public int getEventMask() { - return EventTypes.AnyMask; - } - - @Override - public synchronized void queueEvent(Event e) { - // 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); - } - -} +/******************************************************************************* + * 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 listeners = new ListenerList(IEventQueueListener.class); + SyncListenerList listeners2 = new SyncListenerList(IEventQueueListener.class); + ListenerList coalescers = new ListenerList(EventCoalescer.class); + LinkedList queue = new LinkedList(); + + 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); + } + +}