aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/client/BackgroundPainter.java162
1 files changed, 148 insertions, 14 deletions
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/BackgroundPainter.java b/src/main/java/io/github/cottonmc/cotton/gui/client/BackgroundPainter.java
index bcd8124..18325c3 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/client/BackgroundPainter.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/client/BackgroundPainter.java
@@ -3,6 +3,7 @@ package io.github.cottonmc.cotton.gui.client;
import io.github.cottonmc.cotton.gui.widget.WItemSlot;
import io.github.cottonmc.cotton.gui.widget.WWidget;
import net.minecraft.util.Identifier;
+import net.minecraft.util.math.MathHelper;
public interface BackgroundPainter {
/**
@@ -80,10 +81,26 @@ public interface BackgroundPainter {
}
/**
+ * Creates a background painter that uses either the {@code light} or the {@code dark} background painter
+ * depending on the current setting.
+ *
+ * @param light the light mode background painter
+ * @param dark the dark mode background painter
+ * @return a new background painter that chooses between the two inputs
+ */
+ public static BackgroundPainter createLightDarkVariants(BackgroundPainter light, BackgroundPainter dark) {
+ return (left, top, panel) -> {
+ if (LibGuiClient.config.darkMode) dark.paintBackground(left, top, panel);
+ else light.paintBackground(left, top, panel);
+ };
+ }
+
+ /**
* The nine-patch background painter paints rectangles using a nine-patch texture.
*
* <p>Nine-patch textures are separated into nine sections: four corners, four edges and a center part.
- * The edges and the center are stretched to fill the area between the corners.
+ * The edges and the center are either tiled or stretched, depending on the {@linkplain BackgroundPainter.NinePatch.Mode mode},
+ * to fill the area between the corners.
*
* <p>{@code NinePatch} painters have a customizable padding that can be applied.
* For example, a GUI panel for a container block might have a padding of 8 pixels, like {@link BackgroundPainter#VANILLA}.
@@ -93,7 +110,11 @@ public interface BackgroundPainter {
private final Identifier texture;
private final int cornerSize;
private final float cornerUv;
- private int padding = 0;
+ private int topPadding = 0;
+ private int leftPadding = 0;
+ private int bottomPadding = 0;
+ private int rightPadding = 0;
+ private Mode mode = Mode.STRETCHING;
/**
* Creates a nine-patch background painter with 4 px corners and a 0.25 cornerUv (corner fraction of whole texture).
@@ -117,12 +138,59 @@ public interface BackgroundPainter {
this.cornerUv = cornerUv;
}
- public int getPadding() {
- return padding;
+ public int getTopPadding() {
+ return topPadding;
+ }
+
+ public NinePatch setTopPadding(int topPadding) {
+ this.topPadding = topPadding;
+ return this;
+ }
+
+ public int getLeftPadding() {
+ return leftPadding;
+ }
+
+ public NinePatch setLeftPadding(int leftPadding) {
+ this.leftPadding = leftPadding;
+ return this;
+ }
+
+ public int getBottomPadding() {
+ return bottomPadding;
+ }
+
+ public NinePatch setBottomPadding(int bottomPadding) {
+ this.bottomPadding = bottomPadding;
+ return this;
+ }
+
+ public int getRightPadding() {
+ return rightPadding;
+ }
+
+ public NinePatch setRightPadding(int rightPadding) {
+ this.rightPadding = rightPadding;
+ return this;
}
public NinePatch setPadding(int padding) {
- this.padding = padding;
+ this.topPadding = this.leftPadding = this.bottomPadding = this.rightPadding = padding;
+ return this;
+ }
+
+ public NinePatch setPadding(int vertical, int horizontal) {
+ this.topPadding = this.bottomPadding = vertical;
+ this.leftPadding = this.rightPadding = horizontal;
+ return this;
+ }
+
+ public NinePatch setPadding(int topPadding, int leftPadding, int bottomPadding, int rightPadding) {
+ this.topPadding = topPadding;
+ this.leftPadding = leftPadding;
+ this.bottomPadding = bottomPadding;
+ this.rightPadding = rightPadding;
+
return this;
}
@@ -138,12 +206,31 @@ public interface BackgroundPainter {
return cornerUv;
}
+ public Mode getMode() {
+ return mode;
+ }
+
+ public NinePatch setMode(Mode mode) {
+ this.mode = mode;
+ return this;
+ }
+
+ public NinePatch stretch() {
+ this.mode = Mode.STRETCHING;
+ return this;
+ }
+
+ public NinePatch tile() {
+ this.mode = Mode.TILING;
+ return this;
+ }
+
@Override
public void paintBackground(int left, int top, WWidget panel) {
- int width = panel.getWidth() + 2 * padding;
- int height = panel.getHeight() + 2 * padding;
- left = left - padding;
- top = top - padding;
+ int width = panel.getWidth() + leftPadding + rightPadding;
+ int height = panel.getHeight() + topPadding + bottomPadding;
+ left = left - leftPadding;
+ top = top - topPadding;
int x1 = left + cornerSize;
int x2 = left + width - cornerSize;
int y1 = top + cornerSize;
@@ -156,12 +243,59 @@ public interface BackgroundPainter {
ScreenDrawing.texturedRect(left, y2, cornerSize, cornerSize, texture, 0, uv2, uv1, 1, 0xFF_FFFFFF);
ScreenDrawing.texturedRect(x2, y2, cornerSize, cornerSize, texture, uv2, uv2, 1, 1, 0xFF_FFFFFF);
- ScreenDrawing.texturedRect(x1, top, width - 2 * cornerSize, cornerSize, texture, uv1, 0, uv2, uv1, 0xFF_FFFFFF);
- ScreenDrawing.texturedRect(left, y1, cornerSize, height - 2 * cornerSize, texture, 0, uv1, uv1, uv2, 0xFF_FFFFFF);
- ScreenDrawing.texturedRect(x1, y2, width - 2 * cornerSize, cornerSize, texture, uv1, uv2, uv2, 1, 0xFF_FFFFFF);
- ScreenDrawing.texturedRect(x2, y1, cornerSize, height - 2 * cornerSize, texture, uv2, uv1, 1, uv2, 0xFF_FFFFFF);
+ if (mode == Mode.TILING) {
+ int tileSize = (int) (cornerSize / cornerUv - 2 * cornerSize);
+ int widthLeft = width - 2 * cornerSize;
+ int heightLeft = height - 2 * cornerSize;
+ int tileCountX = MathHelper.ceil((float) widthLeft / tileSize);
+ int tileCountY = MathHelper.ceil((float) heightLeft / tileSize);
+ for (int i = 0; i < tileCountX; i++) {
+ float px = 1 / 16f;
+ int tileWidth = Math.min(widthLeft, tileSize);
+ float uo = (tileSize - tileWidth) * px; // Used to remove unnecessary pixels on the X axis
+
+ ScreenDrawing.texturedRect(x1 + i * tileSize, top, tileWidth, cornerSize, texture, uv1, 0, uv2 - uo, uv1, 0xFF_FFFFFF);
+ ScreenDrawing.texturedRect(x1 + i * tileSize, y2, tileWidth, cornerSize, texture, uv1, uv2, uv2 - uo, 1, 0xFF_FFFFFF);
+
+ // Reset the height left each time the Y is looped
+ heightLeft = height - 2 * cornerSize;
+
+ for (int j = 0; j < tileCountY; j++) {
+ int tileHeight = Math.min(heightLeft, tileSize);
+ float vo = (tileSize - tileHeight) * px; // Used to remove unnecessary pixels on the Y axis
+
+ ScreenDrawing.texturedRect(left, y1 + j * tileSize, cornerSize, tileHeight, texture, 0, uv1, uv1, uv2 - vo, 0xFF_FFFFFF);
+ ScreenDrawing.texturedRect(x2, y1 + j * tileSize, cornerSize, tileHeight, texture, uv2, uv1, 1, uv2 - vo, 0xFF_FFFFFF);
+
+ ScreenDrawing.texturedRect(x1 + i * tileSize, y1 + j * tileSize, tileWidth, tileHeight, texture, uv1, uv1, uv2 - uo, uv2 - vo, 0xFF_FFFFFF);
+ heightLeft -= tileSize;
+ }
+ widthLeft -= tileSize;
+ }
+ } else {
+ ScreenDrawing.texturedRect(x1, top, width - 2 * cornerSize, cornerSize, texture, uv1, 0, uv2, uv1, 0xFF_FFFFFF);
+ ScreenDrawing.texturedRect(left, y1, cornerSize, height - 2 * cornerSize, texture, 0, uv1, uv1, uv2, 0xFF_FFFFFF);
+ ScreenDrawing.texturedRect(x1, y2, width - 2 * cornerSize, cornerSize, texture, uv1, uv2, uv2, 1, 0xFF_FFFFFF);
+ ScreenDrawing.texturedRect(x2, y1, cornerSize, height - 2 * cornerSize, texture, uv2, uv1, 1, uv2, 0xFF_FFFFFF);
+
+ ScreenDrawing.texturedRect(x1, y1, width - 2 * cornerSize, height - 2 * cornerSize, texture, uv1, uv1, uv2, uv2, 0xFF_FFFFFF);
+ }
+ }
+
+ /**
+ * The mode of a nine-patch painter defines how it fills the area between the corners.
+ */
+ public enum Mode {
+ /**
+ * The texture is stretched to fill the edges and the center.
+ * This is the default mode.
+ */
+ STRETCHING,
- ScreenDrawing.texturedRect(x1, y1, width - 2 * cornerSize, height - 2 * cornerSize, texture, uv1, uv1, uv2, uv2, 0xFF_FFFFFF);
+ /**
+ * The texture is tiled to fill the edges and the center.
+ */
+ TILING;
}
}
}