/******************************************************************************* * Copyright (c) 2000, 2010 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.gef.ui.parts; import java.util.HashMap; import java.util.Map; import org.eclipse.swt.accessibility.ACC; import org.eclipse.swt.accessibility.AccessibleControlEvent; import org.eclipse.swt.accessibility.AccessibleControlListener; import org.eclipse.swt.accessibility.AccessibleEvent; import org.eclipse.swt.accessibility.AccessibleListener; import org.eclipse.swt.dnd.DragSourceEvent; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.TraverseEvent; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.widgets.Event; import org.eclipse.draw2d.EventDispatcher; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.InputEvent; import org.eclipse.draw2d.SWTEventDispatcher; import org.eclipse.draw2d.geometry.Point; import org.eclipse.gef.AccessibleEditPart; import org.eclipse.gef.EditDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPartViewer; /** * A special event dispatcher that will route events to the {@link EditDomain} * when appropriate. * <p> * IMPORTANT: This class is <EM>not</EM> intended to be used or subclassed by * clients. * * @author hudsonr */ public class DomainEventDispatcher extends SWTEventDispatcher { /** * The edit domain */ protected EditDomain domain; /** * The viewer on which this dispatcher is created. */ protected EditPartViewer viewer; private boolean editorCaptured = false; private Cursor overrideCursor; private Map accessibles = new HashMap(); private EditPartAccessibilityDispatcher accessibilityDispatcher; /** * Extended accessibility support for editpart. * * @author hudsonr */ protected class EditPartAccessibilityDispatcher extends AccessibilityDispatcher { private AccessibleEditPart get(int childID) { if (childID == ACC.CHILDID_SELF || childID == ACC.CHILDID_NONE) if (getViewer().getContents() != null) return (AccessibleEditPart) getViewer().getContents() .getAdapter(AccessibleEditPart.class); else return null; return (AccessibleEditPart) accessibles.get(new Integer(childID)); } /** * @see AccessibleControlListener#getChildAtPoint(AccessibleControlEvent) */ public void getChildAtPoint(AccessibleControlEvent e) { org.eclipse.swt.graphics.Point p = new org.eclipse.swt.graphics.Point( e.x, e.y); p = getViewer().getControl().toControl(p); EditPart part = getViewer().findObjectAt(new Point(p.x, p.y)); if (part == null) return; AccessibleEditPart acc = (AccessibleEditPart) part .getAdapter(AccessibleEditPart.class); if (acc != null) e.childID = acc.getAccessibleID(); } /** * @see AccessibleControlListener#getChildCount(AccessibleControlEvent) */ public void getChildCount(AccessibleControlEvent e) { AccessibleEditPart acc = get(e.childID); if (acc != null) acc.getChildCount(e); } /** * @see AccessibleControlListener#getChildren(AccessibleControlEvent) */ public void getChildren(AccessibleControlEvent e) { AccessibleEditPart acc = get(e.childID); if (acc != null) acc.getChildren(e); } /** * @see AccessibleControlListener#getDefaultAction(AccessibleControlEvent) */ public void getDefaultAction(AccessibleControlEvent e) { AccessibleEditPart acc = get(e.childID); if (acc != null) acc.getDefaultAction(e); } /** * @see AccessibleListener#getDescription(AccessibleEvent) */ public void getDescription(AccessibleEvent e) { AccessibleEditPart acc = get(e.childID); if (acc != null) acc.getDescription(e); } /** * @see AccessibleControlListener#getFocus(AccessibleControlEvent) */ public void getFocus(AccessibleControlEvent e) { AccessibleEditPart acc = (AccessibleEditPart) getViewer() .getFocusEditPart().getAdapter(AccessibleEditPart.class); if (acc != null) e.childID = acc.getAccessibleID(); } /** * @see AccessibleListener#getHelp(AccessibleEvent) */ public void getHelp(AccessibleEvent e) { AccessibleEditPart acc = get(e.childID); if (acc != null) acc.getHelp(e); } /** * @see AccessibleListener#getKeyboardShortcut(AccessibleEvent) */ public void getKeyboardShortcut(AccessibleEvent e) { AccessibleEditPart acc = get(e.childID); if (acc != null) acc.getKeyboardShortcut(e); } /** * @see AccessibleControlListener#getLocation(AccessibleControlEvent) */ public void getLocation(AccessibleControlEvent e) { AccessibleEditPart acc = get(e.childID); if (acc != null) acc.getLocation(e); } /** * @see AccessibleListener#getName(AccessibleEvent) */ public void getName(AccessibleEvent e) { AccessibleEditPart acc = get(e.childID); if (acc != null) acc.getName(e); } /** * @see AccessibleControlListener#getRole(AccessibleControlEvent) */ public void getRole(AccessibleControlEvent e) { AccessibleEditPart acc = get(e.childID); if (acc != null) acc.getRole(e); } /** * @see AccessibleControlListener#getSelection(AccessibleControlEvent) */ public void getSelection(AccessibleControlEvent e) { } /** * @see AccessibleControlListener#getState(AccessibleControlEvent) */ public void getState(AccessibleControlEvent e) { AccessibleEditPart acc = get(e.childID); if (acc != null) acc.getState(e); } /** * @see AccessibleControlListener#getValue(AccessibleControlEvent) */ public void getValue(AccessibleControlEvent e) { AccessibleEditPart acc = get(e.childID); if (acc != null) acc.getValue(e); } } /** * Constructs the dispatcher for the given domain and viewer. * * @param d * the domain * @param v * the viewer */ public DomainEventDispatcher(EditDomain d, EditPartViewer v) { domain = d; viewer = v; setEnableKeyTraversal(false); } /** * @see EventDispatcher#dispatchFocusGained(org.eclipse.swt.events.FocusEvent) */ public void dispatchFocusGained(FocusEvent event) { super.dispatchFocusGained(event); domain.focusGained(event, viewer); } /** * @see EventDispatcher#dispatchFocusLost(org.eclipse.swt.events.FocusEvent) */ public void dispatchFocusLost(FocusEvent event) { super.dispatchFocusLost(event); domain.focusLost(event, viewer); setRouteEventsToEditor(false); } /** * @see EventDispatcher#dispatchKeyPressed(org.eclipse.swt.events.KeyEvent) */ public void dispatchKeyPressed(org.eclipse.swt.events.KeyEvent e) { if (!editorCaptured) { super.dispatchKeyPressed(e); if (draw2dBusy()) return; } if (okToDispatch()) domain.keyDown(e, viewer); } /** * @see org.eclipse.draw2d.SWTEventDispatcher#dispatchKeyTraversed(org.eclipse.swt.events.TraverseEvent) */ public void dispatchKeyTraversed(TraverseEvent e) { if (!editorCaptured) { super.dispatchKeyTraversed(e); if (!e.doit) return; } if (okToDispatch()) domain.keyTraversed(e, viewer); } /** * @see EventDispatcher#dispatchKeyReleased(org.eclipse.swt.events.KeyEvent) */ public void dispatchKeyReleased(org.eclipse.swt.events.KeyEvent e) { if (!editorCaptured) { super.dispatchKeyReleased(e); if (draw2dBusy()) return; } if (okToDispatch()) domain.keyUp(e, viewer); } /** * @see EventDispatcher#dispatchMouseDoubleClicked(org.eclipse.swt.events.MouseEvent) */ public void dispatchMouseDoubleClicked(org.eclipse.swt.events.MouseEvent me) { if (!editorCaptured) { super.dispatchMouseDoubleClicked(me); if (draw2dBusy()) return; } if (okToDispatch()) domain.mouseDoubleClick(me, viewer); } /** * @see EventDispatcher#dispatchMouseEntered(org.eclipse.swt.events.MouseEvent) */ public void dispatchMouseEntered(org.eclipse.swt.events.MouseEvent me) { if (!editorCaptured) { super.dispatchMouseEntered(me); if (draw2dBusy()) return; } if (okToDispatch()) { domain.viewerEntered(me, viewer); } } /** * @see EventDispatcher#dispatchMouseExited(org.eclipse.swt.events.MouseEvent) */ public void dispatchMouseExited(org.eclipse.swt.events.MouseEvent me) { if (!editorCaptured) { super.dispatchMouseExited(me); if (draw2dBusy()) return; } if (okToDispatch()) { domain.viewerExited(me, viewer); } } /** * @see EventDispatcher#dispatchMouseHover(org.eclipse.swt.events.MouseEvent) */ public void dispatchMouseHover(org.eclipse.swt.events.MouseEvent me) { if (!editorCaptured) { super.dispatchMouseHover(me); if (draw2dBusy()) return; } if (okToDispatch()) domain.mouseHover(me, viewer); } /** * @see EventDispatcher#dispatchMousePressed(org.eclipse.swt.events.MouseEvent) */ public void dispatchMousePressed(org.eclipse.swt.events.MouseEvent me) { if (!editorCaptured) { super.dispatchMousePressed(me); if (draw2dBusy()) return; } if (okToDispatch()) { setFocus(null); control.forceFocus(); setRouteEventsToEditor(true); domain.mouseDown(me, viewer); } } /** * @see EventDispatcher#dispatchMouseMoved(org.eclipse.swt.events.MouseEvent) */ public void dispatchMouseMoved(org.eclipse.swt.events.MouseEvent me) { if (!editorCaptured) { super.dispatchMouseMoved(me); if (draw2dBusy()) return; } if (okToDispatch()) { if ((me.stateMask & InputEvent.ANY_BUTTON) != 0) domain.mouseDrag(me, viewer); else domain.mouseMove(me, viewer); } } /** * @see EventDispatcher#dispatchMouseReleased(org.eclipse.swt.events.MouseEvent) */ public void dispatchMouseReleased(org.eclipse.swt.events.MouseEvent me) { if (!editorCaptured) { super.dispatchMouseReleased(me); if (draw2dBusy()) return; } if (okToDispatch()) { setRouteEventsToEditor(false); domain.mouseUp(me, viewer); updateFigureUnderCursor(me); } } /** * Dispatches a drag finished event. * * @param event * the event * @param viewer * the viewer on which the event occured. */ public void dispatchNativeDragFinished(DragSourceEvent event, AbstractEditPartViewer viewer) { // $TODO delete the viewer parameter from the method domain.nativeDragFinished(event, viewer); } /** * Dispatches a drag started event. * * @param event * the event * @param viewer * the viewer */ public void dispatchNativeDragStarted(DragSourceEvent event, AbstractEditPartViewer viewer) { // $TODO delete the viewer parameter from the method setRouteEventsToEditor(false); domain.nativeDragStarted(event, viewer); } /** * Forwards the event to the EditDomain. * * @see org.eclipse.draw2d.EventDispatcher#dispatchMouseWheelScrolled(org.eclipse.swt.widgets.Event) */ public void dispatchMouseWheelScrolled(Event evt) { if (!editorCaptured) super.dispatchMouseWheelScrolled(evt); if (evt.doit && okToDispatch()) domain.mouseWheelScrolled(evt, viewer); } private boolean draw2dBusy() { if (getCurrentEvent() != null) if (getCurrentEvent().isConsumed()) return true; if (isCaptured()) return true; return false; } /** * Lazily creates and returns the accessibility dispatcher. * * @see org.eclipse.draw2d.EventDispatcher#getAccessibilityDispatcher() */ protected AccessibilityDispatcher getAccessibilityDispatcher() { if (accessibilityDispatcher == null) accessibilityDispatcher = new EditPartAccessibilityDispatcher(); return accessibilityDispatcher; } /** * Returns the viewer on which this dispatcher was created * * @return the viewer for this dispatcher */ protected final EditPartViewer getViewer() { return viewer; } private boolean okToDispatch() { return domain != null; } void putAccessible(AccessibleEditPart acc) { accessibles.put(new Integer(acc.getAccessibleID()), acc); } void removeAccessible(AccessibleEditPart acc) { accessibles.remove(new Integer(acc.getAccessibleID())); } /** * @see EventDispatcher#setCapture(IFigure) */ protected void setCapture(IFigure figure) { super.setCapture(figure); if (figure == null) { releaseCapture(); setRouteEventsToEditor(true); } } /** * @see SWTEventDispatcher#setCursor(Cursor) */ protected void setCursor(Cursor newCursor) { if (overrideCursor == null) super.setCursor(newCursor); else super.setCursor(overrideCursor); } /** * Sets whether events should go directly to the edit domain. * * @param value * <code>true</code> if all events should go directly to the edit * domain */ public void setRouteEventsToEditor(boolean value) { editorCaptured = value; } /** * Sets the override cursor. * * @param newCursor * the cursor */ public void setOverrideCursor(Cursor newCursor) { if (overrideCursor == newCursor) return; overrideCursor = newCursor; if (overrideCursor == null) updateCursor(); else setCursor(overrideCursor); } }