diff options
author | Juuxel <6596629+Juuxel@users.noreply.github.com> | 2020-01-20 22:39:34 +0200 |
---|---|---|
committer | Juuxel <6596629+Juuxel@users.noreply.github.com> | 2020-01-20 22:39:34 +0200 |
commit | 48a6356cc9941293f5ad9a7921b927098877d5cd (patch) | |
tree | 5e0585aef54ca53e0cb644ab8c60442216ffeea6 | |
parent | 661754ffb1e7150659d7dc43d3a7d024d776f0b5 (diff) | |
download | LibGui-48a6356cc9941293f5ad9a7921b927098877d5cd.tar.gz LibGui-48a6356cc9941293f5ad9a7921b927098877d5cd.tar.bz2 LibGui-48a6356cc9941293f5ad9a7921b927098877d5cd.zip |
Add better padding and tiling support to nine-patch painters
The padding can now be set separately for each
direction, and the painters now support tiling
the texture in addition to stretching it.
-rw-r--r-- | src/main/java/io/github/cottonmc/cotton/gui/client/BackgroundPainter.java | 162 |
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; } } } |