blob: 60449af8e5d5f03cf77012bb316d893a1fbc5777 [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;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.jface.action.IAction;
/**
* The KeyHandler should handle all normal keystrokes on an
* <code>EditPartViewer</code>. <I>Normal</i> is simply defined as keystrokes
* which are not associated with an Accelerator on the Menu. The KeyHandler will
* be forwarded KeyEvents by the active Tool, which is usually the
* SelectionTool. The Tool may be in a state where keystrokes should not be
* processed, in which case it will not forward the keystrokes. For this reason,
* it is important to always handle KeyEvents by using a KeyHandler.
* <P>
* KeyHandlers can be chained by calling {@link #setParent(KeyHandler)}. If this
* KeyHandler does not handle the keystroke, it will pass the keystroke to its
* <i>parent</i> KeyHandler.
* <P>
* KeyHandlers can be implemented using two stragegies. One is to map
* {@link KeyStroke KeyStrokes} to {@link org.eclipse.jface.action.IAction
* Actions} using the {@link #put(KeyStroke, IAction)} and
* {@link #remove(KeyStroke)} API. The other is to subclass KeyHandler, and
* override various methods. A combination of the two is also useful.
*
* @since 2.0
*/
public class KeyHandler {
private Map actions;
private KeyHandler parent;
/**
* Processes a <i>key pressed</i> event. This method is called by the Tool
* whenever a key is pressed, and the Tool is in the proper state.
*
* @param event
* the KeyEvent
* @return <code>true</code> if KeyEvent was handled in some way
*/
public boolean keyPressed(KeyEvent event) {
if (performStroke(new KeyStroke(event, true))) {
event.doit = false;
return true;
}
return parent != null && parent.keyPressed(event);
}
/**
* Processes a <i>key released</i> event. This method is called by the Tool
* whenever a key is released, and the Tool is in the proper state.
*
* @param event
* the KeyEvent
* @return <code>true</code> if KeyEvent was handled in some way
*/
public boolean keyReleased(KeyEvent event) {
if (performStroke(new KeyStroke(event, false)))
return true;
return parent != null && parent.keyReleased(event);
}
private boolean performStroke(KeyStroke key) {
if (actions == null)
return false;
IAction action = (IAction) actions.get(key);
if (action == null)
return false;
if (action.isEnabled())
action.run();
return true;
}
/**
* Maps a specified <code>KeyStroke</code> to an <code>IAction</code>. When
* a KeyEvent occurs matching the given KeyStroke, the Action will be
* <code>run()</code> iff it is enabled.
*
* @param keystroke
* the KeyStroke
* @param action
* the Action to run
*/
public void put(KeyStroke keystroke, IAction action) {
if (actions == null)
actions = new HashMap();
actions.put(keystroke, action);
}
/**
* Removed a mapped <code>IAction</code> for the specified
* <code>KeyStroke</code>.
*
* @param keystroke
* the KeyStroke to be unmapped
*/
public void remove(KeyStroke keystroke) {
if (actions != null)
actions.remove(keystroke);
}
/**
* Sets a <i>parent</i> <code>KeyHandler</code> to which this KeyHandler
* will forward un-consumed KeyEvents. This KeyHandler will first attempt to
* handle KeyEvents. If it does not recognize a given KeyEvent, that event
* is passed to its <i>parent</i>
*
* @param parent
* the <i>parent</i> KeyHandler
* @return <code>this</code> for convenience
*/
public KeyHandler setParent(KeyHandler parent) {
this.parent = parent;
return this;
}
}