/* * $Id$ * * Copyright (c) 2000-2005 by Rodney Kinney, Brent Easton * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License (LGPL) as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, copies are available * at http://www.opensource.org. */ package VASSAL.counters; import java.awt.Component; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Shape; import java.awt.event.InputEvent; import java.util.ArrayList; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.KeyStroke; import VASSAL.build.module.documentation.HelpFile; import VASSAL.command.Command; import VASSAL.configure.NamedKeyStrokeArrayConfigurer; import VASSAL.configure.PropertyExpression; import VASSAL.configure.PropertyExpressionConfigurer; import VASSAL.configure.StringConfigurer; import VASSAL.tools.NamedKeyStroke; import VASSAL.tools.SequenceEncoder; /** * RestrictCommands * Restrict the availability of Key Commands, depending on a * Property Match String. * - Variable list of Key Commands to restrict * - Disable or Invisible * */ public class RestrictCommands extends Decorator implements EditablePiece { public static final String ID = "hideCmd;"; protected static final String HIDE = "Hide"; protected static final String DISABLE = "Disable"; protected String name = ""; protected PropertyExpression propertyMatch = new PropertyExpression(); protected String action = HIDE; protected NamedKeyStroke[] watchKeys = new NamedKeyStroke[0]; public RestrictCommands() { this(ID, null); } public RestrictCommands(String type, GamePiece inner) { mySetType(type); setInner(inner); } public Rectangle boundingBox() { return piece.boundingBox(); } public void draw(Graphics g, int x, int y, Component obs, double zoom) { piece.draw(g, x, y, obs, zoom); } public String getName() { return piece.getName(); } protected KeyCommand[] myGetKeyCommands() { return new KeyCommand[0]; } public String myGetState() { return ""; } public String myGetType() { SequenceEncoder se = new SequenceEncoder(';'); se.append(name) .append(action) .append(propertyMatch.getExpression()) .append(NamedKeyStrokeArrayConfigurer.encode(watchKeys)); return ID + se.getValue(); } public Command myKeyEvent(KeyStroke stroke) { return null; } /* * Cancel execution of watched KeyStrokes */ public Command keyEvent(KeyStroke stroke) { if (!matchesFilter()) { return super.keyEvent(stroke); } else { for (int j = 0; j < watchKeys.length ; j++) { if (watchKeys[j].equals(stroke)) { return null; } } } return super.keyEvent(stroke); } protected KeyCommand[] getKeyCommands() { KeyCommand[] commands = super.getKeyCommands(); ArrayList<KeyCommand> newCommands = new ArrayList<KeyCommand>(commands.length); if (matchesFilter()) { for (int i = 0; i < commands.length; i++) { boolean matches = false; for (int j = 0; j < watchKeys.length && ! matches; j++) { matches = (watchKeys[j].equals(commands[i].getKeyStroke())); } if (matches) { if (action.equals(DISABLE)) { KeyCommand newCommand = new KeyCommand(commands[i]); newCommand.setEnabled(false); newCommands.add(newCommand); } } else { newCommands.add(commands[i]); } } commands = newCommands.toArray(new KeyCommand[newCommands.size()]); } return commands; } protected boolean matchesFilter() { GamePiece outer = Decorator.getOutermost(this); if (!propertyMatch.isNull()) { if (!propertyMatch.accept(outer)) { return false; } } return true; } public void mySetState(String newState) { } public Shape getShape() { return piece.getShape(); } public String getDescription() { String s = "Restrict Commands"; if (name.length() > 0) { s += " - " + name; } return s; } public HelpFile getHelpFile() { return HelpFile.getReferenceManualPage("RestrictCommands.htm"); } public void mySetType(String type) { SequenceEncoder.Decoder st = new SequenceEncoder.Decoder(type, ';'); st.nextToken(); name = st.nextToken(""); action = st.nextToken(HIDE); propertyMatch.setExpression(st.nextToken("")); String keys = st.nextToken(""); if (keys.indexOf(',') > 0) { watchKeys = NamedKeyStrokeArrayConfigurer.decode(keys); } else { watchKeys = new NamedKeyStroke[keys.length()]; for (int i = 0; i < watchKeys.length; i++) { watchKeys[i] = new NamedKeyStroke(keys.charAt(i),InputEvent.CTRL_MASK); } } } public PieceEditor getEditor() { return new Ed(this); } public static class Ed implements PieceEditor { protected StringConfigurer name; protected PropertyExpressionConfigurer propertyMatch; protected NamedKeyStrokeArrayConfigurer watchKeys; protected JComboBox actionOption; protected JPanel box; public Ed(RestrictCommands piece) { box = new JPanel(); box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS)); name = new StringConfigurer(null, "Description: ", piece.name); box.add(name.getControls()); actionOption = new JComboBox(); actionOption.addItem(HIDE); actionOption.addItem(DISABLE); actionOption.setSelectedIndex((piece.action.equals(HIDE)) ? 0 : 1); Box b = Box.createHorizontalBox(); b.add(new JLabel("Restriction: ")); b.add(actionOption); box.add(b); propertyMatch = new PropertyExpressionConfigurer(null, "Restrict when properties match: ", piece.propertyMatch, Decorator.getOutermost(piece)); box.add(propertyMatch.getControls()); watchKeys = new NamedKeyStrokeArrayConfigurer(null, "Restrict these Key Commands ", piece.watchKeys); box.add(watchKeys.getControls()); } public Component getControls() { return box; } public String getState() { return ""; } public String getType() { SequenceEncoder se = new SequenceEncoder(';'); se.append(name.getValueString()) .append((actionOption.getSelectedIndex()==0) ? HIDE : DISABLE) .append(propertyMatch.getValueString()) .append(watchKeys.getValueString()); return ID + se.getValue(); } } }