/* * 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) { } }