/* * $Id$ * * Copyright (c) 2000-2003 by Rodney Kinney * * 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. */ /* * Created by IntelliJ IDEA. * User: rkinney * Date: Jun 11, 2002 * Time: 9:30:01 PM * To change template for new class use * Code Style | Class Templates options (Tools | IDE Options). */ package VASSAL.build.module; import java.awt.Window; import java.awt.dnd.DropTarget; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.List; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLayeredPane; import javax.swing.JScrollPane; import javax.swing.KeyStroke; import javax.swing.WindowConstants; import VASSAL.build.Buildable; import VASSAL.build.GameModule; import VASSAL.build.module.documentation.HelpFile; import VASSAL.build.module.map.boardPicker.Board; import VASSAL.configure.ConfigureTree; import VASSAL.configure.StringArrayConfigurer; import VASSAL.configure.ValidationReport; import VASSAL.configure.ValidityChecker; import VASSAL.i18n.Resources; import VASSAL.tools.AdjustableSpeedScrollPane; import VASSAL.tools.ArrayUtils; import VASSAL.tools.menu.MenuManager; /** * A Map that may be configured to be visible only a particular side. * If visible to all, the map will respond to key/mouse events * only from the player playing the assigned side */ public class PrivateMap extends Map { protected String[] owners = new String[0]; protected boolean visibleToAll; protected Map surrogate; public static final String VISIBLE = "visible"; //$NON-NLS-1$ public static final String SIDE = "side"; //$NON-NLS-1$ public static final String USE_BOARDS = "useBoards"; //$NON-NLS-1$ public String[] getAttributeNames() { return ArrayUtils.append( new String[]{ SIDE, VISIBLE, USE_BOARDS }, super.getAttributeNames() ); } public String[] getAttributeDescriptions() { return ArrayUtils.append( new String[]{ "Belongs to side", //$NON-NLS-1$ "Visible to all players?", //$NON-NLS-1$ "Use same boards as this map: " //$NON-NLS-1$ }, super.getAttributeDescriptions() ); } public Class<?>[] getAttributeTypes() { return ArrayUtils.append( new Class<?>[]{ String[].class, Boolean.class, String.class }, super.getAttributeTypes() ); } public void setAttribute(String key, Object value) { if (VISIBLE.equals(key)) { if (value instanceof String) { value = Boolean.valueOf((String) value); } visibleToAll = ((Boolean) value).booleanValue(); } else if (SIDE.equals(key)) { if (value instanceof String) { value = StringArrayConfigurer.stringToArray((String) value); } owners = (String[]) value; } else if (USE_BOARDS.equals(key)) { for (Map m : Map.getMapList()) { if (m.getMapName().equals(value)) { surrogate = m; break; } } } else { super.setAttribute(key, value); } } public String getAttributeValueString(String key) { if (VISIBLE.equals(key)) { return String.valueOf(visibleToAll); } else if (SIDE.equals(key)) { return StringArrayConfigurer.arrayToString(owners); } else if (USE_BOARDS.equals(key)) { return surrogate == null ? null : surrogate.getMapName(); } else { return super.getAttributeValueString(key); } } public JComponent getView() { if (theMap == null) { theMap = new View(this); scroll = new AdjustableSpeedScrollPane( theMap, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); scroll.unregisterKeyboardAction(KeyStroke.getKeyStroke( KeyEvent.VK_PAGE_DOWN, 0)); scroll.unregisterKeyboardAction(KeyStroke.getKeyStroke( KeyEvent.VK_PAGE_UP, 0)); layeredPane.setLayout(new InsetLayout(layeredPane, scroll)); layeredPane.add(scroll, JLayeredPane.DEFAULT_LAYER); } return theMap; } protected Window createParentFrame() { if (GlobalOptions.getInstance().isUseSingleWindow()) { final JDialog d = new JDialog(GameModule.getGameModule().getFrame()) { private static final long serialVersionUID = 1L; @Override public void setVisible(boolean show) { super.setVisible(show && (visibleToAll || isAccessibleTo(PlayerRoster.getMySide()))); } }; d.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); d.setTitle(getDefaultWindowTitle()); return d; } else { final JFrame d = new JFrame() { private static final long serialVersionUID = 1L; @Override public void setVisible(boolean show) { super.setVisible(show && (visibleToAll || isAccessibleTo(PlayerRoster.getMySide()))); } }; d.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); d.setTitle(getDefaultWindowTitle()); d.setJMenuBar(MenuManager.getInstance().getMenuBarFor(d)); return d; } } public void sideChanged(String oldSide, String newSide) { super.sideChanged(oldSide, newSide); ((View)getView()).disableListeners(); if (isAccessibleTo(newSide)) { ((View)getView()).enableListeners(); } launchButton.setEnabled(isVisibleTo(PlayerRoster.getMySide())); } public boolean shouldDockIntoMainWindow() { return false; } /** Return true if the player playing the given side can access this map * @see PlayerRoster */ public boolean isAccessibleTo(String playerSide) { for (int i = 0; i < owners.length; ++i) { if (owners[i].equals(playerSide)) { return true; } } return false; } public boolean isVisibleTo(String playerSide) { return (visibleToAll || isAccessibleTo(playerSide)); } public void setup(boolean show) { super.setup(show); if (!show) { ((View) theMap).disableListeners(); } else if (isAccessibleTo(PlayerRoster.getMySide())) { ((View) theMap).enableListeners(); } launchButton.setEnabled(isVisibleTo(PlayerRoster.getMySide())); } @Override public void setBoards(Collection<Board> c) { if (surrogate != null) { c = surrogate.getBoards(); edgeBuffer = surrogate.getEdgeBuffer(); } super.setBoards(c); } /** @deprecated Use {@link #setBoards(Collection<Board>)} instead. */ @Override @Deprecated public void setBoards(Enumeration<Board> boardList) { if (surrogate != null) { boardList = surrogate.getAllBoards(); edgeBuffer = surrogate.getEdgeBuffer(); } super.setBoards(boardList); } public static String getConfigureTypeName() { return Resources.getString("Editor.PrivateMap.component_type"); //$NON-NLS-1$ } public HelpFile getHelpFile() { return HelpFile.getReferenceManualPage("PrivateWindow.htm"); //$NON-NLS-1$ } public void build(org.w3c.dom.Element el) { validator = new ValidityChecker() { public void validate(Buildable target, ValidationReport report) { if (!PlayerRoster.isActive()) { report.addWarning(Resources.getString("Editor.PrivateMap.warning", ConfigureTree.getConfigureName(PlayerRoster.class), ConfigureTree.getConfigureName(getClass()))); } } }; surrogate = null; super.build(el); } public static class View extends Map.View { private static final long serialVersionUID = 1L; private boolean listenersActive; private List<KeyListener> keyListeners = new ArrayList<KeyListener>(); private List<MouseListener> mouseListeners = new ArrayList<MouseListener>(); private List<MouseMotionListener> mouseMotionListeners = new ArrayList<MouseMotionListener>(); private DropTarget dropTarget; public View(PrivateMap m) { super(m); } public synchronized void setDropTarget(DropTarget dt) { if (dt != null) { dropTarget = dt; } } public synchronized void addKeyListener(KeyListener l) { if (listenersActive) { super.addKeyListener(l); } else { keyListeners.add(l); } } public synchronized void addMouseListener(MouseListener l) { if (listenersActive) { super.addMouseListener(l); } else { mouseListeners.add(l); } } public synchronized void addMouseMotionListener(MouseMotionListener l) { if (listenersActive) { super.addMouseMotionListener(l); } else { mouseMotionListeners.add(l); } } /** * Disable all keyboard and mouse listeners on this component */ protected void disableListeners() { for (KeyListener l : keyListeners) { removeKeyListener(l); } for (MouseListener l : mouseListeners) { removeMouseListener(l); } for (MouseMotionListener l : mouseMotionListeners) { removeMouseMotionListener(l); } super.setDropTarget(null); listenersActive = false; } /** * Enable all keyboard and mouse listeners on this component */ protected void enableListeners() { for (KeyListener l : keyListeners) { super.addKeyListener(l); } for (MouseListener l : mouseListeners) { super.addMouseListener(l); } for (MouseMotionListener l : mouseMotionListeners) { super.addMouseMotionListener(l); } super.setDropTarget(dropTarget); listenersActive = true; } } }