Ticket #18638: 18638.1.patch
File 18638.1.patch, 10.5 KB (added by , 6 years ago) |
---|
-
src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java
54 54 import org.openstreetmap.josm.gui.MapView; 55 55 import org.openstreetmap.josm.gui.SideButton; 56 56 import org.openstreetmap.josm.gui.dialogs.layer.ActivateLayerAction; 57 import org.openstreetmap.josm.gui.dialogs.layer.CycleLayerAction; 57 58 import org.openstreetmap.josm.gui.dialogs.layer.DeleteLayerAction; 58 59 import org.openstreetmap.josm.gui.dialogs.layer.DuplicateAction; 59 60 import org.openstreetmap.josm.gui.dialogs.layer.LayerListTransferHandler; … … 141 142 private final ActivateLayerAction activateLayerAction; 142 143 private final ShowHideLayerAction showHideLayerAction; 143 144 145 private final CycleLayerAction cycleLayerAction; 146 144 147 //TODO This duplicates ShowHide actions functionality 145 148 /** stores which layer index to toggle and executes the ShowHide action if the layer is present */ 146 149 private final class ToggleLayerIndexVisibility extends AbstractAction { … … 329 332 // Show/Activate layer on Enter key press 330 333 InputMapUtils.addSpacebarAction(layerList, showHideLayerAction); 331 334 335 // Cycle layer action 336 cycleLayerAction = new CycleLayerAction(); 337 332 338 createLayout(layerList, true, Arrays.asList( 333 339 new SideButton(moveUpAction, false), 334 340 new SideButton(moveDownAction, false), … … 388 394 DISPLAY_NUMBERS.removeListener(visibilityWidthListener); 389 395 ExpertToggleAction.removeExpertModeChangeListener(visibilityWidthListener); 390 396 layerManager.removeLayerChangeListener(visibilityWidthListener); 397 cycleLayerAction.destroy(); 391 398 super.destroy(); 392 399 instance = null; 393 400 } -
src/org/openstreetmap/josm/gui/dialogs/layer/CycleLayerAction.java
1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.dialogs.layer; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 6 import java.awt.event.ActionEvent; 7 import java.awt.event.KeyEvent; 8 import java.util.ArrayList; 9 import java.util.Collections; 10 import java.util.List; 11 import java.util.stream.Collectors; 12 13 import org.openstreetmap.josm.actions.JosmAction; 14 import org.openstreetmap.josm.gui.MainApplication; 15 import org.openstreetmap.josm.gui.layer.ImageryLayer; 16 import org.openstreetmap.josm.gui.layer.Layer; 17 import org.openstreetmap.josm.gui.layer.MainLayerManager; 18 import org.openstreetmap.josm.tools.ImageProvider; 19 import org.openstreetmap.josm.tools.Shortcut; 20 21 /** 22 * Allow users to cycle between adjacent layers easily 23 * 24 * @author Taylor Smock 25 * @since xxx 26 */ 27 public class CycleLayerAction extends JosmAction { 28 protected final static int KEYUP = KeyEvent.VK_OPEN_BRACKET; 29 protected final static int KEYDOWN = KeyEvent.VK_CLOSE_BRACKET; 30 protected final static int MODIFIER = Shortcut.SHIFT; 31 private static Shortcut cycleUp = Shortcut.registerShortcut("core:cyclelayerup", tr("Cycle layers up"), 32 KEYUP, MODIFIER); 33 private static Shortcut cycleDown = Shortcut.registerShortcut("core:cyclelayerdown", tr("Cycle layers down"), 34 KEYDOWN, MODIFIER); 35 36 /** 37 * Create a CycleLayerAction that cycles through layers that are in the model 38 */ 39 public CycleLayerAction() { 40 super(tr("Cycle layers"), "dialogs/next", tr("Cycle through layers"), cycleDown, true, 41 "cycle-layer", false); 42 MainApplication.registerActionShortcut(this, cycleUp); // cycleDown gets registered by JosmAction 43 new ImageProvider("dialogs", "next").getResource().attachImageIcon(this, true); 44 putValue(SHORT_DESCRIPTION, tr("Cycle through visible layers.")); 45 putValue(NAME, tr("Cycle layers")); 46 } 47 48 @Override 49 public void actionPerformed(ActionEvent e) { 50 MainLayerManager manager = MainApplication.getLayerManager(); 51 List<Layer> managerLayers = manager.getLayers().stream().filter(layer -> !(layer instanceof ImageryLayer)) 52 .collect(Collectors.toList()); 53 if (managerLayers.isEmpty()) 54 return; 55 int key = KeyEvent.getExtendedKeyCodeForChar(e.getActionCommand().charAt(0)); 56 char character = KeyEvent.getKeyText(key).charAt(0); 57 int realKey = KeyEvent.getExtendedKeyCodeForChar(character); 58 Shortcut shortcut = Shortcut 59 .findShortcut(realKey, cycleDown.getAssignedModifier()) 60 .orElse(null); 61 62 List<Layer> layers; 63 if (cycleUp.equals(shortcut)) { 64 int index = managerLayers.indexOf(manager.getActiveLayer()); 65 int sublist = index < managerLayers.size() ? index + 1 : index; 66 if (index >= managerLayers.size() - 1) { 67 index = 0; 68 sublist = 0; 69 } 70 layers = managerLayers.subList(sublist, managerLayers.size()); 71 } else { 72 layers = new ArrayList<>(managerLayers); 73 Collections.reverse(layers); 74 int index = layers.indexOf(manager.getActiveLayer()); 75 int sublist = index < managerLayers.size() - 1 ? index + 1 : 0; 76 layers = layers.subList(sublist, layers.size()); 77 } 78 Layer layer = layers.stream().filter(Layer::isVisible).filter(tlayer -> !(tlayer instanceof ImageryLayer)) 79 .findFirst() 80 .orElse(manager.getActiveLayer()); 81 82 manager.setActiveLayer(layer); 83 } 84 85 @Override 86 public void destroy() { 87 super.destroy(); 88 MainApplication.unregisterActionShortcut(this, cycleUp); 89 } 90 } -
test/unit/org/openstreetmap/josm/gui/dialogs/layer/CycleLayerActionTest.java
1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.dialogs.layer; 3 4 import static org.junit.Assert.assertEquals; 5 import static org.openstreetmap.josm.tools.I18n.tr; 6 7 import java.awt.event.ActionEvent; 8 import java.awt.event.KeyEvent; 9 10 import org.junit.Before; 11 import org.junit.Rule; 12 import org.junit.Test; 13 import org.openstreetmap.josm.data.imagery.ImageryInfo; 14 import org.openstreetmap.josm.data.imagery.ImageryLayerInfo; 15 import org.openstreetmap.josm.data.osm.DataSet; 16 import org.openstreetmap.josm.gui.MainApplication; 17 import org.openstreetmap.josm.gui.layer.ImageryLayer; 18 import org.openstreetmap.josm.gui.layer.MainLayerManager; 19 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 20 import org.openstreetmap.josm.testutils.JOSMTestRules; 21 22 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 23 24 /** 25 * Test class for {@link CycleLayerAction} 26 * 27 * @author Taylor Smock 28 */ 29 public class CycleLayerActionTest { 30 /** Layers need a projection */ 31 @Rule 32 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") 33 public JOSMTestRules test = new JOSMTestRules().main().preferences().projection().fakeImagery(); 34 35 CycleLayerAction cycle; 36 MainLayerManager manager; 37 38 final static int MODIFIER = CycleLayerAction.MODIFIER; 39 final static int KEYUP = CycleLayerAction.KEYUP; 40 final static int KEYDOWN = CycleLayerAction.KEYDOWN; 41 ActionEvent down; 42 ActionEvent up; 43 44 /** 45 * Set up common items (make layers, etc.) 46 */ 47 @Before 48 public void setUp() { 49 cycle = new CycleLayerAction(); 50 manager = MainApplication.getLayerManager(); 51 for (int i = 0; i < 10; i++) { 52 manager.addLayer(new OsmDataLayer(new DataSet(), tr("Layer {0}", i), null)); 53 } 54 up = new ActionEvent(this, ActionEvent.ACTION_FIRST, KeyEvent.getKeyText(KEYUP), MODIFIER); 55 down = new ActionEvent(this, ActionEvent.ACTION_FIRST, KeyEvent.getKeyText(KEYDOWN), MODIFIER); 56 } 57 58 /** 59 * Test going down from the bottom 60 */ 61 @Test 62 public void testDownBottom() { 63 manager.setActiveLayer(manager.getLayers().get(0)); 64 cycle.actionPerformed(down); 65 assertEquals(manager.getLayers().size() - 1, manager.getLayers().indexOf(manager.getActiveLayer())); 66 } 67 68 /** 69 * Check going up from the top 70 */ 71 @Test 72 public void testUpTop() { 73 manager.setActiveLayer(manager.getLayers().get(manager.getLayers().size() - 1)); 74 cycle.actionPerformed(up); 75 assertEquals(0, manager.getLayers().indexOf(manager.getActiveLayer())); 76 } 77 78 /** 79 * Check going down 80 */ 81 @Test 82 public void testDown() { 83 manager.setActiveLayer(manager.getLayers().get(3)); 84 cycle.actionPerformed(down); 85 assertEquals(2, manager.getLayers().indexOf(manager.getActiveLayer())); 86 } 87 88 /** 89 * Check going up 90 */ 91 @Test 92 public void testUp() { 93 manager.setActiveLayer(manager.getLayers().get(3)); 94 cycle.actionPerformed(up); 95 assertEquals(4, manager.getLayers().indexOf(manager.getActiveLayer())); 96 } 97 98 /** 99 * Test no layers 100 */ 101 @Test 102 public void testNoLayers() { 103 manager.getLayers().forEach(manager::removeLayer); 104 cycle.actionPerformed(up); 105 cycle.actionPerformed(down); 106 assertEquals(0, manager.getLayers().size()); 107 } 108 109 /** 110 * Test with an aerial imagery layer 111 */ 112 @Test 113 public void testWithAerialImagery() { 114 final ImageryInfo magentaTilesInfo = ImageryLayerInfo.instance.getLayers().stream() 115 .filter(i -> i.getName().equals("Magenta Tiles")).findAny().get(); 116 ImageryLayer imageryLayer = ImageryLayer.create(magentaTilesInfo); 117 manager.addLayer(imageryLayer); 118 manager.moveLayer(imageryLayer, 5); 119 manager.setActiveLayer(manager.getLayers().get(4)); 120 cycle.actionPerformed(up); 121 assertEquals(6, manager.getLayers().indexOf(manager.getActiveLayer())); 122 cycle.actionPerformed(down); 123 assertEquals(4, manager.getLayers().indexOf(manager.getActiveLayer())); 124 } 125 }