/*
* Copyright (c) 2014 tabletoptool.com team.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* rptools.com team - initial implementation
* tabletoptool.com team - further development
*/
package com.t3.client.ui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.ComponentInputMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import com.t3.client.TabletopTool;
import com.t3.client.ui.zone.ZoneRenderer;
import com.t3.language.I18N;
import com.t3.model.grid.Grid;
public abstract class Tool extends JToggleButton implements ActionListener, KeyListener {
private static final long serialVersionUID = -6365594431759083634L;
private Toolbox toolbox;
protected Map<KeyStroke, Action> keyActionMap = new HashMap<KeyStroke, Action>();
private final Set<Character> keyDownSet = new HashSet<Character>();
public Tool() {
// Map the escape key to reset this tool.
installKeystrokes(keyActionMap);
addActionListener(this);
setToolTipText(I18N.getText(getTooltip()));
setFocusable(false);
setFocusPainted(false);
}
protected boolean isKeyDown(char key) {
return keyDownSet.contains(key);
}
public boolean isAvailable() {
return true;
}
void setToolbox(Toolbox toolbox) {
this.toolbox = toolbox;
}
protected void installKeystrokes(Map<KeyStroke, Action> actionMap) {
actionMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), new EscapeAction());
}
public abstract String getTooltip();
public abstract String getInstructions();
protected void addListeners(JComponent comp) {
if (comp == null) {
return;
}
if (this instanceof MouseListener) {
comp.addMouseListener((MouseListener) this);
}
if (this instanceof MouseMotionListener) {
comp.addMouseMotionListener((MouseMotionListener) this);
}
if (this instanceof MouseWheelListener) {
comp.addMouseWheelListener((MouseWheelListener) this);
}
// Keystrokes
comp.addKeyListener(this);
comp.setActionMap(createActionMap(keyActionMap));
comp.setInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, createInputMap(keyActionMap));
}
void removeListeners(JComponent comp) {
if (comp == null) {
return;
}
comp.removeKeyListener(this);
if (this instanceof MouseListener) {
comp.removeMouseListener((MouseListener) this);
}
if (this instanceof MouseMotionListener) {
comp.removeMouseMotionListener((MouseMotionListener) this);
}
if (this instanceof MouseWheelListener) {
comp.removeMouseWheelListener((MouseWheelListener) this);
}
}
protected void attachTo(ZoneRenderer renderer) {
// No op
}
protected void detachFrom(ZoneRenderer renderer) {
// No op
}
protected void addGridBasedKeys(Grid grid, boolean enable) {
// do nothing; only overridden by PointerTool currently
}
private InputMap createInputMap(Map<KeyStroke, Action> keyActionMap) {
ComponentInputMap inputMap = new ComponentInputMap((JPanel) TabletopTool.getFrame().getContentPane());
for (KeyStroke keyStroke : keyActionMap.keySet()) {
inputMap.put(keyStroke, keyStroke.toString());
}
return inputMap;
}
private ActionMap createActionMap(Map<KeyStroke, Action> keyActionMap) {
ActionMap actionMap = new ActionMap();
for (KeyStroke keyStroke : keyActionMap.keySet()) {
actionMap.put(keyStroke.toString(), keyActionMap.get(keyStroke));
// System.out.println(keyStroke.toString() + ": " + keyActionMap.get(keyStroke).toString());
}
return actionMap;
}
/**
* Implement this method to clear internal data to a start drawing state. This method must repaint whatever it is
* being displayed upon.
*/
protected abstract void resetTool();
/**
* Perform the escape action on a tool.
*
* @author jgorrell
*/
private class EscapeAction extends AbstractAction {
private static final long serialVersionUID = -514197544905143826L;
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
@Override
public void actionPerformed(ActionEvent e) {
// This should probably go somewhere else like T3Frame...
// but it was just too easy to plop down here to resist =)
// although having it here will be a quick reminder about competing
// Escape actions.
if (TabletopTool.getFrame().isFullScreen()) {
TabletopTool.getFrame().showWindowed();
}
resetTool();
}
}
////
// ACTION LISTENER
@Override
public void actionPerformed(ActionEvent e) {
if (isSelected()) {
toolbox.setSelectedTool(Tool.this);
}
}
////
// KEY LISTENER
@Override
public void keyPressed(KeyEvent e) {
keyDownSet.add(e.getKeyChar());
}
@Override
public void keyReleased(KeyEvent e) {
keyDownSet.remove(e.getKeyChar());
}
@Override
public void keyTyped(KeyEvent e) {
}
}