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