/******************************************************************************* * Copyright (c) 2000, 2007 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.tools; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.graphics.Cursor; import org.eclipse.draw2d.FigureCanvas; import org.eclipse.draw2d.geometry.Point; import org.eclipse.gef.SharedCursors; /** * A subclass of the SelectionTool that allows panning * by holding down the space bar. */ public class PanningSelectionTool extends SelectionTool { private boolean isSpaceBarDown = false; private Point viewLocation; /** * The state to indicate that the space bar has been pressed but * no drag has been initiated. */ protected static final int PAN = SelectionTool.MAX_STATE << 1; /** * The state to indicate that a pan is in progress. */ protected static final int PAN_IN_PROGRESS = PAN << 1; /** Max state */ protected static final int MAX_STATE = PAN_IN_PROGRESS; /** * Returns <code>true</code> if spacebar condition was accepted. * @param e the key event * @return true if the space bar was the key event. */ protected boolean acceptSpaceBar(KeyEvent e) { return (e.character == ' ' && (e.stateMask & SWT.MODIFIER_MASK) == 0); } /** * @see org.eclipse.gef.tools.AbstractTool#getDebugName() */ protected String getDebugName() { return "Panning Tool";//$NON-NLS-1$ } /** * @see org.eclipse.gef.tools.AbstractTool#getDebugNameForState(int) */ protected String getDebugNameForState(int state) { if (state == PAN) return "Pan Initial"; //$NON-NLS-1$ else if (state == PAN_IN_PROGRESS) return "Pan In Progress"; //$NON-NLS-1$ return super.getDebugNameForState(state); } /** * Returns the cursor used under normal conditions. * * @see #setDefaultCursor(Cursor) * @return the default cursor */ protected Cursor getDefaultCursor() { if (isInState(PAN | PAN_IN_PROGRESS)) return SharedCursors.HAND; return super.getDefaultCursor(); } /** * @see org.eclipse.gef.tools.SelectionTool#handleButtonDown(int) */ protected boolean handleButtonDown(int which) { if (which == 1 && getCurrentViewer().getControl() instanceof FigureCanvas && stateTransition(PAN, PAN_IN_PROGRESS)) { viewLocation = ((FigureCanvas) getCurrentViewer().getControl()).getViewport().getViewLocation(); return true; } return super.handleButtonDown(which); } /** * @see org.eclipse.gef.tools.SelectionTool#handleButtonUp(int) */ protected boolean handleButtonUp(int which) { if (which == 1 && isSpaceBarDown && stateTransition(PAN_IN_PROGRESS, PAN)) return true; else if (which == 1 && stateTransition(PAN_IN_PROGRESS, STATE_INITIAL)) { refreshCursor(); return true; } return super.handleButtonUp(which); } /** * @see org.eclipse.gef.tools.AbstractTool#handleDrag() */ protected boolean handleDrag() { if (isInState(PAN_IN_PROGRESS) && getCurrentViewer().getControl() instanceof FigureCanvas) { FigureCanvas canvas = (FigureCanvas)getCurrentViewer().getControl(); canvas.scrollTo(viewLocation.x - getDragMoveDelta().width, viewLocation.y - getDragMoveDelta().height); return true; } else { return super.handleDrag(); } } /** * @see org.eclipse.gef.tools.SelectionTool#handleFocusLost() */ protected boolean handleFocusLost() { if (isInState(PAN | PAN_IN_PROGRESS)) { setState(STATE_INITIAL); refreshCursor(); return true; } return super.handleFocusLost(); } /** * @see org.eclipse.gef.tools.SelectionTool#handleKeyDown(org.eclipse.swt.events.KeyEvent) */ protected boolean handleKeyDown(KeyEvent e) { if (acceptSpaceBar(e)) { isSpaceBarDown = true; if (stateTransition(STATE_INITIAL, PAN)) refreshCursor(); return true; } else { if (stateTransition(PAN, STATE_INITIAL)) { refreshCursor(); isSpaceBarDown = false; return true; } else if (isInState(PAN_IN_PROGRESS)) isSpaceBarDown = false; } return super.handleKeyDown(e); } /** * @see org.eclipse.gef.tools.SelectionTool#handleKeyUp(org.eclipse.swt.events.KeyEvent) */ protected boolean handleKeyUp(KeyEvent e) { if (acceptSpaceBar(e)) { isSpaceBarDown = false; if (stateTransition(PAN, STATE_INITIAL)) refreshCursor(); return true; } return super.handleKeyUp(e); } }