mirror of
https://github.com/BlueMap-Minecraft/BlueMapAPI.git
synced 2024-11-27 12:46:04 +01:00
Add builder-pattern to all Markers, MarkerSet, Line and Shape
This commit is contained in:
parent
8265cdfe05
commit
97c7f7a916
@ -101,4 +101,42 @@ public int hashCode() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static abstract class Builder<T extends DistanceRangedMarker, B extends DistanceRangedMarker.Builder<T, B>>
|
||||
extends Marker.Builder<T, B> {
|
||||
|
||||
Double minDistance, maxDistance;
|
||||
|
||||
/**
|
||||
* Sets the minimum distance of the camera to the position of the {@link Marker} for it to be displayed.<br>
|
||||
* If the camera is closer to this {@link Marker} than this distance, it will be hidden!
|
||||
*
|
||||
* @param minDistance the new minimum distance
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public B minDistance(double minDistance) {
|
||||
this.minDistance = minDistance;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum distance of the camera to the position of the {@link Marker} for it to be displayed.<br>
|
||||
* If the camera is further to this {@link Marker} than this distance, it will be hidden!
|
||||
*
|
||||
* @param maxDistance the new maximum distance
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public B maxDistance(double maxDistance) {
|
||||
this.maxDistance = maxDistance;
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
T build(T marker) {
|
||||
if (minDistance != null) marker.setMinDistance(minDistance);
|
||||
if (maxDistance != null) marker.setMaxDistance(maxDistance);
|
||||
return super.build(marker);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -64,12 +64,17 @@ private ExtrudeMarker() {
|
||||
* @see #setShape(Shape, float, float)
|
||||
*/
|
||||
public ExtrudeMarker(String label, Shape shape, float shapeMinY, float shapeMaxY) {
|
||||
this(label, calculateShapeCenter(Objects.requireNonNull(shape, "shape must not be null"), shapeMinY, shapeMaxY), shape, shapeMinY, shapeMaxY);
|
||||
this(
|
||||
label,
|
||||
calculateShapeCenter(Objects.requireNonNull(shape, "shape must not be null"), shapeMinY, shapeMaxY),
|
||||
shape, shapeMinY, shapeMaxY
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ExtrudeMarker}.
|
||||
* <p><i>(Since the shape has its own positions, the position is only used to determine e.g. the distance to the camera)</i></p>
|
||||
* <p><i>(Since the shape has its own positions, the position is only used to determine
|
||||
* e.g. the distance to the camera)</i></p>
|
||||
*
|
||||
* @param label the label of the marker
|
||||
* @param position the coordinates of the marker
|
||||
@ -90,7 +95,8 @@ public ExtrudeMarker(String label, Vector3d position, Shape shape, float shapeMi
|
||||
|
||||
/**
|
||||
* Getter for {@link Shape} of this {@link ExtrudeMarker}.
|
||||
* <p>The shape is placed on the xz-plane of the map, so the y-coordinates of the {@link Shape}'s points are the z-coordinates in the map.</p>
|
||||
* <p>The shape is placed on the xz-plane of the map, so the y-coordinates of the {@link Shape}'s points are the
|
||||
* z-coordinates in the map.</p>
|
||||
* @return the {@link Shape}
|
||||
*/
|
||||
public Shape getShape() {
|
||||
@ -117,7 +123,8 @@ public float getShapeMaxY() {
|
||||
|
||||
/**
|
||||
* Sets the {@link Shape} of this {@link ExtrudeMarker}.
|
||||
* <p>The shape is placed on the xz-plane of the map, so the y-coordinates of the {@link Shape}'s points will be the z-coordinates in the map.</p>
|
||||
* <p>The shape is placed on the xz-plane of the map, so the y-coordinates of the {@link Shape}'s points will be
|
||||
* the z-coordinates in the map.</p>
|
||||
* <i>(The shape will be extruded from minY to maxY on the map)</i>
|
||||
* @param shape the new {@link Shape}
|
||||
* @param minY the new min-height (y-coordinate) of the shape on the map
|
||||
@ -140,7 +147,8 @@ public void centerPosition() {
|
||||
}
|
||||
|
||||
/**
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled, you'll only see the marker when it is not behind anything.
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled,
|
||||
* you'll only see the marker when it is not behind anything.
|
||||
* @return <code>true</code> if the depthTest is enabled
|
||||
*/
|
||||
public boolean isDepthTestEnabled() {
|
||||
@ -148,7 +156,8 @@ public boolean isDepthTestEnabled() {
|
||||
}
|
||||
|
||||
/**
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled, you'll only see the marker when it is not behind anything.
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled,
|
||||
* you'll only see the marker when it is not behind anything.
|
||||
* @param enabled if the depth-test should be enabled for this {@link ExtrudeMarker}
|
||||
*/
|
||||
public void setDepthTestEnabled(boolean enabled) {
|
||||
@ -251,4 +260,114 @@ private static Vector3d calculateShapeCenter(Shape shape, float shapeMinY, float
|
||||
return new Vector3d(center.getX(), centerY, center.getY());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder for {@link ExtrudeMarker}s.
|
||||
* @return a new Builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder extends ObjectMarker.Builder<ExtrudeMarker, Builder> {
|
||||
|
||||
Shape shape;
|
||||
float shapeMinY, shapeMaxY;
|
||||
Boolean depthTest;
|
||||
Integer lineWidth;
|
||||
Color lineColor;
|
||||
Color fillColor;
|
||||
|
||||
/**
|
||||
* Sets the {@link Shape} of the {@link ExtrudeMarker}.
|
||||
* <p>The shape is placed on the xz-plane of the map, so the y-coordinates of the {@link Shape}'s points will
|
||||
* be the z-coordinates in the map.</p>
|
||||
* <i>(The shape will be extruded from minY to maxY on the map)</i>
|
||||
* @param shape the new {@link Shape}
|
||||
* @param minY the new min-height (y-coordinate) of the shape on the map
|
||||
* @param maxY the new max-height (y-coordinate) of the shape on the map
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder shape(Shape shape, float minY, float maxY) {
|
||||
this.shape = shape;
|
||||
this.shapeMinY = minY;
|
||||
this.shapeMaxY = maxY;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the {@link ExtrudeMarker} to the center of the {@link Shape} (it's bounding box).
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder centerPosition() {
|
||||
position(null);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled,
|
||||
* you'll only see the marker when it is not behind anything.
|
||||
* @param enabled if the depth-test should be enabled for this {@link ExtrudeMarker}
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder depthTestEnabled(boolean enabled) {
|
||||
this.depthTest = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the width of the lines for the {@link ExtrudeMarker}.
|
||||
* @param width the new width in pixels
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder lineWidth(int width) {
|
||||
this.lineWidth = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Color} of the border-line of the shape.
|
||||
* @param color the new line-color
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder lineColor(Color color) {
|
||||
this.lineColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fill-{@link Color} of the shape.
|
||||
* @param color the new fill-color
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder fillColor(Color color) {
|
||||
this.fillColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ExtrudeMarker} with the current builder-settings.<br>
|
||||
* The minimum required settings to build this marker are:
|
||||
* <ul>
|
||||
* <li>{@link #label(String)}</li>
|
||||
* <li>{@link #shape(Shape, float, float)}</li>
|
||||
* </ul>
|
||||
* @return The new {@link ExtrudeMarker}-instance
|
||||
*/
|
||||
@Override
|
||||
public ExtrudeMarker build() {
|
||||
ExtrudeMarker marker = new ExtrudeMarker(
|
||||
checkNotNull(label, "label"),
|
||||
checkNotNull(shape, "shape"),
|
||||
shapeMinY,
|
||||
shapeMaxY
|
||||
);
|
||||
if (depthTest != null) marker.setDepthTestEnabled(depthTest);
|
||||
if (lineWidth != null) marker.setLineWidth(lineWidth);
|
||||
if (lineColor != null) marker.setLineColor(lineColor);
|
||||
if (fillColor != null) marker.setFillColor(fillColor);
|
||||
return build(marker);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -120,7 +120,8 @@ public String getHtml() {
|
||||
*
|
||||
* <p>
|
||||
* <b>Important:</b><br>
|
||||
* Make sure you escape all html-tags from possible user inputs to prevent possible <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">XSS-Attacks</a> on the web-client!
|
||||
* Make sure you escape all html-tags from possible user inputs to prevent possible
|
||||
* <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">XSS-Attacks</a> on the web-client!
|
||||
* </p>
|
||||
*
|
||||
* @param html the html that will be inserted as the marker.
|
||||
@ -149,4 +150,77 @@ public int hashCode() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder for {@link HtmlMarker}s.
|
||||
* @return a new Builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder extends DistanceRangedMarker.Builder<HtmlMarker, Builder> {
|
||||
|
||||
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
|
||||
*/
|
||||
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}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Important:</b><br>
|
||||
* Make sure you escape all html-tags from possible user inputs to prevent possible <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">XSS-Attacks</a> on the web-client!
|
||||
* </p>
|
||||
*
|
||||
* @param html the html that will be inserted as the marker.
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder html(String html) {
|
||||
this.html = html;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link HtmlMarker} with the current builder-settings.<br>
|
||||
* The minimum required settings to build this marker are:
|
||||
* <ul>
|
||||
* <li>{@link #setLabel(String)}</li>
|
||||
* <li>{@link #setPosition(Vector3d)}</li>
|
||||
* <li>{@link #setHtml(String)}</li>
|
||||
* </ul>
|
||||
* @return The new {@link HtmlMarker}-instance
|
||||
*/
|
||||
@Override
|
||||
public HtmlMarker build() {
|
||||
HtmlMarker marker = new HtmlMarker(
|
||||
checkNotNull(label, "label"),
|
||||
checkNotNull(position, "position"),
|
||||
checkNotNull(html, "html")
|
||||
);
|
||||
if (anchor != null) marker.setAnchor(anchor);
|
||||
return build(marker);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -59,12 +59,13 @@ private LineMarker() {
|
||||
* @see #setLine(Line)
|
||||
*/
|
||||
public LineMarker(String label, Line line) {
|
||||
this(label, calculateLineCenter(Objects.requireNonNull(line, "shape must not be null")), line);
|
||||
this(label, calculateLineCenter(Objects.requireNonNull(line, "line must not be null")), line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link LineMarker}.
|
||||
* <p><i>(Since the line has its own positions, the position is only used to determine e.g. the distance to the camera)</i></p>
|
||||
* <p><i>(Since the line has its own positions, the position is only used to determine
|
||||
* e.g. the distance to the camera)</i></p>
|
||||
*
|
||||
* @param label the label of the marker
|
||||
* @param position the coordinates of the marker
|
||||
@ -106,7 +107,8 @@ public void centerPosition() {
|
||||
}
|
||||
|
||||
/**
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled, you'll only see the marker when it is not behind anything.
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled,
|
||||
* you'll only see the marker when it is not behind anything.
|
||||
* @return <code>true</code> if the depthTest is enabled
|
||||
*/
|
||||
public boolean isDepthTestEnabled() {
|
||||
@ -114,7 +116,8 @@ public boolean isDepthTestEnabled() {
|
||||
}
|
||||
|
||||
/**
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled, you'll only see the marker when it is not behind anything.
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled,
|
||||
* you'll only see the marker when it is not behind anything.
|
||||
* @param enabled if the depth-test should be enabled for this {@link LineMarker}
|
||||
*/
|
||||
public void setDepthTestEnabled(boolean enabled) {
|
||||
@ -181,4 +184,90 @@ private static Vector3d calculateLineCenter(Line line) {
|
||||
return line.getMin().add(line.getMax()).mul(0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder for {@link LineMarker}s.
|
||||
* @return a new Builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder extends ObjectMarker.Builder<LineMarker, Builder> {
|
||||
|
||||
Line line;
|
||||
Boolean depthTest;
|
||||
Integer lineWidth;
|
||||
Color lineColor;
|
||||
|
||||
/**
|
||||
* Sets the {@link Line} of the {@link LineMarker}.
|
||||
* @param line the new {@link Line}
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder line(Line line) {
|
||||
this.line = line;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the {@link LineMarker} to the center of the {@link Line} (it's bounding box).
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder centerPosition() {
|
||||
position(null);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map.
|
||||
* If it is enabled, you'll only see the marker when it is not behind anything.
|
||||
* @param enabled if the depth-test should be enabled for the {@link LineMarker}
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder depthTestEnabled(boolean enabled) {
|
||||
this.depthTest = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the width of the lines for this {@link LineMarker}.
|
||||
* @param width the new width in pixels
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder lineWidth(int width) {
|
||||
this.lineWidth = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Color} of the border-line of the shape.
|
||||
* @param color the new line-color
|
||||
*/
|
||||
public Builder lineColor(Color color) {
|
||||
this.lineColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link LineMarker} with the current builder-settings.<br>
|
||||
* The minimum required settings to build this marker are:
|
||||
* <ul>
|
||||
* <li>{@link #label(String)}</li>
|
||||
* <li>{@link #line(Line)}</li>
|
||||
* </ul>
|
||||
* @return The new {@link LineMarker}-instance
|
||||
*/
|
||||
public LineMarker build() {
|
||||
LineMarker marker = new LineMarker(
|
||||
checkNotNull(label, "label"),
|
||||
checkNotNull(line, "line")
|
||||
);
|
||||
if (depthTest != null) marker.setDepthTestEnabled(depthTest);
|
||||
if (lineWidth != null) marker.setLineWidth(lineWidth);
|
||||
if (lineColor != null) marker.setLineColor(lineColor);
|
||||
return build(marker);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public String getLabel() {
|
||||
*/
|
||||
public void setLabel(String label) {
|
||||
//escape html-tags
|
||||
this.label = label
|
||||
this.label = Objects.requireNonNull(label, "label cannot be null")
|
||||
.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">");
|
||||
@ -94,7 +94,7 @@ public Vector3d getPosition() {
|
||||
* @param position the new position
|
||||
*/
|
||||
public void setPosition(Vector3d position) {
|
||||
this.position = position;
|
||||
this.position = Objects.requireNonNull(position, "position cannot be null");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,4 +127,65 @@ public int hashCode() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static abstract class Builder<T extends Marker, B extends Marker.Builder<T, B>> {
|
||||
|
||||
String label;
|
||||
Vector3d position;
|
||||
|
||||
/**
|
||||
* Sets the label of the {@link Marker}.
|
||||
* <p><i>(HTML-Tags will be escaped.)</i></p>
|
||||
* @param label the new label for the {@link Marker}
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public B label(String label) {
|
||||
this.label = label;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of where the {@link Marker} lives on the map.
|
||||
* @param position the new position
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public B position(Vector3d position) {
|
||||
this.position = position;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of where the {@link Marker} lives on the map.
|
||||
* @param x the x-coordinate of the new position
|
||||
* @param y the y-coordinate of the new position
|
||||
* @param z the z-coordinate of the new position
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public B position(int x, int y, int z) {
|
||||
return position(new Vector3d(x, y, z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Marker} with the current builder-settings
|
||||
* @return The new {@link Marker}-instance
|
||||
*/
|
||||
public abstract T build();
|
||||
|
||||
T build(T marker) {
|
||||
if (label != null) marker.setLabel(label);
|
||||
if (position != null) marker.setPosition(position);
|
||||
return marker;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
B self() {
|
||||
return (B) this;
|
||||
}
|
||||
|
||||
<O> O checkNotNull(O object, String name) {
|
||||
if (object == null) throw new IllegalStateException(name + " has to be set and cannot be null");
|
||||
return object;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -82,15 +82,20 @@ public MarkerSet(String label, boolean toggleable, boolean defaultHidden) {
|
||||
|
||||
/**
|
||||
* Getter for the label of this {@link MarkerSet}.
|
||||
* <p>The label is used in the web-app to name the toggle-button of this {@link MarkerSet} if it is toggleable. ({@link #isToggleable()})</p>
|
||||
* <p>The label is used in the web-app to name the toggle-button of this {@link MarkerSet} if it is toggleable.
|
||||
* ({@link #isToggleable()})</p>
|
||||
*
|
||||
* @return the label of this {@link MarkerSet}
|
||||
*/
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the label of this {@link MarkerSet}.
|
||||
* <p>The label is used in the web-app to name the toggle-button of this {@link MarkerSet} if it is toggleable. ({@link #isToggleable()})</p>
|
||||
* <p>The label is used in the web-app to name the toggle-button of this {@link MarkerSet} if it is toggleable.
|
||||
* ({@link #isToggleable()})</p>
|
||||
*
|
||||
* @param label the new label
|
||||
*/
|
||||
public void setLabel(String label) {
|
||||
@ -99,7 +104,9 @@ public void setLabel(String label) {
|
||||
|
||||
/**
|
||||
* Checks if the {@link MarkerSet} is toggleable.
|
||||
* <p>If this is <code>true</code>, the web-app will display a toggle-button for this {@link MarkerSet} so the user can choose to enable/disable all markers of this set.</p>
|
||||
* <p>If this is <code>true</code>, the web-app will display a toggle-button for this {@link MarkerSet} so the user
|
||||
* can choose to enable/disable all markers of this set.</p>
|
||||
*
|
||||
* @return whether this {@link MarkerSet} is toggleable
|
||||
*/
|
||||
public boolean isToggleable() {
|
||||
@ -108,7 +115,9 @@ public boolean isToggleable() {
|
||||
|
||||
/**
|
||||
* Changes if this {@link MarkerSet} is toggleable.
|
||||
* <p>If this is <code>true</code>, the web-app will display a toggle-button for this {@link MarkerSet} so the user can choose to enable/disable all markers of this set.</p>
|
||||
* <p>If this is <code>true</code>, the web-app will display a toggle-button for this {@link MarkerSet} so the user
|
||||
* can choose to enable/disable all markers of this set.</p>
|
||||
*
|
||||
* @param toggleable whether this {@link MarkerSet} should be toggleable
|
||||
*/
|
||||
public void setToggleable(boolean toggleable) {
|
||||
@ -117,7 +126,9 @@ public void setToggleable(boolean toggleable) {
|
||||
|
||||
/**
|
||||
* Checks if this {@link MarkerSet} is hidden by default.
|
||||
* <p>This is basically the default-state of the toggle-button from {@link #isToggleable()}. If this is <code>true</code> the markers of this marker set will initially be hidden and can be displayed using the toggle-button.</p>
|
||||
* <p>This is basically the default-state of the toggle-button from {@link #isToggleable()}.
|
||||
* If this is <code>true</code> the markers of this marker set will initially be hidden and can be displayed
|
||||
* using the toggle-button.</p>
|
||||
*
|
||||
* @return whether this {@link MarkerSet} is hidden by default
|
||||
* @see #isToggleable()
|
||||
@ -128,13 +139,14 @@ public boolean isDefaultHidden() {
|
||||
|
||||
/**
|
||||
* Sets if this {@link MarkerSet} is hidden by default.
|
||||
* <p>This is basically the default-state of the toggle-button from {@link #isToggleable()}. If this is <code>true</code> the markers of this marker set will initially be hidden and can be displayed using the toggle-button.</p>
|
||||
* <p>This is basically the default-state of the toggle-button from {@link #isToggleable()}. If this is
|
||||
* <code>true</code> the markers of this marker set will initially be hidden and can be displayed using the toggle-button.</p>
|
||||
*
|
||||
* @param defaultHide whether this {@link MarkerSet} should be hidden by default
|
||||
* @param defaultHidden whether this {@link MarkerSet} should be hidden by default
|
||||
* @see #isToggleable()
|
||||
*/
|
||||
public void setDefaultHidden(boolean defaultHide) {
|
||||
this.defaultHidden = defaultHide;
|
||||
public void setDefaultHidden(boolean defaultHidden) {
|
||||
this.defaultHidden = defaultHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,4 +181,83 @@ public int hashCode() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder for {@link MarkerSet}s.
|
||||
* @return a new Builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private String label;
|
||||
private Boolean toggleable, defaultHidden;
|
||||
|
||||
/**
|
||||
* Sets the label of the {@link MarkerSet}.
|
||||
* <p>The label is used in the web-app to name the toggle-button of the {@link MarkerSet} if it is toggleable.
|
||||
* ({@link #toggleable(Boolean)})</p>
|
||||
*
|
||||
* @param label the new label
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder label(String label) {
|
||||
this.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes if the {@link MarkerSet} is toggleable.
|
||||
* <p>If this is <code>true</code>, the web-app will display a toggle-button for the {@link MarkerSet}
|
||||
* so the user can choose to enable/disable all markers of this set.</p>
|
||||
*
|
||||
* @param toggleable whether the {@link MarkerSet} should be toggleable
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder toggleable(Boolean toggleable) {
|
||||
this.toggleable = toggleable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if this {@link MarkerSet} is hidden by default.
|
||||
* <p>This is basically the default-state of the toggle-button from {@link #toggleable(Boolean)}.
|
||||
* If this is <code>true</code> the markers of this marker set will initially be hidden and can be displayed
|
||||
* using the toggle-button.</p>
|
||||
*
|
||||
* @param defaultHidden whether this {@link MarkerSet} should be hidden by default
|
||||
* @return this builder for chaining
|
||||
* @see #isToggleable()
|
||||
*/
|
||||
public Builder defaultHidden(Boolean defaultHidden) {
|
||||
this.defaultHidden = defaultHidden;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MarkerSet} with the current builder-settings.<br>
|
||||
* The minimum required settings to build this marker-set are:
|
||||
* <ul>
|
||||
* <li>{@link #setLabel(String)}</li>
|
||||
* </ul>
|
||||
* @return The new {@link MarkerSet}-instance
|
||||
*/
|
||||
public MarkerSet build() {
|
||||
MarkerSet markerSet = new MarkerSet(
|
||||
checkNotNull(label, "label")
|
||||
);
|
||||
if (toggleable != null) markerSet.setToggleable(toggleable);
|
||||
if (defaultHidden != null) markerSet.setDefaultHidden(defaultHidden);
|
||||
return markerSet;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
<O> O checkNotNull(O object, String name) {
|
||||
if (object == null) throw new IllegalStateException(name + " has to be set and cannot be null");
|
||||
return object;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,19 +47,20 @@ public ObjectMarker(String type, String label, Vector3d position) {
|
||||
|
||||
/**
|
||||
* Getter for the detail of this marker. The label can include html-tags.
|
||||
* @return the detail of this {@link ObjectMarker}
|
||||
* @return the detail of this {@link Marker}
|
||||
*/
|
||||
public String getDetail() {
|
||||
return detail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the detail of this {@link ObjectMarker}. The detail can include html-tags.<br>
|
||||
* Sets the detail of this {@link Marker}. The detail can include html-tags.<br>
|
||||
* This is the text that will be displayed on the popup when you click on this marker.
|
||||
* <p>
|
||||
* <b>Important:</b><br>
|
||||
* Html-tags in the label will not be escaped, so you can use them to style the {@link ObjectMarker}-detail.<br>
|
||||
* Make sure you escape all html-tags from possible user inputs to prevent possible <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">XSS-Attacks</a> on the web-client!
|
||||
* Html-tags in the label will not be escaped, so you can use them to style the {@link Marker}-detail.<br>
|
||||
* Make sure you escape all html-tags from possible user inputs to prevent possible
|
||||
* <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">XSS-Attacks</a> on the web-client!
|
||||
* </p>
|
||||
*
|
||||
* @param detail the new detail for this {@link ObjectMarker}
|
||||
@ -129,4 +130,61 @@ public int hashCode() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static abstract class Builder<T extends ObjectMarker, B extends ObjectMarker.Builder<T, B>>
|
||||
extends DistanceRangedMarker.Builder<T, B> {
|
||||
|
||||
String detail;
|
||||
String link;
|
||||
boolean newTab;
|
||||
|
||||
/**
|
||||
* Sets the detail of the {@link Marker}. The detail can include html-tags.<br>
|
||||
* This is the text that will be displayed on the popup when you click on the marker.
|
||||
* <p>
|
||||
* <b>Important:</b><br>
|
||||
* Html-tags in the label will not be escaped, so you can use them to style the {@link Marker}-detail.<br>
|
||||
* Make sure you escape all html-tags from possible user inputs to prevent possible
|
||||
* <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">XSS-Attacks</a> on the web-client!
|
||||
* </p>
|
||||
*
|
||||
* @param detail the new detail for the {@link Marker}
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public B detail(String detail) {
|
||||
this.detail = detail;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the link-address of the {@link Marker}.<br>
|
||||
* If a link is present, this link will be followed when the user clicks on the marker in the web-app.
|
||||
*
|
||||
* @param link the link, or <code>null</code> to disable the link
|
||||
* @param newTab whether the link should be opened in a new tab
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public B link(String link, boolean newTab) {
|
||||
this.link = link;
|
||||
this.newTab = newTab;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link Marker} will have no link. (See: {@link #link(String, boolean)})
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public B noLink() {
|
||||
this.link = null;
|
||||
this.newTab = false;
|
||||
return self();
|
||||
}
|
||||
|
||||
T build(T marker) {
|
||||
if (detail != null) marker.setDetail(detail);
|
||||
if (link != null) marker.setLink(link, newTab);
|
||||
return super.build(marker);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -134,4 +134,72 @@ public int hashCode() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder for {@link POIMarker}s.
|
||||
* @return a new Builder
|
||||
*/
|
||||
public static Builder toBuilder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder extends DistanceRangedMarker.Builder<POIMarker, Builder> {
|
||||
|
||||
String icon;
|
||||
Vector2i anchor;
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
* @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
|
||||
*/
|
||||
public Builder icon(String iconAddress, int anchorX, int anchorY) {
|
||||
return icon(iconAddress, new Vector2i(anchorX, anchorY));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
* @param anchor the position of the position (in pixels) where the icon is anchored to the map
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder icon(String iconAddress, Vector2i anchor) {
|
||||
this.icon = Objects.requireNonNull(iconAddress, "iconAddress must not be null");
|
||||
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
|
||||
*/
|
||||
public Builder defaultIcon() {
|
||||
this.icon = null;
|
||||
this.anchor = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link POIMarker} with the current builder-settings.<br>
|
||||
* The minimum required settings to build this marker are:
|
||||
* <ul>
|
||||
* <li>{@link #setLabel(String)}</li>
|
||||
* <li>{@link #setPosition(Vector3d)}</li>
|
||||
* </ul>
|
||||
* @return The new {@link POIMarker}-instance
|
||||
*/
|
||||
public POIMarker build() {
|
||||
POIMarker marker = new POIMarker(
|
||||
checkNotNull(label, "label"),
|
||||
checkNotNull(position, "position")
|
||||
);
|
||||
if (icon != null) marker.setIcon(icon, anchor);
|
||||
return build(marker);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -69,7 +69,8 @@ public ShapeMarker(String label, Shape shape, float shapeY) {
|
||||
|
||||
/**
|
||||
* Creates a new {@link ShapeMarker}.
|
||||
* <p><i>(Since the shape has its own positions, the position is only used to determine e.g. the distance to the camera)</i></p>
|
||||
* <p><i>(Since the shape has its own positions, the position is only used to determine
|
||||
* e.g. the distance to the camera)</i></p>
|
||||
*
|
||||
* @param label the label of the marker
|
||||
* @param position the coordinates of the marker
|
||||
@ -88,7 +89,8 @@ public ShapeMarker(String label, Vector3d position, Shape shape, float shapeY) {
|
||||
|
||||
/**
|
||||
* Getter for {@link Shape} of this {@link ShapeMarker}.
|
||||
* <p>The shape is placed on the xz-plane of the map, so the y-coordinates of the {@link Shape}'s points are the z-coordinates in the map.</p>
|
||||
* <p>The shape is placed on the xz-plane of the map, so the y-coordinates of the {@link Shape}'s points are
|
||||
* the z-coordinates in the map.</p>
|
||||
* @return the {@link Shape}
|
||||
*/
|
||||
public Shape getShape() {
|
||||
@ -105,7 +107,8 @@ public float getShapeY() {
|
||||
|
||||
/**
|
||||
* Sets the {@link Shape} of this {@link ShapeMarker}.
|
||||
* <p>The shape is placed on the xz-plane of the map, so the y-coordinates of the {@link Shape}'s points will be the z-coordinates in the map.</p>
|
||||
* <p>The shape is placed on the xz-plane of the map, so the y-coordinates of the {@link Shape}'s points will be
|
||||
* the z-coordinates in the map.</p>
|
||||
* @param shape the new {@link Shape}
|
||||
* @param y the new height (y-coordinate) of the shape on the map
|
||||
*
|
||||
@ -125,7 +128,8 @@ public void centerPosition() {
|
||||
}
|
||||
|
||||
/**
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled, you'll only see the marker when it is not behind anything.
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled,
|
||||
* you'll only see the marker when it is not behind anything.
|
||||
* @return <code>true</code> if the depthTest is enabled
|
||||
*/
|
||||
public boolean isDepthTestEnabled() {
|
||||
@ -133,7 +137,8 @@ public boolean isDepthTestEnabled() {
|
||||
}
|
||||
|
||||
/**
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled, you'll only see the marker when it is not behind anything.
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map. If it is enabled,
|
||||
* you'll only see the marker when it is not behind anything.
|
||||
* @param enabled if the depth-test should be enabled for this {@link ShapeMarker}
|
||||
*/
|
||||
public void setDepthTestEnabled(boolean enabled) {
|
||||
@ -233,4 +238,109 @@ private static Vector3d calculateShapeCenter(Shape shape, float shapeY) {
|
||||
return new Vector3d(center.getX(), shapeY, center.getY());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder for {@link ShapeMarker}s.
|
||||
* @return a new Builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder extends ObjectMarker.Builder<ShapeMarker, Builder> {
|
||||
|
||||
Shape shape;
|
||||
float shapeY;
|
||||
Boolean depthTest;
|
||||
Integer lineWidth;
|
||||
Color lineColor;
|
||||
Color fillColor;
|
||||
|
||||
/**
|
||||
* Sets the {@link Shape} of the {@link ShapeMarker}.
|
||||
* <p>The shape is placed on the xz-plane of the map, so the y-coordinates of the {@link Shape}'s points
|
||||
* will be the z-coordinates in the map.</p>
|
||||
* @param shape the new {@link Shape}
|
||||
* @param y the new height (y-coordinate) of the shape on the map
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder shape(Shape shape, float y) {
|
||||
this.shape = shape;
|
||||
this.shapeY = y;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the {@link ShapeMarker} to the center of the {@link Shape} (it's bounding box).
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder centerPosition() {
|
||||
position(null);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the depth-test is disabled, you can see the marker fully through all objects on the map.
|
||||
* If it is enabled, you'll only see the marker when it is not behind anything.
|
||||
* @param enabled if the depth-test should be enabled for the {@link ShapeMarker}
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder depthTestEnabled(boolean enabled) {
|
||||
this.depthTest = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the width of the border-line for the {@link ShapeMarker}.
|
||||
* @param width the new width in pixels
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder lineWidth(int width) {
|
||||
this.lineWidth = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Color} of the border-line of the shape.
|
||||
* @param color the new line-color
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder lineColor(Color color) {
|
||||
this.lineColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fill-{@link Color} of the shape.
|
||||
* @param color the new fill-color
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder fillColor(Color color) {
|
||||
this.fillColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ShapeMarker} with the current builder-settings.<br>
|
||||
* The minimum required settings to build this marker are:
|
||||
* <ul>
|
||||
* <li>{@link #label(String)}</li>
|
||||
* <li>{@link #shape(Shape, float)}</li>
|
||||
* </ul>
|
||||
* @return The new {@link ShapeMarker}-instance
|
||||
*/
|
||||
public ShapeMarker build() {
|
||||
ShapeMarker marker = new ShapeMarker(
|
||||
checkNotNull(label, "label"),
|
||||
checkNotNull(shape, "shape"),
|
||||
shapeY
|
||||
);
|
||||
if (depthTest != null) marker.setDepthTestEnabled(depthTest);
|
||||
if (lineWidth != null) marker.setLineWidth(lineWidth);
|
||||
if (lineColor != null) marker.setLineColor(lineColor);
|
||||
if (fillColor != null) marker.setFillColor(fillColor);
|
||||
return build(marker);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -68,6 +68,15 @@ public Color(int i) {
|
||||
this((i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF, ((i >> 24) & 0xFF) / 255f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new color from the given integer in the format 0xRRGGBB.
|
||||
* @param i the integer to create the color from
|
||||
* @param alpha the alpha value in range 0-1
|
||||
*/
|
||||
public Color(int i, float alpha) {
|
||||
this((i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* The value can be an integer in String-Format (see {@link #Color(int)}) or a string in hexadecimal format
|
||||
* prefixed with # <i>(css-style: e.g. <code>#f16</code> becomes <code>#ff1166</code>)</i>.
|
||||
@ -78,17 +87,34 @@ public Color(String cssColorString) {
|
||||
this(parseColorString(Objects.requireNonNull(cssColorString)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the red-component of the color.
|
||||
* @return the red-component of the color in range 0-255
|
||||
*/
|
||||
public int getRed() {
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the green-component of the color.
|
||||
* @return the green-component of the color in range 0-255
|
||||
*/
|
||||
public int getGreen() {
|
||||
return g;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the blue-component of the color.
|
||||
* @return the blue-component of the color in range 0-255
|
||||
*/
|
||||
public int getBlue() {
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the alpha-component of the color.
|
||||
* @return the alpha-component of the color in range 0-1
|
||||
*/
|
||||
public float getAlpha() {
|
||||
return a;
|
||||
}
|
||||
@ -97,7 +123,9 @@ private static int parseColorString(String val) {
|
||||
if (val.charAt(0) == '#') {
|
||||
val = val.substring(1);
|
||||
if (val.length() == 3) val = val + "f";
|
||||
if (val.length() == 4) val = "" + val.charAt(0) + val.charAt(0) + val.charAt(1) + val.charAt(1) + val.charAt(2) + val.charAt(2) + val.charAt(3) + val.charAt(3);
|
||||
if (val.length() == 4) val = "" +
|
||||
val.charAt(0) + val.charAt(0) + val.charAt(1) + val.charAt(1) +
|
||||
val.charAt(2) + val.charAt(2) + val.charAt(3) + val.charAt(3);
|
||||
if (val.length() == 6) val = val + "ff";
|
||||
if (val.length() != 8) throw new NumberFormatException("Invalid color format!");
|
||||
val = val.substring(6, 8) + val.substring(0, 6); // move alpha to front
|
||||
|
@ -28,7 +28,10 @@
|
||||
import de.bluecolored.bluemap.api.debug.DebugDump;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A line consisting of 2 or more {@link Vector3d}-points.
|
||||
@ -46,6 +49,10 @@ public Line(Vector3d... points) {
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
public Line(Collection<Vector3d> points) {
|
||||
this(points.toArray(Vector3d[]::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the amount of points in this line.
|
||||
* @return the amount of points
|
||||
@ -54,6 +61,11 @@ public int getPointCount() {
|
||||
return points.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the point at the given index.
|
||||
* @param i the index
|
||||
* @return the point at the given index
|
||||
*/
|
||||
public Vector3d getPoint(int i) {
|
||||
return points[i];
|
||||
}
|
||||
@ -112,4 +124,53 @@ public int hashCode() {
|
||||
return Arrays.hashCode(points);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a builder to build {@link Line}s.
|
||||
* @return a new builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
List<Vector3d> points;
|
||||
|
||||
public Builder() {
|
||||
this.points = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a point to the end of line.
|
||||
* @param point the point to be added.
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder addPoint(Vector3d point) {
|
||||
this.points.add(point);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds multiple points to the end of line.
|
||||
* @param points the points to be added.
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder addPoints(Vector3d... points) {
|
||||
this.points.addAll(Arrays.asList(points));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new {@link Line} with the points set in this builder.<br>
|
||||
* There need to be at least 2 points to build a {@link Line}.
|
||||
* @return the new {@link Line}
|
||||
* @throws IllegalStateException if there are less than 2 points added to this builder
|
||||
*/
|
||||
public Line build() {
|
||||
if (points.size() < 2) throw new IllegalStateException("A line has to have at least 2 points!");
|
||||
return new Line(points);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,10 @@
|
||||
import de.bluecolored.bluemap.api.debug.DebugDump;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A shape consisting of 3 or more {@link Vector2d}-points on a plane.
|
||||
@ -43,10 +46,13 @@ public class Shape {
|
||||
|
||||
public Shape(Vector2d... points) {
|
||||
if (points.length < 3) throw new IllegalArgumentException("A shape has to have at least 3 points!");
|
||||
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
public Shape(Collection<Vector2d> points) {
|
||||
this(points.toArray(Vector2d[]::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the amount of points in this shape.
|
||||
* @return the amount of points
|
||||
@ -55,6 +61,11 @@ public int getPointCount() {
|
||||
return points.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the point at the given index.
|
||||
* @param i the index
|
||||
* @return the point at the given index
|
||||
*/
|
||||
public Vector2d getPoint(int i) {
|
||||
return points[i];
|
||||
}
|
||||
@ -201,4 +212,53 @@ public static Shape createCircle(double centerX, double centerY, double radius,
|
||||
return createCircle(new Vector2d(centerX, centerY), radius, points);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a builder to build {@link Shape}s.
|
||||
* @return a new builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
List<Vector2d> points;
|
||||
|
||||
public Builder() {
|
||||
this.points = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a point to the end of line.
|
||||
* @param point the point to be added.
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder addPoint(Vector2d point) {
|
||||
this.points.add(point);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds multiple points to the end of line.
|
||||
* @param points the points to be added.
|
||||
* @return this builder for chaining
|
||||
*/
|
||||
public Builder addPoints(Vector2d... points) {
|
||||
this.points.addAll(Arrays.asList(points));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new {@link Shape} with the points set in this builder.<br>
|
||||
* There need to be at least 3 points to build a {@link Shape}.
|
||||
* @return the new {@link Shape}
|
||||
* @throws IllegalStateException if there are less than 3 points added to this builder
|
||||
*/
|
||||
public Shape build() {
|
||||
if (points.size() < 3) throw new IllegalStateException("A shape has to have at least 3 points!");
|
||||
return new Shape(points);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user