X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fdiagram%2Fparticipant%2FElementInteractor.java;h=ae9c1ce07a64da56e7c170149ea23d1261b00e9b;hb=HEAD;hp=aae577dfb663ddf96fa810ddd813106c9929e17c;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementInteractor.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementInteractor.java index aae577dfb..ae9c1ce07 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementInteractor.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementInteractor.java @@ -1,215 +1,215 @@ -/******************************************************************************* - * 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.g2d.diagram.participant; - -import java.awt.geom.Point2D; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.simantics.g2d.canvas.IMouseCaptureContext; -import org.simantics.g2d.canvas.IMouseCaptureHandle; -import org.simantics.g2d.canvas.IMouseCaptureHandleListener; -import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; -import org.simantics.g2d.diagram.handler.PickContext; -import org.simantics.g2d.diagram.handler.PickRequest; -import org.simantics.g2d.diagram.handler.PickRequest.PickSorter; -import org.simantics.g2d.element.IElement; -import org.simantics.g2d.element.handler.HandleMouseEvent; -import org.simantics.g2d.participant.TransformUtil; -import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; -import org.simantics.scenegraph.g2d.events.MouseEvent; -import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent; -import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent; - -/** - * This participant sends mouse events to elements that have a {@link HandleMouseEvent} - * handler. - * - * @see HandleMouseEvent - * @author Toni Kalajainen - */ -public class ElementInteractor extends AbstractDiagramParticipant { - - @Dependency PickContext pick; - @Dependency TransformUtil util; - - private PickSorter pickSorter; - - public static final int INTERACTOR_PRIORITY = Integer.MAX_VALUE-1; - - Map mouseCaptureMap = - new HashMap(); - Map mouseFocus = new HashMap(); - - public ElementInteractor() { - } - - public ElementInteractor(PickSorter pickSorter) { - this.pickSorter = pickSorter; - } - - private class ElementMouseCaptureHandle implements IMouseCaptureHandle { - IMouseCaptureHandle origHandle; - IElement element; - @Override - public void addMouseCaptureHandleListener(IMouseCaptureHandleListener listener) { - origHandle.addMouseCaptureHandleListener(listener); - } - @Override - public int mouseId() { - return origHandle.mouseId(); - } - @Override - public void release() { - mouseCaptureMap.remove(origHandle.mouseId()); - origHandle.release(); - } - @Override - public void removeMouseCaptureHandleListener(IMouseCaptureHandleListener listener) { - origHandle.removeMouseCaptureHandleListener(listener); - } - } - - /** - * Capture mouse events to an element. - * @param element - * @param mouseId - * @return capture handle or null if capture is not available in the context - */ - public IMouseCaptureHandle captureMouse(IElement element, int mouseId) - { - // Release old capture - ElementMouseCaptureHandle prevHnd = mouseCaptureMap.get(mouseId); - if (prevHnd!=null) { - prevHnd.release(); - mouseCaptureMap.remove(mouseId); - } - - // Check that capture is available - IMouseCaptureContext mcc = getContext().getMouseCaptureContext(); - if (mcc==null) return null; - - // make new capture - ElementMouseCaptureHandle hnd = new ElementMouseCaptureHandle(); - hnd.origHandle = mcc.captureMouse(mouseId); - hnd.element = element; - mouseCaptureMap.put(mouseId, hnd); - return hnd; - } - - /** - * Get all grabs of an element - * @param e element - * @return - */ - public Collection getGrabsOfElement(IElement e) - { - List result = new ArrayList(); - for (ElementMouseCaptureHandle eh : mouseCaptureMap.values()) - if (eh.element == e) - result.add(eh); - return result; - } - - public IMouseCaptureHandle getGrabOfElement(IElement e, int mouseId) - { - for (ElementMouseCaptureHandle eh : mouseCaptureMap.values()) - if (eh.element == e && eh.mouseId() == mouseId) - return eh; - return null; - } - - @EventHandler(priority = INTERACTOR_PRIORITY) - public boolean handleMouseEvent(MouseEvent me) { - assertDependencies(); - - // Determine element for capture - IElement currentFocus = null; - ElementMouseCaptureHandle hnd = mouseCaptureMap.get(me.mouseId); - // Mouse is captured - if (hnd != null) { - currentFocus = hnd.element; - //System.out.println("capture: " + hnd); - } else { - // Pick element under the mouse - Point2D controlPos = me.controlPosition; - Point2D diagramPos = util.controlToCanvas(controlPos, null); - PickRequest req = new PickRequest(diagramPos); - req.pickSorter = pickSorter; - //req.pickSorter = PickRequest.PickSorter.CONNECTIONS_LAST; - ArrayList result = new ArrayList(); - pick.pick(diagram, req, result); - if (result.size()>0) { - _sortByOrder(result); - currentFocus = result.get(result.size()-1); - //System.out.println("Focus " + currentFocus + " " + result.size()); - } - - } - - // Send enter & exit events to elements - IElement prevFocus = mouseFocus.get(me.mouseId); - // Focus has changed - if (currentFocus!=prevFocus) { - if (prevFocus!=null) { - MouseExitEvent exit = new MouseExitEvent(getContext(), me.time, me.mouseId, me.buttons, me.stateMask, me.controlPosition, me.screenPosition); - sendElementMouseEvent(prevFocus, exit); - } - if (currentFocus!=null) { - MouseEnterEvent enter = new MouseEnterEvent(getContext(), me.time, me.mouseId, me.buttons, me.stateMask, me.controlPosition, me.screenPosition); - sendElementMouseEvent(currentFocus, enter); - } - } - mouseFocus.put(me.mouseId, currentFocus); - - // Send event to all handlers - if (currentFocus==null) return false; - //return sendElementMouseEvent(currentFocus, me); - sendElementMouseEvent(currentFocus, me); - return false; - } - - private boolean sendElementMouseEvent(IElement e, MouseEvent me) - { - //System.out.println("sendElementMouseEvent(" + e + ", " + me + ")"); - // FIXME: eating events here will cause DND to not work. Workaround is to not eat the events. Need proper fix. - for (HandleMouseEvent eh : e.getElementClass().getItemsByClass(HandleMouseEvent.class)) - { - if (eh.handleMouseEvent(e, getContext(), me)) return false; - } - return false; - } - - // copy-paste from ZOrderhandler (list is reverse, so element on top is first) - void _sortByOrder(List list) - { - List elements = diagram.getElements(); - final Map position = new HashMap(); - for (IElement e : list) - position.put(e, elements.indexOf(e)); - Comparator c = new Comparator() { - @Override - public int compare(IElement o1, IElement o2) { - int pos1 = position.get(o1); - int pos2 = position.get(o2); - return pos1-pos2; - } - }; - Collections.sort(list, c); - } - -} +/******************************************************************************* + * 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.g2d.diagram.participant; + +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.simantics.g2d.canvas.IMouseCaptureContext; +import org.simantics.g2d.canvas.IMouseCaptureHandle; +import org.simantics.g2d.canvas.IMouseCaptureHandleListener; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.diagram.handler.PickContext; +import org.simantics.g2d.diagram.handler.PickRequest; +import org.simantics.g2d.diagram.handler.PickRequest.PickSorter; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.HandleMouseEvent; +import org.simantics.g2d.participant.TransformUtil; +import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; +import org.simantics.scenegraph.g2d.events.MouseEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent; + +/** + * This participant sends mouse events to elements that have a {@link HandleMouseEvent} + * handler. + * + * @see HandleMouseEvent + * @author Toni Kalajainen + */ +public class ElementInteractor extends AbstractDiagramParticipant { + + @Dependency PickContext pick; + @Dependency TransformUtil util; + + private PickSorter pickSorter; + + public static final int INTERACTOR_PRIORITY = Integer.MAX_VALUE-1; + + Map mouseCaptureMap = + new HashMap(); + Map mouseFocus = new HashMap(); + + public ElementInteractor() { + } + + public ElementInteractor(PickSorter pickSorter) { + this.pickSorter = pickSorter; + } + + private class ElementMouseCaptureHandle implements IMouseCaptureHandle { + IMouseCaptureHandle origHandle; + IElement element; + @Override + public void addMouseCaptureHandleListener(IMouseCaptureHandleListener listener) { + origHandle.addMouseCaptureHandleListener(listener); + } + @Override + public int mouseId() { + return origHandle.mouseId(); + } + @Override + public void release() { + mouseCaptureMap.remove(origHandle.mouseId()); + origHandle.release(); + } + @Override + public void removeMouseCaptureHandleListener(IMouseCaptureHandleListener listener) { + origHandle.removeMouseCaptureHandleListener(listener); + } + } + + /** + * Capture mouse events to an element. + * @param element + * @param mouseId + * @return capture handle or null if capture is not available in the context + */ + public IMouseCaptureHandle captureMouse(IElement element, int mouseId) + { + // Release old capture + ElementMouseCaptureHandle prevHnd = mouseCaptureMap.get(mouseId); + if (prevHnd!=null) { + prevHnd.release(); + mouseCaptureMap.remove(mouseId); + } + + // Check that capture is available + IMouseCaptureContext mcc = getContext().getMouseCaptureContext(); + if (mcc==null) return null; + + // make new capture + ElementMouseCaptureHandle hnd = new ElementMouseCaptureHandle(); + hnd.origHandle = mcc.captureMouse(mouseId); + hnd.element = element; + mouseCaptureMap.put(mouseId, hnd); + return hnd; + } + + /** + * Get all grabs of an element + * @param e element + * @return + */ + public Collection getGrabsOfElement(IElement e) + { + List result = new ArrayList(); + for (ElementMouseCaptureHandle eh : mouseCaptureMap.values()) + if (eh.element == e) + result.add(eh); + return result; + } + + public IMouseCaptureHandle getGrabOfElement(IElement e, int mouseId) + { + for (ElementMouseCaptureHandle eh : mouseCaptureMap.values()) + if (eh.element == e && eh.mouseId() == mouseId) + return eh; + return null; + } + + @EventHandler(priority = INTERACTOR_PRIORITY) + public boolean handleMouseEvent(MouseEvent me) { + assertDependencies(); + + // Determine element for capture + IElement currentFocus = null; + ElementMouseCaptureHandle hnd = mouseCaptureMap.get(me.mouseId); + // Mouse is captured + if (hnd != null) { + currentFocus = hnd.element; + //System.out.println("capture: " + hnd); + } else { + // Pick element under the mouse + Point2D controlPos = me.controlPosition; + Point2D diagramPos = util.controlToCanvas(controlPos, null); + PickRequest req = new PickRequest(diagramPos).context(getContext()); + req.pickSorter = pickSorter; + //req.pickSorter = PickRequest.PickSorter.CONNECTIONS_LAST; + ArrayList result = new ArrayList(); + pick.pick(diagram, req, result); + if (result.size()>0) { + _sortByOrder(result); + currentFocus = result.get(result.size()-1); + //System.out.println("Focus " + currentFocus + " " + result.size()); + } + + } + + // Send enter & exit events to elements + IElement prevFocus = mouseFocus.get(me.mouseId); + // Focus has changed + if (currentFocus!=prevFocus) { + if (prevFocus!=null) { + MouseExitEvent exit = new MouseExitEvent(getContext(), me.time, me.mouseId, me.buttons, me.stateMask, me.controlPosition, me.screenPosition); + sendElementMouseEvent(prevFocus, exit); + } + if (currentFocus!=null) { + MouseEnterEvent enter = new MouseEnterEvent(getContext(), me.time, me.mouseId, me.buttons, me.stateMask, me.controlPosition, me.screenPosition); + sendElementMouseEvent(currentFocus, enter); + } + } + mouseFocus.put(me.mouseId, currentFocus); + + // Send event to all handlers + if (currentFocus==null) return false; + //return sendElementMouseEvent(currentFocus, me); + sendElementMouseEvent(currentFocus, me); + return false; + } + + private boolean sendElementMouseEvent(IElement e, MouseEvent me) + { + //System.out.println("sendElementMouseEvent(" + e + ", " + me + ")"); + // FIXME: eating events here will cause DND to not work. Workaround is to not eat the events. Need proper fix. + for (HandleMouseEvent eh : e.getElementClass().getItemsByClass(HandleMouseEvent.class)) + { + if (eh.handleMouseEvent(e, getContext(), me)) return false; + } + return false; + } + + // copy-paste from ZOrderhandler (list is reverse, so element on top is first) + void _sortByOrder(List list) + { + List elements = diagram.getElements(); + final Map position = new HashMap(); + for (IElement e : list) + position.put(e, elements.indexOf(e)); + Comparator c = new Comparator() { + @Override + public int compare(IElement o1, IElement o2) { + int pos1 = position.get(o1); + int pos2 = position.get(o2); + return pos1-pos2; + } + }; + Collections.sort(list, c); + } + +}