| /******************************************************************************* |
| * 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); |
| } |
| |
| } |