// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.gui.layer;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
/**
* This class defines a position to insert a given layer in the list of layers.
* @author Michael Zangl
* @since 10008
* @since 10592 functional interface
*/
@FunctionalInterface
public interface LayerPositionStrategy {
/**
* always inserts at the front of the stack.
*/
LayerPositionStrategy IN_FRONT = manager -> 0;
/**
* A GPX layer is added below the lowest data layer.
*/
LayerPositionStrategy AFTER_LAST_DATA_LAYER = afterLast(
layer -> layer instanceof OsmDataLayer || layer instanceof ValidatorLayer);
/**
* A normal layer is added after all validation layers.
*/
LayerPositionStrategy AFTER_LAST_VALIDATION_LAYER = afterLast(
layer -> layer instanceof ValidatorLayer);
/**
* The default for background layers: They are added before the first background layer in the list.
* If there is none, they are added at the end of the list.
*/
LayerPositionStrategy BEFORE_FIRST_BACKGROUND_LAYER = inFrontOfFirst(
Layer::isBackgroundLayer);
/**
* Gets a {@link LayerPositionStrategy} that inserts this layer in front of a given layer
* @param other The layer before which to insert this layer
* @return The strategy
*/
static LayerPositionStrategy inFrontOf(Layer other) {
return inFrontOfFirst(obj -> Objects.equals(obj, other));
}
/**
* Gets a {@link LayerPositionStrategy} that inserts the layer in front of the first layer that matches a condition.
* @param what The condition to match.
* @return The strategy.
*/
static LayerPositionStrategy inFrontOfFirst(final Predicate<Layer> what) {
return manager -> {
if (manager != null) {
List<Layer> layers = manager.getLayers();
for (int i = 0; i < layers.size(); i++) {
if (what.test(layers.get(i))) {
return i;
}
}
return layers.size();
}
return 0;
};
}
/**
* 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.
* @param what what to search for
* @return The strategy.
*/
static LayerPositionStrategy afterLast(final Predicate<Layer> what) {
return manager -> {
if (manager != null) {
List<Layer> layers = manager.getLayers();
for (int i = layers.size() - 1; i >= 0; i--) {
if (what.test(layers.get(i))) {
return i + 1;
}
}
}
return 0;
};
}
/**
* Gets the position where the layer should be inserted
* @param manager The layer manager to insert the layer in.
* @return The position in the range 0...layers.size
*/
int getPosition(LayerManager manager);
}