blob: 3759c5afdb92d377121600a7ecda1623de8f7b89 [file] [log] [blame]
/*******************************************************************************
* 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);
}
}