| /****************************************************************************** |
| * Copyright (c) 2000, 2003, 2006 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.gmf.runtime.diagram.ui.internal.parts; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.PositionConstants; |
| import org.eclipse.draw2d.Viewport; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.gef.EditPart; |
| import org.eclipse.gef.GraphicalEditPart; |
| import org.eclipse.gef.GraphicalViewer; |
| import org.eclipse.gef.RootEditPart; |
| import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.KeyEvent; |
| |
| /** |
| * @author melaasar |
| * @canBeSeenBy org.eclipse.gmf.runtime.diagram.ui.* |
| * |
| * To change the template for this generated type comment go to |
| * Window>Preferences>Java>Code Generation>Code and Comments |
| * |
| * <p> |
| * Code taken from Eclipse reference bugzilla #98820 |
| * |
| */ |
| public class DiagramGraphicalViewerKeyHandler |
| extends GraphicalViewerKeyHandler { |
| |
| /** |
| * @param viewer |
| */ |
| public DiagramGraphicalViewerKeyHandler(GraphicalViewer viewer) { |
| super(viewer); |
| } |
| |
| /** |
| * @see org.eclipse.gef.KeyHandler#keyPressed(org.eclipse.swt.events.KeyEvent) |
| */ |
| public boolean keyPressed(KeyEvent event) { |
| switch (event.keyCode) { |
| case SWT.HOME : |
| if ((event.stateMask & SWT.ALT) != 0) { |
| if (navigateEndSibling(event, PositionConstants.WEST)) |
| return true; |
| } else { |
| if (navigateEndSibling(event, PositionConstants.NORTH)) |
| return true; |
| } |
| break; |
| case SWT.END : |
| if ((event.stateMask & SWT.ALT) != 0) { |
| if (navigateEndSibling(event, PositionConstants.EAST)) |
| return true; |
| } else { |
| if (navigateEndSibling(event, PositionConstants.SOUTH)) |
| return true; |
| } |
| break; |
| case SWT.PAGE_UP : |
| if ((event.stateMask & SWT.ALT) != 0) { |
| if (navigatePageSibling(event, PositionConstants.WEST)) |
| return true; |
| } else { |
| if (navigatePageSibling(event, PositionConstants.NORTH)) |
| return true; |
| } |
| break; |
| case SWT.PAGE_DOWN : |
| if ((event.stateMask & SWT.ALT) != 0) { |
| if (navigatePageSibling(event, PositionConstants.EAST)) |
| return true; |
| } else { |
| if (navigatePageSibling(event, PositionConstants.SOUTH)) |
| return true; |
| } |
| } |
| return super.keyPressed(event); |
| } |
| |
| /** |
| * @return |
| */ |
| protected GraphicalEditPart getFocusPart() { |
| return (GraphicalEditPart) getViewer().getFocusEditPart(); |
| } |
| |
| /** |
| * @param part |
| * @param event |
| */ |
| protected void navigateToPart(EditPart part, KeyEvent event) { |
| if (part == null) |
| return; |
| if (!part.isSelectable()) { |
| getViewer().deselectAll(); |
| getViewer().setFocus(part); |
| } else if ((event.stateMask & SWT.SHIFT) != 0) { |
| getViewer().appendSelection(part); |
| getViewer().setFocus(part); |
| } else if ((event.stateMask & SWT.CONTROL) != 0) |
| getViewer().setFocus(part); |
| else |
| getViewer().select(part); |
| getViewer().reveal(part); |
| } |
| |
| /** |
| * @return |
| */ |
| protected List getPartNavigationSiblings() { |
| EditPart epParent = findParent(getFocusPart()); |
| if (epParent != null) |
| return epParent.getChildren(); |
| else |
| return null; |
| } |
| |
| /** |
| * @param figure |
| * @return |
| */ |
| protected Point getFigureInterestingPoint(IFigure figure) { |
| return figure.getBounds().getCenter(); |
| } |
| |
| protected Viewport findViewport(GraphicalEditPart part) { |
| if (part == null) |
| return null; |
| |
| IFigure figure = null; |
| Viewport port = null; |
| do { |
| if (figure == null) |
| figure = part.getContentPane(); |
| else |
| figure = figure.getParent(); |
| if (figure instanceof Viewport) { |
| port = (Viewport) figure; |
| break; |
| } |
| } while (figure != null); |
| return port; |
| } |
| |
| /** |
| * @param event |
| * @param direction |
| * @param page |
| * @param list |
| * @return |
| */ |
| protected boolean navigatePageSibling(KeyEvent event, int direction) { |
| GraphicalEditPart epStart = getFocusPart(); |
| IFigure figure = epStart.getFigure(); |
| Point pStart = getFigureInterestingPoint(figure); |
| figure.translateToAbsolute(pStart); |
| |
| GraphicalEditPart epParent = (GraphicalEditPart) findParent(epStart); |
| Viewport viewport = findViewport(epParent); |
| Rectangle bounds = |
| (viewport != null) |
| ? new Rectangle(viewport.getBounds()) |
| : epParent.getFigure().getClientArea(); |
| figure.translateToAbsolute(bounds); |
| int pageDistance = 0; |
| switch (direction) { |
| case PositionConstants.NORTH : |
| case PositionConstants.SOUTH : |
| pageDistance = bounds.height; |
| break; |
| case PositionConstants.EAST : |
| case PositionConstants.WEST : |
| pageDistance = bounds.width; |
| break; |
| } |
| |
| List editParts = |
| findPageSibling( |
| getPartNavigationSiblings(), |
| pStart, |
| pageDistance, |
| direction, |
| epStart); |
| if (editParts.isEmpty()) |
| return false; |
| if ((event.stateMask & SWT.SHIFT) != 0) { |
| Iterator parts = editParts.iterator(); |
| while (parts.hasNext()) |
| navigateToPart((EditPart) parts.next(), event); |
| } else { |
| EditPart part = (EditPart) editParts.get(editParts.size() - 1); |
| navigateToPart(part, event); |
| } |
| return true; |
| } |
| |
| /** |
| * @param event |
| * @param direction |
| * @param list |
| * @return |
| */ |
| protected boolean navigateEndSibling(KeyEvent event, int direction) { |
| GraphicalEditPart epStart = getFocusPart(); |
| IFigure figure = epStart.getFigure(); |
| Point pStart = getFigureInterestingPoint(figure); |
| figure.translateToAbsolute(pStart); |
| List editParts = |
| findEndSibling( |
| getPartNavigationSiblings(), |
| pStart, |
| direction, |
| epStart); |
| if (editParts.isEmpty()) |
| return false; |
| if ((event.stateMask & SWT.SHIFT) != 0) { |
| Iterator parts = editParts.iterator(); |
| while (parts.hasNext()) |
| navigateToPart((EditPart) parts.next(), event); |
| } else { |
| EditPart part = (EditPart) editParts.get(editParts.size() - 1); |
| navigateToPart(part, event); |
| } |
| return true; |
| } |
| |
| /** |
| * @param siblings |
| * @param pStart |
| * @param minDistance |
| * @param direction |
| * @param exclude |
| * @return |
| */ |
| private List findPageSibling( |
| List siblings, |
| Point pStart, |
| int pageDistance, |
| int direction, |
| EditPart exclude) { |
| GraphicalEditPart epCurrent; |
| GraphicalEditPart epFinal = null; |
| List selection = new ArrayList(); |
| IFigure figure; |
| Point pCurrent; |
| int distance = 0; |
| |
| Iterator iter = siblings.iterator(); |
| while (iter.hasNext()) { |
| epCurrent = (GraphicalEditPart) iter.next(); |
| if (epCurrent == exclude |
| || !epCurrent.getFigure().isVisible() |
| || epCurrent.getFigure().getBounds().isEmpty()) |
| continue; |
| figure = epCurrent.getFigure(); |
| pCurrent = getFigureInterestingPoint(figure); |
| figure.translateToAbsolute(pCurrent); |
| if (pStart.getPosition(pCurrent) != direction) |
| continue; |
| |
| int d = pCurrent.getDistanceOrthogonal(pStart); |
| if (d <= pageDistance) { |
| selection.add(epCurrent); |
| if (d > distance) { |
| distance = d; |
| epFinal = epCurrent; |
| } |
| } |
| if (epFinal != null) { |
| selection.remove(epFinal); |
| selection.add(epFinal); |
| } |
| } |
| return selection; |
| } |
| |
| /** |
| * @param siblings |
| * @param pStart |
| * @param direction |
| * @param exclude |
| * @return |
| */ |
| private List findEndSibling( |
| List siblings, |
| Point pStart, |
| int direction, |
| EditPart exclude) { |
| GraphicalEditPart epCurrent; |
| GraphicalEditPart epFinal = null; |
| List selection = new ArrayList(); |
| IFigure figure; |
| Point pCurrent; |
| int distance = 0; |
| |
| Iterator iter = siblings.iterator(); |
| while (iter.hasNext()) { |
| epCurrent = (GraphicalEditPart) iter.next(); |
| if (epCurrent == exclude |
| || !epCurrent.getFigure().isVisible() |
| || epCurrent.getFigure().getBounds().isEmpty()) |
| continue; |
| figure = epCurrent.getFigure(); |
| pCurrent = getFigureInterestingPoint(figure); |
| figure.translateToAbsolute(pCurrent); |
| if (pStart.getPosition(pCurrent) != direction) |
| continue; |
| |
| selection.add(epCurrent); |
| int d = pCurrent.getDistanceOrthogonal(pStart); |
| if (d > distance) { |
| distance = d; |
| epFinal = epCurrent; |
| } |
| } |
| if (epFinal != null) { |
| selection.remove(epFinal); |
| selection.add(epFinal); |
| } |
| return selection; |
| } |
| |
| |
| /** |
| * @param child |
| * @return EditPart |
| */ |
| private EditPart findParent(EditPart child) { |
| //check to see if we are not looking for a parent on RootEditPart, |
| //as it does not have a parent. |
| if (child instanceof RootEditPart) |
| return child; |
| else |
| return child.getParent(); //any other EditPart |
| } |
| } |