001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.layer; 003 004import java.util.List; 005 006import org.openstreetmap.josm.tools.Predicate; 007import org.openstreetmap.josm.tools.Predicates; 008 009/** 010 * This class defines a position to insert a given layer in the list of layers. 011 * @author Michael Zangl 012 * @since 10008 013 */ 014public abstract class LayerPositionStrategy { 015 016 /** 017 * always inserts at the front of the stack. 018 */ 019 public static final LayerPositionStrategy IN_FRONT = new LayerPositionStrategy() { 020 @Override 021 public int getPosition(LayerManager manager) { 022 return 0; 023 } 024 }; 025 026 /** 027 * A GPX layer is added below the lowest data layer. 028 */ 029 public static final LayerPositionStrategy AFTER_LAST_DATA_LAYER = afterLast(new Predicate<Layer>() { 030 @Override 031 public boolean evaluate(Layer object) { 032 return object instanceof OsmDataLayer || object instanceof ValidatorLayer; 033 } 034 }); 035 036 /** 037 * A normal layer is added after all validation layers. 038 */ 039 public static final LayerPositionStrategy AFTER_LAST_VALIDATION_LAYER = afterLast(new Predicate<Layer>() { 040 @Override 041 public boolean evaluate(Layer object) { 042 return object instanceof ValidatorLayer; 043 } 044 }); 045 046 /** 047 * The default for background layers: They are added before the first background layer in the list. 048 * If there is none, they are added at the end of the list. 049 */ 050 public static final LayerPositionStrategy BEFORE_FIRST_BACKGROUND_LAYER = inFrontOfFirst(new Predicate<Layer>() { 051 @Override 052 public boolean evaluate(Layer object) { 053 return object.isBackgroundLayer(); 054 } 055 }); 056 057 /** 058 * Gets a {@link LayerPositionStrategy} that inserts this layer in front of a given layer 059 * @param other The layer before which to insert this layer 060 * @return The strategy 061 */ 062 public static LayerPositionStrategy inFrontOf(Layer other) { 063 return inFrontOfFirst(Predicates.equalTo(other)); 064 } 065 066 /** 067 * Gets a {@link LayerPositionStrategy} that inserts the layer in front of the first layer that matches a condition. 068 * @param what The condition to match. 069 * @return The strategy. 070 */ 071 public static LayerPositionStrategy inFrontOfFirst(final Predicate<Layer> what) { 072 return new LayerPositionStrategy() { 073 @Override 074 public int getPosition(LayerManager manager) { 075 List<Layer> layers = manager.getLayers(); 076 for (int i = 0; i < layers.size(); i++) { 077 if (what.evaluate(layers.get(i))) { 078 return i; 079 } 080 } 081 return layers.size(); 082 } 083 }; 084 } 085 086 /** 087 * Creates a strategy that places the layer after the last layer of a given kind or at the beginning of the list if no such layer exists. 088 * @param what what to search for 089 * @return The strategy. 090 */ 091 public static LayerPositionStrategy afterLast(final Predicate<Layer> what) { 092 return new LayerPositionStrategy() { 093 @Override 094 public int getPosition(LayerManager manager) { 095 List<Layer> layers = manager.getLayers(); 096 for (int i = layers.size() - 1; i >= 0; i--) { 097 if (what.evaluate(layers.get(i))) { 098 return i + 1; 099 } 100 } 101 return 0; 102 } 103 }; 104 } 105 106 /** 107 * Gets the position where the layer should be inserted 108 * @param manager The layer manager to insert the layer in. 109 * @return The position in the range 0...layers.size 110 */ 111 public abstract int getPosition(LayerManager manager); 112}