diff --git a/src/main/java/de/bluecolored/bluemap/api/WebApp.java b/src/main/java/de/bluecolored/bluemap/api/WebApp.java
index 39a215f..ce35634 100644
--- a/src/main/java/de/bluecolored/bluemap/api/WebApp.java
+++ b/src/main/java/de/bluecolored/bluemap/api/WebApp.java
@@ -94,6 +94,8 @@ public interface WebApp {
*/
void registerScript(String url);
+ // ------
+
/**
* @deprecated You should use the {@link #getWebRoot()} method to create the image-files you need, or store map/marker
* specific images in the map's storage (See: {@link BlueMapMap#getAssetStorage()})!
diff --git a/src/main/java/de/bluecolored/bluemap/api/markers/DetailMarker.java b/src/main/java/de/bluecolored/bluemap/api/markers/DetailMarker.java
new file mode 100644
index 0000000..bc3bb88
--- /dev/null
+++ b/src/main/java/de/bluecolored/bluemap/api/markers/DetailMarker.java
@@ -0,0 +1,50 @@
+package de.bluecolored.bluemap.api.markers;
+
+/**
+ * @see POIMarker
+ * @see ShapeMarker
+ * @see ExtrudeMarker
+ * @see LineMarker
+ */
+public interface DetailMarker {
+
+ /**
+ * Getter for the detail of this marker. The label can include html-tags.
+ * @return the detail of this {@link Marker}
+ */
+ String getDetail();
+
+ /**
+ * Sets the detail of this {@link Marker}. The detail can include html-tags.
+ * This is the text that will be displayed on the popup when you click on this marker.
+ *
+ * Important:
+ * Html-tags in the label will not be escaped, so you can use them to style the {@link Marker}-detail.
+ * Make sure you escape all html-tags from possible user inputs to prevent possible
+ * XSS-Attacks on the web-client!
+ *
+ *
+ * @param detail the new detail for this {@link ObjectMarker}
+ */
+ void setDetail(String detail);
+
+ interface Builder {
+
+ /**
+ * Sets the detail of the {@link Marker}. The detail can include html-tags.
+ * This is the text that will be displayed on the popup when you click on the marker.
+ *
+ * Important:
+ * Html-tags in the label will not be escaped, so you can use them to style the {@link Marker}-detail.
+ * Make sure you escape all html-tags from possible user inputs to prevent possible
+ * XSS-Attacks on the web-client!
+ *
+ *
+ * @param detail the new detail for the {@link Marker}
+ * @return this builder for chaining
+ */
+ B detail(String detail);
+
+ }
+
+}
diff --git a/src/main/java/de/bluecolored/bluemap/api/markers/DistanceRangedMarker.java b/src/main/java/de/bluecolored/bluemap/api/markers/DistanceRangedMarker.java
index 4fcbbf6..c8d1c24 100644
--- a/src/main/java/de/bluecolored/bluemap/api/markers/DistanceRangedMarker.java
+++ b/src/main/java/de/bluecolored/bluemap/api/markers/DistanceRangedMarker.java
@@ -27,6 +27,13 @@ package de.bluecolored.bluemap.api.markers;
import com.flowpowered.math.vector.Vector3d;
import de.bluecolored.bluemap.api.debug.DebugDump;
+/**
+ * @see HtmlMarker
+ * @see POIMarker
+ * @see ShapeMarker
+ * @see ExtrudeMarker
+ * @see LineMarker
+ */
@DebugDump
public abstract class DistanceRangedMarker extends Marker {
diff --git a/src/main/java/de/bluecolored/bluemap/api/markers/ElementMarker.java b/src/main/java/de/bluecolored/bluemap/api/markers/ElementMarker.java
new file mode 100644
index 0000000..10bfc64
--- /dev/null
+++ b/src/main/java/de/bluecolored/bluemap/api/markers/ElementMarker.java
@@ -0,0 +1,113 @@
+package de.bluecolored.bluemap.api.markers;
+
+import com.flowpowered.math.vector.Vector2i;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.regex.Pattern;
+
+/**
+ * @see HtmlMarker
+ * @see POIMarker
+ */
+public interface ElementMarker {
+
+ Pattern STYLE_CLASS_PATTERN = Pattern.compile("-?[_a-zA-Z]+[_a-zA-Z0-9-]*");
+
+ /**
+ * Getter for the position (in pixels) where the element is anchored to the map.
+ * @return the anchor-position in pixels
+ */
+ Vector2i getAnchor();
+
+ /**
+ * Sets the position (in pixels) where the element is anchored to the map.
+ * @param anchor the anchor-position in pixels
+ */
+ void setAnchor(Vector2i anchor);
+
+ /**
+ * Sets the position (in pixels) where the element is anchored to the map.
+ * @param x the anchor-x-position in pixels
+ * @param y the anchor-y-position in pixels
+ */
+ default void setAnchor(int x, int y) {
+ setAnchor(new Vector2i(x, y));
+ }
+
+ /**
+ * Getter for an (unmodifiable) collection of CSS-classed that the element of this marker will have.
+ * @return the style-classes of this element-marker
+ */
+ Collection getStyleClasses();
+
+ /**
+ * Sets the CSS-classes that the element of this marker will have.
+ * All classes must match -?[_a-zA-Z]+[_a-zA-Z0-9-]*
+ * Any existing classes on this marker will be removed.
+ * @param styleClasses the style-classes this element-marker will have
+ */
+ default void setStyleClasses(String... styleClasses) {
+ this.setStyleClasses(Arrays.asList(styleClasses));
+ }
+
+ /**
+ * Sets the CSS-classes that the element of this marker will have.
+ * All classes must match -?[_a-zA-Z]+[_a-zA-Z0-9-]*
+ * Any existing classes on this marker will be removed.
+ * @param styleClasses the style-classes this element-marker will have
+ */
+ void setStyleClasses(Collection styleClasses);
+
+ /**
+ * Adds the CSS-classes that the element of this marker will have.
+ * All classes must match -?[_a-zA-Z]+[_a-zA-Z0-9-]*
+ * @param styleClasses the style-classes this element-marker will have
+ */
+ default void addStyleClasses(String... styleClasses) {
+ this.setStyleClasses(Arrays.asList(styleClasses));
+ }
+
+ /**
+ * Adds the CSS-classes that the element of this marker will have.
+ * All classes must match -?[_a-zA-Z]+[_a-zA-Z0-9-]*
+ * @param styleClasses the style-classes this element-marker will have
+ */
+ void addStyleClasses(Collection styleClasses);
+
+ interface Builder {
+
+ /**
+ * Sets the position (in pixels) where the element is anchored to the map.
+ * @param anchor the anchor-position in pixels
+ * @return this builder for chaining
+ */
+ B anchor(Vector2i anchor);
+
+ /**
+ * Adds the CSS-classes that the element of this marker will have.
+ * All classes must match -?[_a-zA-Z]+[_a-zA-Z0-9-]*
+ * @return this builder for chaining
+ */
+ B styleClasses(String... styleClasses);
+
+ /**
+ * Removes any existing style-classes from this builder.
+ * @see #styleClasses(String...)
+ * @return this builder for chaining
+ */
+ B clearStyleClasses();
+
+ /**
+ * Sets the position (in pixels) where the element is anchored to the map.
+ * @param x the anchor-x-position in pixels
+ * @param y the anchor-y-position in pixels
+ * @return this builder for chaining
+ */
+ default B anchor(int x, int y) {
+ return anchor(new Vector2i(x, y));
+ }
+
+ }
+
+}
diff --git a/src/main/java/de/bluecolored/bluemap/api/markers/HtmlMarker.java b/src/main/java/de/bluecolored/bluemap/api/markers/HtmlMarker.java
index a8d4d03..8b6a806 100644
--- a/src/main/java/de/bluecolored/bluemap/api/markers/HtmlMarker.java
+++ b/src/main/java/de/bluecolored/bluemap/api/markers/HtmlMarker.java
@@ -29,13 +29,16 @@ import com.flowpowered.math.vector.Vector2i;
import com.flowpowered.math.vector.Vector3d;
import de.bluecolored.bluemap.api.debug.DebugDump;
-import java.util.Objects;
+import java.util.*;
/**
* A marker that is a html-element placed somewhere on the map.
*/
+@SuppressWarnings("FieldMayBeFinal")
@DebugDump
-public class HtmlMarker extends DistanceRangedMarker {
+public class HtmlMarker extends DistanceRangedMarker implements ElementMarker {
+
+ private Set classes = new HashSet<>();
private Vector2i anchor;
private String html;
@@ -82,31 +85,16 @@ public class HtmlMarker extends DistanceRangedMarker {
this.anchor = Objects.requireNonNull(anchor, "anchor must not be null");
}
- /**
- * Getter for the position (in pixels) where the html-element is anchored to the map.
- * @return the anchor-position in pixels
- */
+ @Override
public Vector2i getAnchor() {
return anchor;
}
- /**
- * Sets the position (in pixels) where the html-element is anchored to the map.
- * @param anchor the anchor-position in pixels
- */
+ @Override
public void setAnchor(Vector2i anchor) {
this.anchor = Objects.requireNonNull(anchor, "anchor must not be null");
}
- /**
- * Sets the position (in pixels) where the html-element is anchored to the map.
- * @param x the anchor-x-position in pixels
- * @param y the anchor-y-position in pixels
- */
- public void setAnchor(int x, int y) {
- setAnchor(new Vector2i(x, y));
- }
-
/**
* Getter for the html-code of this HTML marker
* @return the html-code
@@ -130,6 +118,28 @@ public class HtmlMarker extends DistanceRangedMarker {
this.html = Objects.requireNonNull(html, "html must not be null");
}
+ @Override
+ public Collection getStyleClasses() {
+ return Collections.unmodifiableCollection(this.classes);
+ }
+
+ @Override
+ public void setStyleClasses(Collection styleClasses) {
+ if (!styleClasses.stream().allMatch(STYLE_CLASS_PATTERN.asMatchPredicate()))
+ throw new IllegalArgumentException("One of the provided style-classes has an invalid format!");
+
+ this.classes.clear();
+ this.classes.addAll(styleClasses);
+ }
+
+ @Override
+ public void addStyleClasses(Collection styleClasses) {
+ if (!styleClasses.stream().allMatch(STYLE_CLASS_PATTERN.asMatchPredicate()))
+ throw new IllegalArgumentException("One of the provided style-classes has an invalid format!");
+
+ this.classes.addAll(styleClasses);
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -158,32 +168,20 @@ public class HtmlMarker extends DistanceRangedMarker {
return new Builder();
}
- public static class Builder extends DistanceRangedMarker.Builder {
+ public static class Builder extends DistanceRangedMarker.Builder
+ implements ElementMarker.Builder {
+
+ Set classes = new HashSet<>();
Vector2i anchor;
String html;
- /**
- * Sets the position (in pixels) where the html-element is anchored to the map.
- * @param anchor the anchor-position in pixels
- * @return this builder for chaining
- */
+ @Override
public Builder anchor(Vector2i anchor) {
this.anchor = anchor;
return this;
}
- /**
- * Sets the position (in pixels) where the html-element is anchored to the map.
- * @param x the anchor-x-position in pixels
- * @param y the anchor-y-position in pixels
- * @return this builder for chaining
- */
- public Builder anchor(int x, int y) {
- this.anchor = new Vector2i(x, y);
- return this;
- }
-
/**
* Sets the html for the {@link HtmlMarker}.
*
@@ -200,6 +198,22 @@ public class HtmlMarker extends DistanceRangedMarker {
return this;
}
+ @Override
+ public Builder styleClasses(String... styleClasses) {
+ Collection styleClassesCollection = Arrays.asList(styleClasses);
+ if (!styleClassesCollection.stream().allMatch(STYLE_CLASS_PATTERN.asMatchPredicate()))
+ throw new IllegalArgumentException("One of the provided style-classes has an invalid format!");
+
+ this.classes.addAll(styleClassesCollection);
+ return this;
+ }
+
+ @Override
+ public Builder clearStyleClasses() {
+ this.classes.clear();
+ return this;
+ }
+
/**
* Creates a new {@link HtmlMarker} with the current builder-settings.
* The minimum required settings to build this marker are:
diff --git a/src/main/java/de/bluecolored/bluemap/api/markers/ObjectMarker.java b/src/main/java/de/bluecolored/bluemap/api/markers/ObjectMarker.java
index a2b07df..ae35e85 100644
--- a/src/main/java/de/bluecolored/bluemap/api/markers/ObjectMarker.java
+++ b/src/main/java/de/bluecolored/bluemap/api/markers/ObjectMarker.java
@@ -31,8 +31,13 @@ import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.Optional;
+/**
+ * @see ShapeMarker
+ * @see ExtrudeMarker
+ * @see LineMarker
+ */
@DebugDump
-public abstract class ObjectMarker extends DistanceRangedMarker {
+public abstract class ObjectMarker extends DistanceRangedMarker implements DetailMarker {
private String detail;
@@ -45,26 +50,12 @@ public abstract class ObjectMarker extends DistanceRangedMarker {
this.detail = Objects.requireNonNull(label, "label must not be null");
}
- /**
- * Getter for the detail of this marker. The label can include html-tags.
- * @return the detail of this {@link Marker}
- */
+ @Override
public String getDetail() {
return detail;
}
- /**
- * Sets the detail of this {@link Marker}. The detail can include html-tags.
- * This is the text that will be displayed on the popup when you click on this marker.
- *
- * Important:
- * Html-tags in the label will not be escaped, so you can use them to style the {@link Marker}-detail.
- * Make sure you escape all html-tags from possible user inputs to prevent possible
- * XSS-Attacks on the web-client!
- *
- *
- * @param detail the new detail for this {@link ObjectMarker}
- */
+ @Override
public void setDetail(String detail) {
this.detail = Objects.requireNonNull(detail);
}
@@ -131,25 +122,14 @@ public abstract class ObjectMarker extends DistanceRangedMarker {
}
public static abstract class Builder>
- extends DistanceRangedMarker.Builder {
+ extends DistanceRangedMarker.Builder
+ implements DetailMarker.Builder {
String detail;
String link;
boolean newTab;
- /**
- * Sets the detail of the {@link Marker}. The detail can include html-tags.
- * This is the text that will be displayed on the popup when you click on the marker.
- *
- * Important:
- * Html-tags in the label will not be escaped, so you can use them to style the {@link Marker}-detail.
- * Make sure you escape all html-tags from possible user inputs to prevent possible
- * XSS-Attacks on the web-client!
- *
- *
- * @param detail the new detail for the {@link Marker}
- * @return this builder for chaining
- */
+ @Override
public B detail(String detail) {
this.detail = detail;
return self();
diff --git a/src/main/java/de/bluecolored/bluemap/api/markers/POIMarker.java b/src/main/java/de/bluecolored/bluemap/api/markers/POIMarker.java
index b5b5aa8..a4a6d97 100644
--- a/src/main/java/de/bluecolored/bluemap/api/markers/POIMarker.java
+++ b/src/main/java/de/bluecolored/bluemap/api/markers/POIMarker.java
@@ -26,13 +26,18 @@ package de.bluecolored.bluemap.api.markers;
import com.flowpowered.math.vector.Vector2i;
import com.flowpowered.math.vector.Vector3d;
-import de.bluecolored.bluemap.api.WebApp;
+import de.bluecolored.bluemap.api.BlueMapMap;
import de.bluecolored.bluemap.api.debug.DebugDump;
-import java.util.Objects;
+import java.util.*;
+@SuppressWarnings("FieldMayBeFinal")
@DebugDump
-public class POIMarker extends DistanceRangedMarker {
+public class POIMarker extends DistanceRangedMarker implements DetailMarker, ElementMarker {
+
+ private Set classes = new HashSet<>();
+
+ private String detail;
private String icon;
private Vector2i anchor;
@@ -72,10 +77,21 @@ public class POIMarker extends DistanceRangedMarker {
*/
public POIMarker(String label, Vector3d position, String iconAddress, Vector2i anchor) {
super("poi", label, position);
+ this.detail = Objects.requireNonNull(label, "label must not be null");
this.icon = Objects.requireNonNull(iconAddress, "iconAddress must not be null");
this.anchor = Objects.requireNonNull(anchor, "anchor must not be null");
}
+ @Override
+ public String getDetail() {
+ return detail;
+ }
+
+ @Override
+ public void setDetail(String detail) {
+ this.detail = detail;
+ }
+
/**
* Getter for the relative address of the icon used to display this {@link POIMarker}
* @return the relative web-address of the icon
@@ -84,18 +100,20 @@ public class POIMarker extends DistanceRangedMarker {
return icon;
}
- /**
- * Getter for the position (in pixels) where the icon is anchored to the map.
- * @return the anchor-position in pixels
- */
+ @Override
public Vector2i getAnchor() {
return anchor;
}
+ @Override
+ public void setAnchor(Vector2i anchor) {
+ this.anchor = Objects.requireNonNull(anchor, "anchor must not be null");
+ }
+
/**
* Sets the icon for this {@link POIMarker}.
* @param iconAddress the web-address of the icon-image. Can be an absolute or relative.
- * You can also use an address returned by {@link WebApp#createImage(java.awt.image.BufferedImage, String)}.
+ * (See: {@link BlueMapMap#getAssetStorage()})
* @param anchorX the x-position of the position (in pixels) where the icon is anchored to the map
* @param anchorY the y-position of the position (in pixels) where the icon is anchored to the map
*/
@@ -106,7 +124,7 @@ public class POIMarker extends DistanceRangedMarker {
/**
* Sets the icon for this {@link POIMarker}.
* @param iconAddress the web-address of the icon-image. Can be an absolute or relative.
- * You can also use an address returned by {@link WebApp#createImage(java.awt.image.BufferedImage, String)}.
+ * (See: {@link BlueMapMap#getAssetStorage()})
* @param anchor the position of the position (in pixels) where the icon is anchored to the map
*/
public void setIcon(String iconAddress, Vector2i anchor) {
@@ -114,6 +132,28 @@ public class POIMarker extends DistanceRangedMarker {
this.anchor = Objects.requireNonNull(anchor, "anchor must not be null");
}
+ @Override
+ public Collection getStyleClasses() {
+ return Collections.unmodifiableCollection(this.classes);
+ }
+
+ @Override
+ public void setStyleClasses(Collection styleClasses) {
+ if (!styleClasses.stream().allMatch(STYLE_CLASS_PATTERN.asMatchPredicate()))
+ throw new IllegalArgumentException("One of the provided style-classes has an invalid format!");
+
+ this.classes.clear();
+ this.classes.addAll(styleClasses);
+ }
+
+ @Override
+ public void addStyleClasses(Collection styleClasses) {
+ if (!styleClasses.stream().allMatch(STYLE_CLASS_PATTERN.asMatchPredicate()))
+ throw new IllegalArgumentException("One of the provided style-classes has an invalid format!");
+
+ this.classes.addAll(styleClasses);
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -142,15 +182,25 @@ public class POIMarker extends DistanceRangedMarker {
return new Builder();
}
- public static class Builder extends DistanceRangedMarker.Builder {
+ public static class Builder extends DistanceRangedMarker.Builder
+ implements DetailMarker.Builder, ElementMarker.Builder {
+ Set classes = new HashSet<>();
+
+ String detail;
String icon;
Vector2i anchor;
+ @Override
+ public Builder detail(String detail) {
+ this.detail = detail;
+ return this;
+ }
+
/**
* Sets the icon for the {@link POIMarker}.
* @param iconAddress the web-address of the icon-image. Can be an absolute or relative.
- * You can also use an address returned by {@link WebApp#createImage(java.awt.image.BufferedImage, String)}.
+ * (See: {@link BlueMapMap#getAssetStorage()})
* @param anchorX the x-position of the position (in pixels) where the icon is anchored to the map
* @param anchorY the y-position of the position (in pixels) where the icon is anchored to the map
* @return this builder for chaining
@@ -162,7 +212,7 @@ public class POIMarker extends DistanceRangedMarker {
/**
* Sets the icon for the {@link POIMarker}.
* @param iconAddress the web-address of the icon-image. Can be an absolute or relative.
- * You can also use an address returned by {@link WebApp#createImage(java.awt.image.BufferedImage, String)}.
+ * (See: {@link BlueMapMap#getAssetStorage()})
* @param anchor the position of the position (in pixels) where the icon is anchored to the map
* @return this builder for chaining
*/
@@ -172,6 +222,12 @@ public class POIMarker extends DistanceRangedMarker {
return this;
}
+ @Override
+ public Builder anchor(Vector2i anchor) {
+ this.anchor = Objects.requireNonNull(anchor, "anchor must not be null");
+ return this;
+ }
+
/**
* The {@link POIMarker} will use the default icon. (See: {@link #icon(String, Vector2i)})
* @return this builder for chaining
@@ -182,6 +238,22 @@ public class POIMarker extends DistanceRangedMarker {
return this;
}
+ @Override
+ public Builder styleClasses(String... styleClasses) {
+ Collection styleClassesCollection = Arrays.asList(styleClasses);
+ if (!styleClassesCollection.stream().allMatch(STYLE_CLASS_PATTERN.asMatchPredicate()))
+ throw new IllegalArgumentException("One of the provided style-classes has an invalid format!");
+
+ this.classes.addAll(styleClassesCollection);
+ return this;
+ }
+
+ @Override
+ public Builder clearStyleClasses() {
+ this.classes.clear();
+ return this;
+ }
+
/**
* Creates a new {@link POIMarker} with the current builder-settings.
* The minimum required settings to build this marker are:
@@ -196,7 +268,9 @@ public class POIMarker extends DistanceRangedMarker {
checkNotNull(label, "label"),
checkNotNull(position, "position")
);
+ if (detail != null) marker.setDetail(detail);
if (icon != null) marker.setIcon(icon, anchor);
+ else if (anchor != null) marker.setAnchor(anchor);
return build(marker);
}