blob: 0d756d6ac08ee8452a7c0fde9c2f7b76554724d4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 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.bpel.common.ui.tray;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.ScrollBar;
import org.eclipse.draw2d.ScrollPane;
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.EditPartViewer;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.KeyHandler;
import org.eclipse.gef.requests.DirectEditRequest;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
public class TrayKeyHandler extends KeyHandler {
protected EditPartViewer viewer;
public TrayKeyHandler(EditPartViewer viewer) {
this.viewer = viewer;
}
@Override
public boolean keyPressed(KeyEvent event) {
switch (event.keyCode) {
case SWT.ARROW_UP:
return navigateNext(event, PositionConstants.NORTH);
case SWT.ARROW_DOWN:
return navigateNext(event, PositionConstants.SOUTH);
case SWT.HOME:
return navigateJump(event, PositionConstants.TOP);
case SWT.END:
return navigateJump(event, PositionConstants.BOTTOM);
case SWT.PAGE_DOWN:
return navigateJump(event, PositionConstants.SOUTH);
case SWT.PAGE_UP:
return navigateJump(event, PositionConstants.NORTH);
case SWT.F2:
return activateDirectEdit(event);
}
// default
return super.keyPressed(event);
}
protected boolean navigateNext(KeyEvent event, int direction) {
GraphicalEditPart currentPart = (GraphicalEditPart)viewer.getFocusEditPart();
// TODO: we should cache this list
List flatList = new ArrayList();
buildFlatList(flatList, viewer.getContents());
int currentPosition = flatList.indexOf(currentPart);
switch (direction) {
case PositionConstants.NORTH:
currentPosition--;
break;
case PositionConstants.SOUTH:
currentPosition++;
break;
}
if (currentPosition >= 0 && currentPosition < flatList.size()) {
currentPart = (GraphicalEditPart) flatList.get(currentPosition);
navigateTo(currentPart, event);
return true;
}
return false;
}
protected void buildFlatList(List result, EditPart container) {
result.add(container);
for (Iterator iter = container.getChildren().iterator(); iter.hasNext();) {
EditPart part = (EditPart) iter.next();
buildFlatList(result, part);
}
}
protected boolean navigateJump(KeyEvent event, int direction) {
return true;
}
protected void navigateTo(GraphicalEditPart part, KeyEvent event) {
if (part == null) return;
if ((event.stateMask & SWT.SHIFT) != 0) {
viewer.appendSelection(part);
viewer.setFocus(part);
} else if ((event.stateMask & SWT.CONTROL) != 0) {
viewer.setFocus(part);
} else {
viewer.select(part);
}
reveal(part);
}
protected void reveal(GraphicalEditPart part) {
// there's no need to scroll to the main edit part because it is always visible
if (part instanceof MainTrayEditPart) return;
MainTrayEditPart mainPart = getMainTrayEditPart(part);
ScrollPane scrollpane = ((MainTrayEditPart.MainTrayContainerFigure)mainPart.getFigure()).getChildrenScrollPane();
Viewport viewport = scrollpane.getViewport();
Rectangle partBounds = part.getFigure().getBounds().getCopy();
Rectangle portBounds = viewport.getBounds();
if (!portBounds.contains(partBounds)) {
Point topLocation = partBounds.getTopLeft();
Point currentLocation = viewport.getViewLocation();
int step = getScrollStep(part);
if (currentLocation.getPosition(topLocation) == PositionConstants.NORTH) {
currentLocation.y -= step;
// ensure that we don't leave things "half-scrolled" at the top
currentLocation.y = (currentLocation.y < step) ? 0 : currentLocation.y;
} else {
currentLocation.y += step;
}
viewport.setViewLocation(currentLocation);
// refreshes the scrollbar so they can disppear if needed
ScrollBar scrollbar = scrollpane.getVerticalScrollBar();
scrollbar.invalidate();
scrollbar.validate();
}
}
protected int getScrollStep(GraphicalEditPart part) {
if (part instanceof TrayCategoryEntryEditPart) {
return part.getFigure().getBounds().height;
}
if (part instanceof TrayCategoryEditPart) {
return ((TrayCategoryEditPart)part).getTitleFigure().getBounds().height;
}
return 0;
}
protected MainTrayEditPart getMainTrayEditPart(EditPart part) {
if (part instanceof MainTrayEditPart) return (MainTrayEditPart)part;
return getMainTrayEditPart(part.getParent());
}
protected boolean activateDirectEdit(KeyEvent event) {
GraphicalEditPart currentPart = (GraphicalEditPart)viewer.getFocusEditPart();
currentPart.performRequest(new DirectEditRequest());
return true;
}
}