/*
* GPLv2 or 3, Copyright (c) 2010 Andrzej Zaborowski
*
* This is the main class for the game plugin.
*/
package wmsturbochallenge;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.event.ActionEvent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.actions.JosmAction;
import org.openstreetmap.josm.gui.MapFrame;
import org.openstreetmap.josm.gui.layer.Layer;
import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
import org.openstreetmap.josm.plugins.Plugin;
import org.openstreetmap.josm.plugins.PluginInformation;
public class WMSRacer extends Plugin implements LayerChangeListener, ActiveLayerChangeListener {
public WMSRacer(PluginInformation info) {
super(info);
driveAction.updateEnabledState();
JMenu toolsMenu = Main.main.menu.toolsMenu;
toolsMenu.addSeparator();
toolsMenu.add(new JMenuItem(driveAction));
}
/* Rather than add an action or main menu entry we should add
* an entry in the new layer's context menus in layerAdded
* but there doesn't seem to be any way to do that :( */
protected static class DriveAction extends JosmAction {
public MapFrame frame = null;
public Layer currentLayer = null;
protected Layer groundLayer = null;
public DriveAction() {
super(tr("Go driving"), "wmsracer",
tr("Drive a race car on this layer"),
null, true);
setEnabled(false);
}
@Override
public void actionPerformed(ActionEvent ev) {
if (groundLayer == null ||
!groundLayer.isBackgroundLayer())
return;
new GameWindow(groundLayer);
}
@Override
public void updateEnabledState() {
if (frame == null) {
groundLayer = null;
setEnabled(false);
return;
}
if (currentLayer != null &&
currentLayer.isBackgroundLayer()) {
groundLayer = currentLayer;
setEnabled(true);
return;
}
/* TODO: should only iterate through visible layers?
* or only wms layers? or perhaps we should allow
* driving on data/gpx layers too, or the full layer
* stack (by calling mapView.paint() instead of
* layer.paint()? Nah.
* (Note that for GPX or Data layers we could do
* some clever rendering directly on our perspectivic
* pseudo-3d surface by defining a strange projection
* like that or rendering in "stripes" at different
* horizontal scanlines (lines equidistant from
* camera eye)) */
for (Layer l : frame.mapView.getLayerManager().getLayers())
if (l.isBackgroundLayer()) {
groundLayer = l;
setEnabled(true);
return;
}
groundLayer = null;
setEnabled(false);
}
}
protected DriveAction driveAction = new DriveAction();
@Override
public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
if (oldFrame != null) {
Main.getLayerManager().removeLayerChangeListener(this);
Main.getLayerManager().removeActiveLayerChangeListener(this);
}
driveAction.frame = newFrame;
driveAction.updateEnabledState();
if (newFrame != null) {
Main.getLayerManager().addLayerChangeListener(this);
Main.getLayerManager().addActiveLayerChangeListener(this);
}
}
@Override
public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
driveAction.currentLayer = Main.getLayerManager().getActiveLayer();
driveAction.updateEnabledState();
}
@Override
public void layerAdded(LayerAddEvent e) {
driveAction.updateEnabledState();
}
@Override
public void layerRemoving(LayerRemoveEvent e) {
driveAction.updateEnabledState();
}
@Override
public void layerOrderChanged(LayerOrderChangeEvent e) {
// Do nothing
}
}