aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/GuiDescription.java78
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/SyncedGuiDescription.java123
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/ValidatedSlot.java25
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java65
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java57
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/client/LightweightGuiDescription.java49
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/client/Scissors.java147
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/client/ScreenDrawing.java20
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java2
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WBar.java8
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WBox.java122
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java113
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WClippedPanel.java17
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WDynamicLabel.java6
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WItem.java2
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java45
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java71
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java22
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java5
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java9
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WPlayerInvPanel.java13
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WText.java77
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WTiledSprite.java46
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java12
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java36
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/data/Color.java17
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/data/HorizontalAlignment.java (renamed from src/main/java/io/github/cottonmc/cotton/gui/widget/data/Alignment.java)2
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/data/VerticalAlignment.java7
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/icon/Icon.java25
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/icon/ItemIcon.java42
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/icon/TextureIcon.java73
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/icon/package-info.java14
32 files changed, 1181 insertions, 169 deletions
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/GuiDescription.java b/src/main/java/io/github/cottonmc/cotton/gui/GuiDescription.java
index 0c31912..cf1226b 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/GuiDescription.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/GuiDescription.java
@@ -5,6 +5,7 @@ import javax.annotation.Nullable;
import io.github.cottonmc.cotton.gui.impl.FocusHandler;
import io.github.cottonmc.cotton.gui.widget.WPanel;
import io.github.cottonmc.cotton.gui.widget.WWidget;
+import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.screen.PropertyDelegate;
@@ -23,8 +24,30 @@ public interface GuiDescription {
public int getTitleColor();
public GuiDescription setRootPanel(WPanel panel);
+
+ /**
+ * Sets the title color of this GUI.
+ *
+ * <p>The dark-mode title color will also be set by this method.
+ * If the specified color is {@link io.github.cottonmc.cotton.gui.widget.WLabel#DEFAULT_TEXT_COLOR},
+ * the dark-mode color will be {@link io.github.cottonmc.cotton.gui.widget.WLabel#DEFAULT_DARKMODE_TEXT_COLOR};
+ * otherwise it will be the specified color.
+ *
+ * @param color the new title color
+ * @return this GUI
+ */
public GuiDescription setTitleColor(int color);
-
+
+ /**
+ * Sets the light and dark title colors of this GUI.
+ *
+ * @param lightColor the light-mode color
+ * @param darkColor the dark-mode color
+ * @return this GUI
+ * @since 2.1.0
+ */
+ GuiDescription setTitleColor(int lightColor, int darkColor);
+
/** Sets the object which manages the integer properties used by WBars */
public GuiDescription setPropertyDelegate(PropertyDelegate delegate);
@@ -61,4 +84,57 @@ public interface GuiDescription {
default void cycleFocus(boolean lookForwards) {
FocusHandler.cycleFocus(this, lookForwards);
}
+
+ /**
+ * Gets whether this GUI is fullscreen.
+ *
+ * <p>Fullscreen GUIs have no default background painter and
+ * have the root panel stretched to fit the entire screen on the client.
+ *
+ * @return true if this GUI is fullscreen, false otherwise
+ * @since 2.0.0
+ */
+ boolean isFullscreen();
+
+ /**
+ * Sets whether this GUI is fullscreen.
+ *
+ * @param fullscreen true if this GUI is fullscreen, false otherwise
+ * @since 2.0.0
+ */
+ void setFullscreen(boolean fullscreen);
+
+ /**
+ * Gets whether the title of this GUI should be rendered by the screen.
+ *
+ * <p>Modders can disable this to render the title themselves with a widget.
+ *
+ * @return true if the title is visible, false otherwise
+ * @since 2.0.0
+ */
+ boolean isTitleVisible();
+
+ /**
+ * Sets whether the title of this GUI should be rendered by the screen.
+ *
+ * @param titleVisible true if the title is visible, false otherwise
+ * @since 2.0.0
+ */
+ void setTitleVisible(boolean titleVisible);
+
+ /**
+ * Gets the horizontal alignment of the GUI title.
+ *
+ * @return the alignment
+ * @since 2.1.0
+ */
+ HorizontalAlignment getTitleAlignment();
+
+ /**
+ * Sets the horizontal alignment of the GUI title.
+ *
+ * @param alignment the new alignment
+ * @since 2.1.0
+ */
+ void setTitleAlignment(HorizontalAlignment alignment);
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/SyncedGuiDescription.java b/src/main/java/io/github/cottonmc/cotton/gui/SyncedGuiDescription.java
index 5f2bef0..cd47af4 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/SyncedGuiDescription.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/SyncedGuiDescription.java
@@ -1,12 +1,14 @@
package io.github.cottonmc.cotton.gui;
import java.util.ArrayList;
+import java.util.function.Supplier;
import javax.annotation.Nullable;
import io.github.cottonmc.cotton.gui.client.BackgroundPainter;
import io.github.cottonmc.cotton.gui.client.LibGuiClient;
import io.github.cottonmc.cotton.gui.widget.*;
+import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.Block;
@@ -16,6 +18,7 @@ import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
+import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.*;
import net.minecraft.screen.slot.Slot;
@@ -35,19 +38,22 @@ public class SyncedGuiDescription extends ScreenHandler implements GuiDescriptio
protected WPanel rootPanel = new WGridPanel();
protected int titleColor = WLabel.DEFAULT_TEXT_COLOR;
protected int darkTitleColor = WLabel.DEFAULT_DARKMODE_TEXT_COLOR;
-
+ protected boolean fullscreen = false;
+ protected boolean titleVisible = true;
+ protected HorizontalAlignment titleAlignment = HorizontalAlignment.LEFT;
+
protected WWidget focus;
-
- public SyncedGuiDescription(int syncId, PlayerInventory playerInventory) {
- super(null, syncId);
+
+ public SyncedGuiDescription(ScreenHandlerType<?> type, int syncId, PlayerInventory playerInventory) {
+ super(type, syncId);
this.blockInventory = null;
this.playerInventory = playerInventory;
this.world = playerInventory.player.world;
this.propertyDelegate = null;//new ArrayPropertyDelegate(1);
}
- public SyncedGuiDescription(int syncId, PlayerInventory playerInventory, Inventory blockInventory, PropertyDelegate propertyDelegate) {
- super(null, syncId);
+ public SyncedGuiDescription(ScreenHandlerType<?> type, int syncId, PlayerInventory playerInventory, Inventory blockInventory, PropertyDelegate propertyDelegate) {
+ super(type, syncId);
this.blockInventory = blockInventory;
this.playerInventory = playerInventory;
this.world = playerInventory.player.world;
@@ -60,22 +66,31 @@ public class SyncedGuiDescription extends ScreenHandler implements GuiDescriptio
}
public int getTitleColor() {
- return LibGuiClient.config.darkMode ? darkTitleColor : titleColor;
+ return (world.isClient && LibGuiClient.config.darkMode) ? darkTitleColor : titleColor;
}
public SyncedGuiDescription setRootPanel(WPanel panel) {
this.rootPanel = panel;
return this;
}
-
+
+ @Override
public SyncedGuiDescription setTitleColor(int color) {
this.titleColor = color;
+ this.darkTitleColor = (color == WLabel.DEFAULT_TEXT_COLOR) ? WLabel.DEFAULT_DARKMODE_TEXT_COLOR : color;
+ return this;
+ }
+
+ @Override
+ public SyncedGuiDescription setTitleColor(int lightColor, int darkColor) {
+ this.titleColor = lightColor;
+ this.darkTitleColor = darkColor;
return this;
}
@Environment(EnvType.CLIENT)
public void addPainters() {
- if (this.rootPanel!=null) {
+ if (this.rootPanel!=null && !fullscreen) {
this.rootPanel.setBackgroundPainter(BackgroundPainter.VANILLA);
}
}
@@ -373,17 +388,43 @@ public class SyncedGuiDescription extends ScreenHandler implements GuiDescriptio
* @return the found inventory
*/
public static Inventory getBlockInventory(ScreenHandlerContext ctx) {
+ return getBlockInventory(ctx, () -> EmptyInventory.INSTANCE);
+ }
+
+ /**
+ * Gets the block inventory at the context.
+ *
+ * <p>If no inventory is found, returns a simple mutable inventory
+ * with the specified number of slots.
+ *
+ * <p>Searches for these implementations in the following order:
+ * <ol>
+ * <li>Blocks implementing {@code InventoryProvider}</li>
+ * <li>Block entities implementing {@code InventoryProvider}</li>
+ * <li>Block entities implementing {@code Inventory}</li>
+ * </ol>
+ *
+ * @param ctx the context
+ * @param size the fallback inventory size
+ * @return the found inventory
+ * @since 2.0.0
+ */
+ public static Inventory getBlockInventory(ScreenHandlerContext ctx, int size) {
+ return getBlockInventory(ctx, () -> new SimpleInventory(size));
+ }
+
+ private static Inventory getBlockInventory(ScreenHandlerContext ctx, Supplier<Inventory> fallback) {
return ctx.run((world, pos) -> {
BlockState state = world.getBlockState(pos);
Block b = state.getBlock();
-
+
if (b instanceof InventoryProvider) {
Inventory inventory = ((InventoryProvider)b).getInventory(state, world, pos);
if (inventory != null) {
return inventory;
}
}
-
+
BlockEntity be = world.getBlockEntity(pos);
if (be!=null) {
if (be instanceof InventoryProvider) {
@@ -395,9 +436,9 @@ public class SyncedGuiDescription extends ScreenHandler implements GuiDescriptio
return (Inventory)be;
}
}
-
- return EmptyInventory.INSTANCE;
- }).orElse(EmptyInventory.INSTANCE);
+
+ return fallback.get();
+ }).orElseGet(fallback);
}
/**
@@ -420,6 +461,30 @@ public class SyncedGuiDescription extends ScreenHandler implements GuiDescriptio
return new ArrayPropertyDelegate(0);
}).orElse(new ArrayPropertyDelegate(0));
}
+
+ /**
+ * Gets the property delegate at the context.
+ *
+ * <p>If no property delegate is found, returns an array property delegate
+ * with the specified number of properties.
+ *
+ * <p>Searches for block entities implementing {@link PropertyDelegateHolder}.
+ *
+ * @param ctx the context
+ * @param size the number of properties
+ * @return the found property delegate
+ * @since 2.0.0
+ */
+ public static PropertyDelegate getBlockPropertyDelegate(ScreenHandlerContext ctx, int size) {
+ return ctx.run((world, pos) -> {
+ BlockEntity be = world.getBlockEntity(pos);
+ if (be!=null && be instanceof PropertyDelegateHolder) {
+ return ((PropertyDelegateHolder)be).getPropertyDelegate();
+ }
+
+ return new ArrayPropertyDelegate(size);
+ }).orElse(new ArrayPropertyDelegate(size));
+ }
//extends ScreenHandler {
@Override
@@ -455,4 +520,34 @@ public class SyncedGuiDescription extends ScreenHandler implements GuiDescriptio
widget.onFocusLost();
}
}
+
+ @Override
+ public boolean isFullscreen() {
+ return fullscreen;
+ }
+
+ @Override
+ public void setFullscreen(boolean fullscreen) {
+ this.fullscreen = fullscreen;
+ }
+
+ @Override
+ public boolean isTitleVisible() {
+ return titleVisible;
+ }
+
+ @Override
+ public void setTitleVisible(boolean titleVisible) {
+ this.titleVisible = titleVisible;
+ }
+
+ @Override
+ public HorizontalAlignment getTitleAlignment() {
+ return titleAlignment;
+ }
+
+ @Override
+ public void setTitleAlignment(HorizontalAlignment titleAlignment) {
+ this.titleAlignment = titleAlignment;
+ }
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/ValidatedSlot.java b/src/main/java/io/github/cottonmc/cotton/gui/ValidatedSlot.java
index 1e9ee3c..6e7db9c 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/ValidatedSlot.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/ValidatedSlot.java
@@ -7,11 +7,14 @@ import net.minecraft.screen.slot.Slot;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import java.util.function.Predicate;
+
public class ValidatedSlot extends Slot {
private static final Logger LOGGER = LogManager.getLogger();
private final int slotNumber;
private boolean insertingAllowed = true;
private boolean takingAllowed = true;
+ private Predicate<ItemStack> filter;
public ValidatedSlot(Inventory inventory, int index, int x, int y) {
super(inventory, index, x, y);
@@ -21,7 +24,7 @@ public class ValidatedSlot extends Slot {
@Override
public boolean canInsert(ItemStack stack) {
- return insertingAllowed && inventory.isValid(slotNumber, stack);
+ return insertingAllowed && inventory.isValid(slotNumber, stack) && filter.test(stack);
}
@Override
@@ -88,4 +91,24 @@ public class ValidatedSlot extends Slot {
public void setTakingAllowed(boolean takingAllowed) {
this.takingAllowed = takingAllowed;
}
+
+ /**
+ * Gets the item stack filter of this slot.
+ *
+ * @return the item filter
+ * @since 2.0.0
+ */
+ public Predicate<ItemStack> getFilter() {
+ return filter;
+ }
+
+ /**
+ * Sets the item stack filter of this slot.
+ *
+ * @param filter the new item filter
+ * @since 2.0.0
+ */
+ public void setFilter(Predicate<ItemStack> filter) {
+ this.filter = filter;
+ }
} \ No newline at end of file
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java
index 2229424..95702a6 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java
@@ -10,14 +10,27 @@ import net.minecraft.text.Text;
import io.github.cottonmc.cotton.gui.GuiDescription;
import io.github.cottonmc.cotton.gui.widget.WPanel;
import io.github.cottonmc.cotton.gui.widget.WWidget;
+import org.lwjgl.opengl.GL11;
public class CottonClientScreen extends Screen implements TextHoverRendererScreen {
protected GuiDescription description;
protected int left = 0;
protected int top = 0;
- protected int containerWidth = 0;
- protected int containerHeight = 0;
-
+
+ /**
+ * The X coordinate of the screen title.
+ *
+ * @since 2.0.0
+ */
+ protected int titleX;
+
+ /**
+ * The Y coordinate of the screen title.
+ *
+ * @since 2.0.0
+ */
+ protected int titleY;
+
protected WWidget lastResponder = null;
public CottonClientScreen(GuiDescription description) {
@@ -33,7 +46,6 @@ public class CottonClientScreen extends Screen implements TextHoverRendererScree
public GuiDescription getDescription() {
return description;
}
-
@Override
public void init(MinecraftClient client, int screenWidth, int screenHeight) {
@@ -43,32 +55,53 @@ public class CottonClientScreen extends Screen implements TextHoverRendererScree
description.addPainters();
reposition(screenWidth, screenHeight);
}
-
- public void reposition(int screenWidth, int screenHeight) {
+
+ /**
+ * Repositions the root panel.
+ *
+ * @param screenWidth the width of the screen
+ * @param screenHeight the height of the screen
+ */
+ protected void reposition(int screenWidth, int screenHeight) {
if (description!=null) {
WPanel root = description.getRootPanel();
if (root!=null) {
- this.containerWidth = root.getWidth();
- this.containerHeight = root.getHeight();
-
- this.left = (screenWidth - root.getWidth()) / 2;
- this.top = (screenHeight - root.getHeight()) / 2;
+ if (!description.isFullscreen()) {
+ this.left = (screenWidth - root.getWidth()) / 2;
+ this.top = (screenHeight - root.getHeight()) / 2;
+ this.titleX = 0;
+ this.titleY = 0;
+ } else {
+ this.left = 0;
+ this.top = 0;
+
+ // Offset the title coordinates a little from the edge
+ this.titleX = 10;
+ this.titleY = 10;
+
+ root.setSize(screenWidth, screenHeight);
+ }
}
}
}
- public void paint(MatrixStack matrices, int mouseX, int mouseY) {
+ private void paint(MatrixStack matrices, int mouseX, int mouseY) {
super.renderBackground(matrices);
if (description!=null) {
WPanel root = description.getRootPanel();
if (root!=null) {
+ GL11.glEnable(GL11.GL_SCISSOR_TEST);
+ Scissors.refreshScissors();
root.paint(matrices, left, top, mouseX-left, mouseY-top);
+ GL11.glDisable(GL11.GL_SCISSOR_TEST);
+ Scissors.checkStackIsEmpty();
+ }
+
+ if (getTitle() != null && description.isTitleVisible()) {
+ int width = description.getRootPanel().getWidth();
+ ScreenDrawing.drawString(matrices, getTitle(), description.getTitleAlignment(), left + titleX, top + titleY, width, description.getTitleColor());
}
- }
-
- if (getTitle() != null) {
- textRenderer.draw(matrices, getTitle(), left, top, description.getTitleColor());
}
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java
index 10ff4f6..4b7a726 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java
@@ -13,6 +13,7 @@ import org.lwjgl.glfw.GLFW;
import io.github.cottonmc.cotton.gui.widget.WPanel;
import io.github.cottonmc.cotton.gui.widget.WWidget;
+import org.lwjgl.opengl.GL11;
/**
* A screen for a {@link SyncedGuiDescription}.
@@ -65,12 +66,26 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl
description.addPainters();
- reposition();
+ reposition(screenWidth, screenHeight);
}
-
- public void reposition() {
+
+ /**
+ * Clears the heavyweight peers of this screen's GUI description.
+ */
+ private void clearPeers() {
+ description.slots.clear();
+ }
+
+ /**
+ * Repositions the root panel.
+ *
+ * @param screenWidth the width of the screen
+ * @param screenHeight the height of the screen
+ */
+ protected void reposition(int screenWidth, int screenHeight) {
WPanel basePanel = description.getRootPanel();
if (basePanel!=null) {
+ clearPeers();
basePanel.validate(description);
backgroundWidth = basePanel.getWidth();
@@ -80,13 +95,24 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl
if (backgroundWidth<16) backgroundWidth=300;
if (backgroundHeight<16) backgroundHeight=300;
}
- x = (width / 2) - (backgroundWidth / 2);
- y = (height / 2) - (backgroundHeight / 2);
- }
-
- @Override
- public void onClose() {
- super.onClose();
+
+ if (!description.isFullscreen()) {
+ x = (width / 2) - (backgroundWidth / 2);
+ y = (height / 2) - (backgroundHeight / 2);
+ titleX = 0;
+ titleY = 0;
+ } else {
+ x = 0;
+ y = 0;
+
+ // Offset the title coordinates a little from the edge
+ titleX = 10;
+ titleY = 10;
+
+ if (basePanel != null) {
+ basePanel.setSize(screenWidth, screenHeight);
+ }
+ }
}
@Override
@@ -211,13 +237,17 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl
@Override
protected void drawBackground(MatrixStack matrices, float partialTicks, int mouseX, int mouseY) {} //This is just an AbstractContainerScreen thing; most Screens don't work this way.
- public void paint(MatrixStack matrices, int mouseX, int mouseY) {
+ private void paint(MatrixStack matrices, int mouseX, int mouseY) {
super.renderBackground(matrices);
if (description!=null) {
WPanel root = description.getRootPanel();
if (root!=null) {
+ GL11.glEnable(GL11.GL_SCISSOR_TEST);
+ Scissors.refreshScissors();
root.paint(matrices, x, y, mouseX-x, mouseY-y);
+ GL11.glDisable(GL11.GL_SCISSOR_TEST);
+ Scissors.checkStackIsEmpty();
}
}
}
@@ -243,8 +273,9 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl
@Override
protected void drawForeground(MatrixStack matrices, int mouseX, int mouseY) {
- if (description != null) {
- this.textRenderer.draw(matrices, this.title, (float) this.field_25267, (float) this.field_25268, description.getTitleColor());
+ if (description != null && description.isTitleVisible()) {
+ int width = description.getRootPanel().getWidth();
+ ScreenDrawing.drawString(matrices, getTitle(), description.getTitleAlignment(), titleX, titleY, width, description.getTitleColor());
}
// Don't draw the player inventory label as it's drawn by the widget itself
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/LightweightGuiDescription.java b/src/main/java/io/github/cottonmc/cotton/gui/client/LightweightGuiDescription.java
index 3eb6578..8a57551 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/client/LightweightGuiDescription.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/client/LightweightGuiDescription.java
@@ -1,5 +1,6 @@
package io.github.cottonmc.cotton.gui.client;
+import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
import net.minecraft.screen.PropertyDelegate;
import io.github.cottonmc.cotton.gui.GuiDescription;
@@ -16,10 +17,14 @@ import javax.annotation.Nullable;
*/
public class LightweightGuiDescription implements GuiDescription {
protected WPanel rootPanel = new WGridPanel();
- protected int titleColor = WLabel.DEFAULT_TEXT_COLOR;
- protected int darkmodeTitleColor = WLabel.DEFAULT_DARKMODE_TEXT_COLOR;
protected PropertyDelegate propertyDelegate;
protected WWidget focus;
+
+ protected int titleColor = WLabel.DEFAULT_TEXT_COLOR;
+ protected int darkmodeTitleColor = WLabel.DEFAULT_DARKMODE_TEXT_COLOR;
+ protected boolean fullscreen = false;
+ protected boolean titleVisible = true;
+ protected HorizontalAlignment titleAlignment = HorizontalAlignment.LEFT;
@Override
public WPanel getRootPanel() {
@@ -40,12 +45,20 @@ public class LightweightGuiDescription implements GuiDescription {
@Override
public GuiDescription setTitleColor(int color) {
this.titleColor = color;
+ this.darkmodeTitleColor = (color == WLabel.DEFAULT_TEXT_COLOR) ? WLabel.DEFAULT_DARKMODE_TEXT_COLOR : color;
+ return this;
+ }
+
+ @Override
+ public GuiDescription setTitleColor(int lightColor, int darkColor) {
+ this.titleColor = lightColor;
+ this.darkmodeTitleColor = darkColor;
return this;
}
@Override
public void addPainters() {
- if (this.rootPanel!=null) {
+ if (this.rootPanel!=null && !fullscreen) {
this.rootPanel.setBackgroundPainter(BackgroundPainter.VANILLA);
}
}
@@ -94,4 +107,34 @@ public class LightweightGuiDescription implements GuiDescription {
widget.onFocusLost();
}
}
+
+ @Override
+ public boolean isFullscreen() {
+ return fullscreen;
+ }
+
+ @Override
+ public void setFullscreen(boolean fullscreen) {
+ this.fullscreen = fullscreen;
+ }
+
+ @Override
+ public boolean isTitleVisible() {
+ return titleVisible;
+ }
+
+ @Override
+ public void setTitleVisible(boolean titleVisible) {
+ this.titleVisible = titleVisible;
+ }
+
+ @Override
+ public HorizontalAlignment getTitleAlignment() {
+ return titleAlignment;
+ }
+
+ @Override
+ public void setTitleAlignment(HorizontalAlignment titleAlignment) {
+ this.titleAlignment = titleAlignment;
+ }
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/Scissors.java b/src/main/java/io/github/cottonmc/cotton/gui/client/Scissors.java
new file mode 100644
index 0000000..4998a05
--- /dev/null
+++ b/src/main/java/io/github/cottonmc/cotton/gui/client/Scissors.java
@@ -0,0 +1,147 @@
+package io.github.cottonmc.cotton.gui.client;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.MinecraftClient;
+import org.lwjgl.opengl.GL11;
+
+import java.util.ArrayDeque;
+import java.util.stream.Collectors;
+
+/**
+ * Contains a stack for GL scissors for restricting the drawn area of a widget.
+ *
+ * @since 2.0.0
+ */
+@Environment(EnvType.CLIENT)
+public final class Scissors {
+ private static final ArrayDeque<Frame> STACK = new ArrayDeque<>();
+
+ private Scissors() {
+ }
+
+ /**
+ * Pushes a new scissor frame onto the stack and refreshes the scissored area.
+ *
+ * @param x the frame's X coordinate
+ * @param y the frame's Y coordinate
+ * @param width the frame's width in pixels
+ * @param height the frame's height in pixels
+ * @return the pushed frame
+ */
+ public static Frame push(int x, int y, int width, int height) {
+ Frame frame = new Frame(x, y, width, height);
+ STACK.push(frame);
+ refreshScissors();
+
+ return frame;
+ }
+
+ /**
+ * Pops the topmost scissor frame and refreshes the scissored area.
+ *
+ * @throws IllegalStateException if there are no scissor frames on the stack
+ */
+ public static void pop() {
+ if (STACK.isEmpty()) {
+ throw new IllegalStateException("No scissors on the stack!");
+ }
+
+ STACK.pop();
+ refreshScissors();
+ }
+
+ static void refreshScissors() {
+ MinecraftClient mc = MinecraftClient.getInstance();
+
+ if (STACK.isEmpty()) {
+ // Just use the full window framebuffer as a scissor
+ GL11.glScissor(0, 0, mc.getWindow().getFramebufferWidth(), mc.getWindow().getFramebufferHeight());
+ return;
+ }
+
+ int x = Integer.MIN_VALUE;
+ int y = Integer.MIN_VALUE;
+ int width = -1;
+ int height = -1;
+
+ for (Frame frame : STACK) {
+ if (x < frame.x) {
+ x = frame.x;
+ }
+ if (y < frame.y) {
+ y = frame.y;
+ }
+ if (width == -1 || x + width > frame.x + frame.width) {
+ width = frame.width - (x - frame.x);
+ }
+ if (height == -1 || y + height > frame.y + frame.height) {
+ height = frame.height - (y - frame.y);
+ }
+ }
+
+ int windowHeight = mc.getWindow().getHeight();
+ double scale = mc.getWindow().getScaleFactor();
+ int scaledWidth = (int) (width * scale);
+ int scaledHeight = (int) (height * scale);
+
+ // Expression for Y coordinate adapted from vini2003's Spinnery (code snippet released under WTFPL)
+ GL11.glScissor((int) (x * scale), (int) (windowHeight - (y * scale) - scaledHeight), scaledWidth, scaledHeight);
+ }
+
+ /**
+ * Internal method. Throws an {@link IllegalStateException} if the scissor stack is not empty.
+ */
+ static void checkStackIsEmpty() {
+ if (!STACK.isEmpty()) {
+ throw new IllegalStateException("Unpopped scissor frames: " + STACK.stream().map(Frame::toString).collect(Collectors.joining(", ")));
+ }
+ }
+
+ /**
+ * A single scissor frame in the stack.
+ */
+ public static final class Frame implements AutoCloseable {
+ private final int x;
+ private final int y;
+ private final int width;
+ private final int height;
+
+ private Frame(int x, int y, int width, int height) {
+ if (width < 0) throw new IllegalArgumentException("Negative width for a stack frame");
+ if (height < 0) throw new IllegalArgumentException("Negative height for a stack frame");
+
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+
+ /**
+ * Pops this frame from the stack.
+ *
+ * @throws IllegalStateException if: <ul>
+ * <li>this frame is not on the stack, or</li>
+ * <li>this frame is not the topmost element on the stack</li>
+ * </ul>
+ * @see Scissors#pop()
+ */
+ @Override
+ public void close() {
+ if (STACK.peekLast() != this) {
+ if (STACK.contains(this)) {
+ throw new IllegalStateException(this + " is not on top of the stack!");
+ } else {
+ throw new IllegalStateException(this + " is not on the stack!");
+ }
+ }
+
+ pop();
+ }
+
+ @Override
+ public String toString() {
+ return "Frame{ at = (" + x + ", " + y + "), size = (" + width + ", " + height + ") }";
+ }
+ }
+}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/ScreenDrawing.java b/src/main/java/io/github/cottonmc/cotton/gui/client/ScreenDrawing.java
index adfff0c..07d4417 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/client/ScreenDrawing.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/client/ScreenDrawing.java
@@ -2,16 +2,16 @@ package io.github.cottonmc.cotton.gui.client;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
-import net.minecraft.class_5348;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.StringRenderable;
import net.minecraft.util.Identifier;
import org.lwjgl.opengl.GL11;
-import io.github.cottonmc.cotton.gui.widget.data.Alignment;
+import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
/**
* {@code ScreenDrawing} contains utility methods for drawing contents on a screen.
@@ -41,12 +41,9 @@ public class ScreenDrawing {
* @param width the width of the box on-screen
* @param height the height of the box on-screen
* @param texture the Identifier for the texture
- * @param u1 the left edge of the texture
- * @param v1 the top edge of the texture
- * @param u2 the right edge of the texture
- * @param v2 the bottom edge of the texture
* @param color a color to tint the texture. This can be transparent! Use 0xFF_FFFFFF if you don't want a color tint
* @param opacity opacity of the drawn texture. (0f is fully opaque and 1f is fully visible)
+ * @since 2.0.0
*/
public static void texturedRect(int x, int y, int width, int height, Identifier texture, int color, float opacity) {
texturedRect(x, y, width, height, texture, 0, 0, 1, 1, color, opacity);
@@ -84,6 +81,7 @@ public class ScreenDrawing {
* @param v2 the bottom edge of the texture
* @param color a color to tint the texture. This can be transparent! Use 0xFF_FFFFFF if you don't want a color tint
* @param opacity opacity of the drawn texture. (0f is fully opaque and 1f is fully visible)
+ * @since 2.0.0
*/
public static void texturedRect(int x, int y, int width, int height, Identifier texture, float u1, float v1, float u2, float v2, int color, float opacity) {
MinecraftClient.getInstance().getTextureManager().bindTexture(texture);
@@ -329,7 +327,7 @@ public class ScreenDrawing {
* @param width the width of the string, used for aligning
* @param color the text color
*/
- public static void drawString(MatrixStack matrices, String s, Alignment align, int x, int y, int width, int color) {
+ public static void drawString(MatrixStack matrices, String s, HorizontalAlignment align, int x, int y, int width, int color) {
switch(align) {
case LEFT: {
MinecraftClient.getInstance().textRenderer.draw(matrices, s, x, y, color);
@@ -362,7 +360,7 @@ public class ScreenDrawing {
* @param color the text color
* @since 1.9.0
*/
- public static void drawString(MatrixStack matrices, class_5348 text, Alignment align, int x, int y, int width, int color) {
+ public static void drawString(MatrixStack matrices, StringRenderable text, HorizontalAlignment align, int x, int y, int width, int color) {
switch(align) {
case LEFT: {
MinecraftClient.getInstance().textRenderer.draw(matrices, text, x, y, color);
@@ -394,7 +392,7 @@ public class ScreenDrawing {
* @param width the width of the string, used for aligning
* @param color the text color
*/
- public static void drawStringWithShadow(MatrixStack matrices, String s, Alignment align, int x, int y, int width, int color) {
+ public static void drawStringWithShadow(MatrixStack matrices, String s, HorizontalAlignment align, int x, int y, int width, int color) {
switch(align) {
case LEFT: {
MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, s, x, y, color);
@@ -426,7 +424,7 @@ public class ScreenDrawing {
* @param width the width of the string, used for aligning
* @param color the text color
*/
- public static void drawStringWithShadow(MatrixStack matrices, class_5348 text, Alignment align, int x, int y, int width, int color) {
+ public static void drawStringWithShadow(MatrixStack matrices, StringRenderable text, HorizontalAlignment align, int x, int y, int width, int color) {
switch(align) {
case LEFT: {
MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, text, x, y, color);
@@ -469,7 +467,7 @@ public class ScreenDrawing {
* @param y the Y position
* @param color the text color
*/
- public static void drawString(MatrixStack matrices, class_5348 text, int x, int y, int color) {
+ public static void drawString(MatrixStack matrices, StringRenderable text, int x, int y, int color) {
MinecraftClient.getInstance().textRenderer.draw(matrices, text, x, y, color);
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java
index 1a440e9..a7f6027 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java
@@ -72,7 +72,7 @@ public abstract class WAbstractSlider extends WWidget {
this.max = max;
this.axis = axis;
this.value = min;
- this.direction = (axis == Axis.HORIZONTAL) ? Direction.LEFT : Direction.UP;
+ this.direction = (axis == Axis.HORIZONTAL) ? Direction.RIGHT : Direction.UP;
}
/**
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WBar.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WBar.java
index 999effc..09b87fd 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WBar.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WBar.java
@@ -5,6 +5,7 @@ import net.fabricmc.api.Environment;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.screen.PropertyDelegate;
import net.minecraft.text.LiteralText;
+import net.minecraft.text.StringRenderable;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
@@ -162,7 +163,7 @@ public class WBar extends WWidget {
}
@Override
- public void addTooltip(List<Text> information) {
+ public void addTooltip(List<StringRenderable> information) {
if (tooltipLabel!=null) {
int value = (field>=0) ? properties.get(field) : 0;
int valMax = (max>=0) ? properties.get(max) : maxValue;
@@ -184,8 +185,9 @@ public class WBar extends WWidget {
}
@Override
- public void createPeers(GuiDescription c) {
- if (properties==null) properties = c.getPropertyDelegate();
+ public void validate(GuiDescription host) {
+ super.validate(host);
+ if (properties==null) properties = host.getPropertyDelegate();
}
/**
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WBox.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WBox.java
index b7fe4c2..261e2f2 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WBox.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WBox.java
@@ -1,6 +1,8 @@
package io.github.cottonmc.cotton.gui.widget;
import io.github.cottonmc.cotton.gui.widget.data.Axis;
+import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
+import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment;
import java.util.Objects;
@@ -21,6 +23,20 @@ public class WBox extends WPanel {
protected Axis axis;
/**
+ * The horizontal alignment for this box's children.
+ *
+ * @since 2.1.0
+ */
+ protected HorizontalAlignment horizontalAlignment = HorizontalAlignment.LEFT;
+
+ /**
+ * The vertical alignment for this box's children.
+ *
+ * @since 2.1.0
+ */
+ protected VerticalAlignment verticalAlignment = VerticalAlignment.TOP;
+
+ /**
* Constructs a box.
*
* @param axis the box axis
@@ -60,12 +76,68 @@ public class WBox extends WPanel {
public void layout() {
int dimension = 0;
+ // Set position offset from alignment along the box axis
+ if (axis == Axis.HORIZONTAL && horizontalAlignment != HorizontalAlignment.LEFT) {
+ int widgetWidth = spacing * (children.size() - 1);
+ for (WWidget child : children) {
+ widgetWidth += child.getWidth();
+ }
+
+ if (horizontalAlignment == HorizontalAlignment.CENTER) {
+ dimension = (getWidth() - widgetWidth) / 2;
+ } else { // right
+ dimension = getWidth() - widgetWidth;
+ }
+ } else if (verticalAlignment != VerticalAlignment.TOP) {
+ int widgetHeight = spacing * (children.size() - 1);
+ for (WWidget child : children) {
+ widgetHeight += child.getHeight();
+ }
+
+ if (verticalAlignment == VerticalAlignment.CENTER) {
+ dimension = (getHeight() - widgetHeight) / 2;
+ } else { // bottom
+ dimension = getHeight() - widgetHeight;
+ }
+ }
+
for (int i = 0; i < children.size(); i++) {
WWidget child = children.get(i);
+
if (axis == Axis.HORIZONTAL) {
- child.setLocation(dimension, 0);
+ int y;
+
+ switch (verticalAlignment) {
+ case TOP:
+ default:
+ y = 0;
+ break;
+ case CENTER:
+ y = (getHeight() - child.getHeight()) / 2;
+ break;
+ case BOTTOM:
+ y = getHeight() - child.getHeight();
+ break;
+ }
+
+ child.setLocation(dimension, y);
} else {
- child.setLocation(0, dimension);
+ int x;
+
+ switch (horizontalAlignment) {
+ case LEFT:
+ default:
+ x = 0;
+ break;
+ case CENTER:
+ x = (getWidth() - child.getWidth()) / 2;
+ break;
+ case RIGHT:
+ x = getWidth() - child.getWidth();
+ break;
+ }
+
+ child.setLocation(x, dimension);
}
if (child instanceof WPanel) ((WPanel) child).layout();
@@ -120,4 +192,50 @@ public class WBox extends WPanel {
this.axis = Objects.requireNonNull(axis, "axis");
return this;
}
+
+ /**
+ * Gets the horizontal alignment of this box.
+ *
+ * @return the alignment
+ * @since 2.1.0
+ */
+ public HorizontalAlignment getHorizontalAlignment() {
+ return horizontalAlignment;
+ }
+
+ /**
+ * Sets the horizontal alignment of this box.
+ *
+ * @param alignment the new alignment
+ * @return this box
+ * @throws NullPointerException if the alignment is null
+ * @since 2.1.0
+ */
+ public WBox setHorizontalAlignment(HorizontalAlignment alignment) {
+ this.horizontalAlignment = Objects.requireNonNull(alignment, "alignment");
+ return this;
+ }
+
+ /**
+ * Gets the vertical alignment of this box.
+ *
+ * @return the alignment
+ * @since 2.1.0
+ */
+ public VerticalAlignment getVerticalAlignment() {
+ return verticalAlignment;
+ }
+
+ /**
+ * Sets the vertical alignment of this box.
+ *
+ * @param alignment the new alignment
+ * @return this box
+ * @throws NullPointerException if the alignment is null
+ * @since 2.1.0
+ */
+ public WBox setVerticalAlignment(VerticalAlignment alignment) {
+ this.verticalAlignment = Objects.requireNonNull(alignment, "alignment");
+ return this;
+ }
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java
index 7087e00..f65b513 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java
@@ -1,32 +1,66 @@
package io.github.cottonmc.cotton.gui.widget;
+import io.github.cottonmc.cotton.gui.widget.icon.Icon;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
-import net.minecraft.class_5348;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.StringRenderable;
import io.github.cottonmc.cotton.gui.client.ScreenDrawing;
-import io.github.cottonmc.cotton.gui.widget.data.Alignment;
+import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
+
+import javax.annotation.Nullable;
public class WButton extends WWidget {
- private class_5348 label;
+ private StringRenderable label;
protected int color = WLabel.DEFAULT_TEXT_COLOR;
protected int darkmodeColor = WLabel.DEFAULT_TEXT_COLOR;
private boolean enabled = true;
- protected Alignment alignment = Alignment.CENTER;
-
- private Runnable onClick;
+ protected HorizontalAlignment alignment = HorizontalAlignment.CENTER;
+ @Nullable private Runnable onClick;
+ @Nullable private Icon icon = null;
+
+ /**
+ * Constructs a button with no label and no icon.
+ */
public WButton() {
}
-
- public WButton(class_5348 text) {
- this.label = text;
+
+ /**
+ * Constructs a button with an icon.
+ *
+ * @param icon the icon
+ * @since 2.2.0
+ */
+ public WButton(Icon icon) {
+ this.icon = icon;
+ }
+
+ /**
+ * Constructs a button with a label.
+ *
+ * @param label the label
+ */
+ public WButton(StringRenderable label) {
+ this.label = label;
+ }
+
+ /**
+ * Constructs a button with an icon and a label.
+ *
+ * @param icon the icon
+ * @param label the label
+ * @since 2.2.0
+ */
+ public WButton(Icon icon, StringRenderable label) {
+ this.icon = icon;
+ this.label = label;
}
@Override
@@ -58,6 +92,10 @@ public class WButton extends WWidget {
ScreenDrawing.texturedRect(x, y, getWidth()/2, 20, AbstractButtonWidget.WIDGETS_LOCATION, buttonLeft, buttonTop, buttonLeft+buttonWidth, buttonTop+buttonHeight, 0xFFFFFFFF);
ScreenDrawing.texturedRect(x+(getWidth()/2), y, getWidth()/2, 20, AbstractButtonWidget.WIDGETS_LOCATION, buttonEndLeft, buttonTop, 200*px, buttonTop+buttonHeight, 0xFFFFFFFF);
+
+ if (icon != null) {
+ icon.paint(matrices, x + 2, y + 2, 16);
+ }
if (label!=null) {
int color = 0xE0E0E0;
@@ -66,8 +104,9 @@ public class WButton extends WWidget {
} /*else if (hovered) {
color = 0xFFFFA0;
}*/
-
- ScreenDrawing.drawStringWithShadow(matrices, label, alignment, x, y + ((20 - 8) / 2), width, color); //LibGuiClient.config.darkMode ? darkmodeColor : color);
+
+ int xOffset = (icon != null && alignment == HorizontalAlignment.LEFT) ? 18 : 0;
+ ScreenDrawing.drawStringWithShadow(matrices, label, alignment, x + xOffset, y + ((20 - 8) / 2), width, color); //LibGuiClient.config.darkMode ? darkmodeColor : color);
}
}
@@ -96,8 +135,25 @@ public class WButton extends WWidget {
}
}
- public WButton setOnClick(Runnable r) {
- this.onClick = r;
+ /**
+ * Gets the click handler of this button.
+ *
+ * @return the click handler
+ * @since 2.2.0
+ */
+ @Nullable
+ public Runnable getOnClick() {
+ return onClick;
+ }
+
+ /**
+ * Sets the click handler of this button.
+ *
+ * @param onClick the new click handler
+ * @return this button
+ */
+ public WButton setOnClick(@Nullable Runnable onClick) {
+ this.onClick = onClick;
return this;
}
@@ -110,21 +166,44 @@ public class WButton extends WWidget {
return this;
}
- public class_5348 getLabel() {
+ public StringRenderable getLabel() {
return label;
}
- public WButton setLabel(class_5348 label) {
+ public WButton setLabel(StringRenderable label) {
this.label = label;
return this;
}
- public Alignment getAlignment() {
+ public HorizontalAlignment getAlignment() {
return alignment;
}
- public WButton setAlignment(Alignment alignment) {
+ public WButton setAlignment(HorizontalAlignment alignment) {
this.alignment = alignment;
return this;
}
+
+ /**
+ * Gets the icon of this button.
+ *
+ * @return the icon
+ * @since 2.2.0
+ */
+ @Nullable
+ public Icon getIcon() {
+ return icon;
+ }
+
+ /**
+ * Sets the icon of this button.
+ *
+ * @param icon the new icon
+ * @return this button
+ * @since 2.2.0
+ */
+ public WButton setIcon(@Nullable Icon icon) {
+ this.icon = icon;
+ return this;
+ }
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WClippedPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WClippedPanel.java
index d4cd9f5..531ae85 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WClippedPanel.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WClippedPanel.java
@@ -1,8 +1,7 @@
package io.github.cottonmc.cotton.gui.widget;
-import net.minecraft.client.MinecraftClient;
+import io.github.cottonmc.cotton.gui.client.Scissors;
import net.minecraft.client.util.math.MatrixStack;
-import org.lwjgl.opengl.GL11;
/**
* A panel that is clipped to only render widgets inside its bounds.
@@ -12,20 +11,10 @@ public class WClippedPanel extends WPanel {
public void paint(MatrixStack matrices, int x, int y, int mouseX, int mouseY) {
if (getBackgroundPainter()!=null) getBackgroundPainter().paintBackground(x, y, this);
- GL11.glEnable(GL11.GL_SCISSOR_TEST);
- MinecraftClient mc = MinecraftClient.getInstance();
- int rawHeight = mc.getWindow().getHeight();
- double scaleFactor = mc.getWindow().getScaleFactor();
- int scaledWidth = (int) (getWidth() * scaleFactor);
- int scaledHeight = (int) (getHeight() * scaleFactor);
-
- // Expression for Y coordinate adapted from vini2003's Spinnery (code snippet released under WTFPL)
- GL11.glScissor((int) (x * scaleFactor), (int) (rawHeight - (y * scaleFactor) - scaledHeight), scaledWidth, scaledHeight);
-
+ Scissors.push(x, y, width, height);
for(WWidget child : children) {
child.paint(matrices, x + child.getX(), y + child.getY(), mouseX-child.getX(), mouseY-child.getY());
}
-
- GL11.glDisable(GL11.GL_SCISSOR_TEST);
+ Scissors.pop();
}
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WDynamicLabel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WDynamicLabel.java
index 9e87174..a3adac9 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WDynamicLabel.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WDynamicLabel.java
@@ -4,7 +4,7 @@ import net.minecraft.client.util.math.MatrixStack;
import io.github.cottonmc.cotton.gui.client.LibGuiClient;
import io.github.cottonmc.cotton.gui.client.ScreenDrawing;
-import io.github.cottonmc.cotton.gui.widget.data.Alignment;
+import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
import java.util.function.Supplier;
@@ -17,7 +17,7 @@ import java.util.function.Supplier;
*/
public class WDynamicLabel extends WWidget {
protected Supplier<String> text;
- protected Alignment alignment = Alignment.LEFT;
+ protected HorizontalAlignment alignment = HorizontalAlignment.LEFT;
protected int color;
protected int darkmodeColor;
@@ -71,7 +71,7 @@ public class WDynamicLabel extends WWidget {
return this;
}
- public WDynamicLabel setAlignment(Alignment align) {
+ public WDynamicLabel setAlignment(HorizontalAlignment align) {
this.alignment = align;
return this;
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WItem.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WItem.java
index ffba2c3..1269afe 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WItem.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WItem.java
@@ -62,7 +62,7 @@ public class WItem extends WWidget {
MinecraftClient mc = MinecraftClient.getInstance();
ItemRenderer renderer = mc.getItemRenderer();
renderer.zOffset = 100f;
- renderer.method_27951(mc.player, items.get(current), x + getWidth() / 2 - 9, y + getHeight() / 2 - 9);
+ renderer.renderInGui(items.get(current), x + getWidth() / 2 - 9, y + getHeight() / 2 - 9);
renderer.zOffset = 0f;
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java
index ec1bf9c..2aee0e7 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java
@@ -2,6 +2,7 @@ package io.github.cottonmc.cotton.gui.widget;
import java.util.ArrayList;
import java.util.List;
+import java.util.function.Predicate;
import io.github.cottonmc.cotton.gui.GuiDescription;
import io.github.cottonmc.cotton.gui.ValidatedSlot;
@@ -11,16 +12,19 @@ import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.inventory.Inventory;
+import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.slot.SlotActionType;
import javax.annotation.Nullable;
public class WItemSlot extends WWidget {
+ private static final Predicate<ItemStack> DEFAULT_FILTER = stack -> true;
private final List<ValidatedSlot> peers = new ArrayList<>();
@Nullable
@Environment(EnvType.CLIENT)
- private BackgroundPainter backgroundPainter = BackgroundPainter.SLOT;
+ // TODO: Set the background painter to SLOT in a new method that sets a widget's default painter.
+ private BackgroundPainter backgroundPainter = null;
private Inventory inventory;
private int startIndex = 0;
private int slotsWide = 1;
@@ -29,6 +33,7 @@ public class WItemSlot extends WWidget {
private boolean insertingAllowed = true;
private boolean takingAllowed = true;
private int focusedSlot = -1;
+ private Predicate<ItemStack> filter = DEFAULT_FILTER;
public WItemSlot(Inventory inventory, int startIndex, int slotsWide, int slotsHigh, boolean big) {
this.inventory = inventory;
@@ -186,8 +191,8 @@ public class WItemSlot extends WWidget {
}
@Override
- public void createPeers(GuiDescription c) {
- super.createPeers(c);
+ public void validate(GuiDescription host) {
+ super.validate(host);
peers.clear();
int index = startIndex;
@@ -197,8 +202,9 @@ public class WItemSlot extends WWidget {
ValidatedSlot slot = createSlotPeer(inventory, index, this.getAbsoluteX() + (x * 18) + 1, this.getAbsoluteY() + (y * 18) + 1);
slot.setInsertingAllowed(insertingAllowed);
slot.setTakingAllowed(takingAllowed);
+ slot.setFilter(filter);
peers.add(slot);
- c.addSlotPeer(slot);
+ host.addSlotPeer(slot);
index++;
}
}
@@ -251,13 +257,36 @@ public class WItemSlot extends WWidget {
public void setBackgroundPainter(@Nullable BackgroundPainter painter) {
this.backgroundPainter = painter;
}
-
+
+ /**
+ * Gets the item filter of this item slot.
+ *
+ * @return the item filter
+ * @since 2.0.0
+ */
+ public Predicate<ItemStack> getFilter() {
+ return filter;
+ }
+
+ /**
+ * Sets the item filter of this item slot.
+ *
+ * @param filter the new item filter
+ * @return this item slot
+ * @since 2.0.0
+ */
+ public WItemSlot setFilter(Predicate<ItemStack> filter) {
+ this.filter = filter;
+ for (ValidatedSlot peer : peers) {
+ peer.setFilter(filter);
+ }
+ return this;
+ }
+
@Environment(EnvType.CLIENT)
@Override
public void paint(MatrixStack matrices, int x, int y, int mouseX, int mouseY) {
- if (backgroundPainter!=null) {
- backgroundPainter.paintBackground(x, y, this);
- }
+ (backgroundPainter != null ? backgroundPainter : BackgroundPainter.SLOT).paintBackground(x, y, this);
}
@Nullable
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java
index 518a4a6..ffd8433 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java
@@ -1,18 +1,20 @@
package io.github.cottonmc.cotton.gui.widget;
+import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
-import net.minecraft.class_5348;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
+import net.minecraft.text.StringRenderable;
import net.minecraft.text.Style;
import io.github.cottonmc.cotton.gui.client.LibGuiClient;
import io.github.cottonmc.cotton.gui.client.ScreenDrawing;
import io.github.cottonmc.cotton.gui.client.TextHoverRendererScreen;
-import io.github.cottonmc.cotton.gui.widget.data.Alignment;
+import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
import javax.annotation.Nullable;
@@ -20,8 +22,9 @@ import javax.annotation.Nullable;
* A single-line label widget.
*/
public class WLabel extends WWidget {
- protected class_5348 text;
- protected Alignment alignment = Alignment.LEFT;
+ protected StringRenderable text;
+ protected HorizontalAlignment horizontalAlignment = HorizontalAlignment.LEFT;
+ protected VerticalAlignment verticalAlignment = VerticalAlignment.TOP;
protected int color;
protected int darkmodeColor;
@@ -51,7 +54,7 @@ public class WLabel extends WWidget {
* @param text the text of the label
* @param color the color of the label
*/
- public WLabel(class_5348 text, int color) {
+ public WLabel(StringRenderable text, int color) {
this.text = text;
this.color = color;
this.darkmodeColor = (color==DEFAULT_TEXT_COLOR) ? DEFAULT_DARKMODE_TEXT_COLOR : color;
@@ -72,13 +75,30 @@ public class WLabel extends WWidget {
* @param text the text of the label
* @since 1.8.0
*/
- public WLabel(class_5348 text) {
+ public WLabel(StringRenderable text) {
this(text, DEFAULT_TEXT_COLOR);
}
@Override
public void paint(MatrixStack matrices, int x, int y, int mouseX, int mouseY) {
- ScreenDrawing.drawString(matrices, text, alignment, x, y, this.getWidth(), LibGuiClient.config.darkMode ? darkmodeColor : color);
+ MinecraftClient mc = MinecraftClient.getInstance();
+ TextRenderer renderer = mc.textRenderer;
+ int yOffset;
+
+ switch (verticalAlignment) {
+ case CENTER:
+ yOffset = height / 2 - renderer.fontHeight / 2;
+ break;
+ case BOTTOM:
+ yOffset = height - renderer.fontHeight;
+ break;
+ case TOP:
+ default:
+ yOffset = 0;
+ break;
+ }
+
+ ScreenDrawing.drawString(matrices, text, horizontalAlignment, x, y + yOffset, this.getWidth(), LibGuiClient.config.darkMode ? darkmodeColor : color);
Style hoveredTextStyle = getTextStyleAt(mouseX, mouseY);
if (hoveredTextStyle != null) {
@@ -196,7 +216,7 @@ public class WLabel extends WWidget {
*
* @return the text
*/
- public class_5348 getText() {
+ public StringRenderable getText() {
return text;
}
@@ -206,29 +226,50 @@ public class WLabel extends WWidget {
* @param text the new text
* @return this label
*/
- public WLabel setText(class_5348 text) {
+ public WLabel setText(StringRenderable text) {
this.text = text;
return this;
}
/**
- * Gets the text alignment of this label.
+ * Gets the horizontal text alignment of this label.
+ *
+ * @return the alignment
+ * @since 2.0.0
+ */
+ public HorizontalAlignment getHorizontalAlignment() {
+ return horizontalAlignment;
+ }
+
+ /**
+ * Sets the horizontal text alignment of this label.
+ *
+ * @param align the new text alignment
+ * @return this label
+ */
+ public WLabel setHorizontalAlignment(HorizontalAlignment align) {
+ this.horizontalAlignment = align;
+ return this;
+ }
+
+ /**
+ * Gets the vertical text alignment of this label.
*
* @return the alignment
* @since 2.0.0
*/
- public Alignment getAlignment() {
- return alignment;
+ public VerticalAlignment getVerticalAlignment() {
+ return verticalAlignment;
}
/**
- * Sets the text alignment of this label.
+ * Sets the vertical text alignment of this label.
*
* @param align the new text alignment
* @return this label
*/
- public WLabel setAlignment(Alignment align) {
- this.alignment = align;
+ public WLabel setVerticalAlignment(VerticalAlignment align) {
+ this.verticalAlignment = align;
return this;
}
} \ No newline at end of file
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java
index 7f122da..200b191 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java
@@ -2,14 +2,14 @@ package io.github.cottonmc.cotton.gui.widget;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
-import net.minecraft.class_5348;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.util.math.Vector3f;
+import net.minecraft.text.StringRenderable;
import net.minecraft.util.math.Quaternion;
import io.github.cottonmc.cotton.gui.client.ScreenDrawing;
-import io.github.cottonmc.cotton.gui.widget.data.Alignment;
+import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
import io.github.cottonmc.cotton.gui.widget.data.Axis;
import javax.annotation.Nullable;
@@ -26,9 +26,9 @@ import javax.annotation.Nullable;
public class WLabeledSlider extends WAbstractSlider {
private static final Quaternion ROTATION_Z_270 = Vector3f.POSITIVE_X.getDegreesQuaternion(270);
- @Nullable private class_5348 label = null;
+ @Nullable private StringRenderable label = null;
@Nullable private LabelUpdater labelUpdater = null;
- private Alignment labelAlignment = Alignment.CENTER;
+ private HorizontalAlignment labelAlignment = HorizontalAlignment.CENTER;
/**
* Constructs a horizontal slider with no default label.
@@ -59,7 +59,7 @@ public class WLabeledSlider extends WAbstractSlider {
* @param axis the slider axis
* @param label the slider label (can be null)
*/
- public WLabeledSlider(int min, int max, Axis axis, @Nullable class_5348 label) {
+ public WLabeledSlider(int min, int max, Axis axis, @Nullable StringRenderable label) {
this(min, max, axis);
this.label = label;
}
@@ -71,7 +71,7 @@ public class WLabeledSlider extends WAbstractSlider {
* @param max the maximum value
* @param label the slider label (can be null)
*/
- public WLabeledSlider(int min, int max, @Nullable class_5348 label) {
+ public WLabeledSlider(int min, int max, @Nullable StringRenderable label) {
this(min, max);
this.label = label;
}
@@ -91,7 +91,7 @@ public class WLabeledSlider extends WAbstractSlider {
* @return the label
*/
@Nullable
- public class_5348 getLabel() {
+ public StringRenderable getLabel() {
return label;
}
@@ -100,7 +100,7 @@ public class WLabeledSlider extends WAbstractSlider {
*
* @param label the new label
*/
- public void setLabel(@Nullable class_5348 label) {
+ public void setLabel(@Nullable StringRenderable label) {
this.label = label;
}
@@ -117,7 +117,7 @@ public class WLabeledSlider extends WAbstractSlider {
*
* @return the alignment
*/
- public Alignment getLabelAlignment() {
+ public HorizontalAlignment getLabelAlignment() {
return labelAlignment;
}
@@ -126,7 +126,7 @@ public class WLabeledSlider extends WAbstractSlider {
*
* @param labelAlignment the new alignment
*/
- public void setLabelAlignment(Alignment labelAlignment) {
+ public void setLabelAlignment(HorizontalAlignment labelAlignment) {
this.labelAlignment = labelAlignment;
}
@@ -228,6 +228,6 @@ public class WLabeledSlider extends WAbstractSlider {
* @param value the slider value
* @return the label
*/
- class_5348 updateLabel(int value);
+ StringRenderable updateLabel(int value);
}
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java
index 9ba8562..bcfbf2b 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java
@@ -97,8 +97,9 @@ public class WListPanel<D, W extends WWidget> extends WClippedPanel {
child.setParent(this);
// Set up the widget's host
if (host != null) {
- child.validate(host);
- child.createPeers(host);
+ // setHost instead of validate since we cannot have independent validations
+ // TODO: System for independently validating widgets?
+ child.setHost(host);
}
return child;
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java
index d657a01..10725ee 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java
@@ -27,6 +27,7 @@ public abstract class WPanel extends WWidget {
@Environment(EnvType.CLIENT)
private BackgroundPainter backgroundPainter = null;
+ @SuppressWarnings("deprecation")
@Override
public void createPeers(GuiDescription c) {
super.createPeers(c);
@@ -174,8 +175,16 @@ public abstract class WPanel extends WWidget {
return this;
}
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Subclasses should call {@code super.validate(c)} to ensure that children are validated.
+ *
+ * @param c the host GUI description
+ */
@Override
public void validate(GuiDescription c) {
+ super.validate(c);
layout();
for (WWidget child : children) {
child.validate(c);
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPlayerInvPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPlayerInvPanel.java
index da2ac1c..3879e1f 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPlayerInvPanel.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPlayerInvPanel.java
@@ -1,5 +1,6 @@
package io.github.cottonmc.cotton.gui.widget;
+import io.github.cottonmc.cotton.gui.GuiDescription;
import io.github.cottonmc.cotton.gui.client.BackgroundPainter;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@@ -13,6 +14,8 @@ import javax.annotation.Nullable;
public class WPlayerInvPanel extends WPlainPanel {
private final WItemSlot inv;
private final WItemSlot hotbar;
+ @Nullable
+ private final WWidget label;
/**
* Constructs a player inventory panel with a label.
@@ -44,6 +47,7 @@ public class WPlayerInvPanel extends WPlainPanel {
public WPlayerInvPanel(PlayerInventory playerInventory, @Nullable WWidget label) {
int y = 0;
+ this.label = label;
if (label != null) {
this.add(label, 0, 0, label.getWidth(), label.getHeight());
y += label.getHeight();
@@ -75,5 +79,12 @@ public class WPlayerInvPanel extends WPlainPanel {
hotbar.setBackgroundPainter(painter);
return this;
}
-}
+ @Override
+ public void validate(GuiDescription c) {
+ super.validate(c);
+ if (c != null && label instanceof WLabel) {
+ ((WLabel) label).setColor(c.getTitleColor());
+ }
+ }
+}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WText.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WText.java
index 4cf268e..8fb50b8 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WText.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WText.java
@@ -1,18 +1,19 @@
package io.github.cottonmc.cotton.gui.widget;
+import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
-import net.minecraft.class_5348;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.StringRenderable;
import net.minecraft.text.Style;
import io.github.cottonmc.cotton.gui.client.LibGuiClient;
import io.github.cottonmc.cotton.gui.client.ScreenDrawing;
import io.github.cottonmc.cotton.gui.client.TextHoverRendererScreen;
-import io.github.cottonmc.cotton.gui.widget.data.Alignment;
+import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
import javax.annotation.Nullable;
import java.util.List;
@@ -24,18 +25,19 @@ import java.util.Objects;
* @since 1.8.0
*/
public class WText extends WWidget {
- protected class_5348 text;
+ protected StringRenderable text;
protected int color;
protected int darkmodeColor;
- protected Alignment alignment = Alignment.LEFT;
- private List<class_5348> wrappedLines;
+ protected HorizontalAlignment horizontalAlignment = HorizontalAlignment.LEFT;
+ protected VerticalAlignment verticalAlignment = VerticalAlignment.TOP;
+ private List<StringRenderable> wrappedLines;
private boolean wrappingScheduled = false;
- public WText(class_5348 text) {
+ public WText(StringRenderable text) {
this(text, WLabel.DEFAULT_TEXT_COLOR);
}
- public WText(class_5348 text, int color) {
+ public WText(StringRenderable text, int color) {
this.text = Objects.requireNonNull(text, "text must not be null");
this.color = color;
this.darkmodeColor = (color == WLabel.DEFAULT_TEXT_COLOR) ? WLabel.DEFAULT_DARKMODE_TEXT_COLOR : color;
@@ -72,7 +74,7 @@ public class WText extends WWidget {
int lineIndex = y / font.fontHeight;
if (lineIndex >= 0 && lineIndex < wrappedLines.size()) {
- class_5348 line = wrappedLines.get(lineIndex);
+ StringRenderable line = wrappedLines.get(lineIndex);
return font.getTextHandler().trimToWidth(line, x);
}
@@ -88,11 +90,26 @@ public class WText extends WWidget {
}
TextRenderer font = MinecraftClient.getInstance().textRenderer;
+
+ int yOffset;
+ switch (verticalAlignment) {
+ case CENTER:
+ yOffset = height / 2 - font.fontHeight * wrappedLines.size() / 2;
+ break;
+ case BOTTOM:
+ yOffset = height - font.fontHeight * wrappedLines.size();
+ break;
+ case TOP:
+ default:
+ yOffset = 0;
+ break;
+ }
+
for (int i = 0; i < wrappedLines.size(); i++) {
- class_5348 line = wrappedLines.get(i);
+ StringRenderable line = wrappedLines.get(i);
int c = LibGuiClient.config.darkMode ? darkmodeColor : color;
- ScreenDrawing.drawString(matrices, line, alignment, x, y + i * font.fontHeight, width, c);
+ ScreenDrawing.drawString(matrices, line, horizontalAlignment, x, y + yOffset + i * font.fontHeight, width, c);
}
Style hoveredTextStyle = getTextStyleAt(mouseX, mouseY);
@@ -120,7 +137,7 @@ public class WText extends WWidget {
*
* @return the text
*/
- public class_5348 getText() {
+ public StringRenderable getText() {
return text;
}
@@ -130,7 +147,7 @@ public class WText extends WWidget {
* @param text the new text
* @return this label
*/
- public WText setText(class_5348 text) {
+ public WText setText(StringRenderable text) {
Objects.requireNonNull(text, "text is null");
this.text = text;
wrappingScheduled = true;
@@ -203,24 +220,46 @@ public class WText extends WWidget {
}
/**
- * Gets the alignment of this text widget.
+ * Gets the horizontal alignment of this text widget.
*
* @return the alignment
* @since 1.9.0
*/
- public Alignment getAlignment() {
- return alignment;
+ public HorizontalAlignment getHorizontalAlignment() {
+ return horizontalAlignment;
}
/**
- * Sets the alignment of this text widget.
+ * Sets the horizontal alignment of this text widget.
*
- * @param alignment the new alignment
+ * @param horizontalAlignment the new alignment
* @return this widget
* @since 1.9.0
*/
- public WText setAlignment(Alignment alignment) {
- this.alignment = alignment;
+ public WText setHorizontalAlignment(HorizontalAlignment horizontalAlignment) {
+ this.horizontalAlignment = horizontalAlignment;
+ return this;
+ }
+
+ /**
+ * Gets the vertical alignment of this text widget.
+ *
+ * @return the alignment
+ * @since 2.0.0
+ */
+ public VerticalAlignment getVerticalAlignment() {
+ return verticalAlignment;
+ }
+
+ /**
+ * Sets the vertical alignment of this text widget.
+ *
+ * @param verticalAlignment the new alignment
+ * @return this widget
+ * @since 2.0.0
+ */
+ public WText setVerticalAlignment(VerticalAlignment verticalAlignment) {
+ this.verticalAlignment = verticalAlignment;
return this;
}
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WTiledSprite.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WTiledSprite.java
index d49074f..516c876 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WTiledSprite.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WTiledSprite.java
@@ -52,6 +52,50 @@ public class WTiledSprite extends WSprite {
tileHeight = height;
}
+ /**
+ * Gets the tile width of this sprite.
+ *
+ * @return the tile width
+ * @since 2.2.0
+ */
+ public int getTileWidth() {
+ return tileWidth;
+ }
+
+ /**
+ * Gets the tile height of this sprite.
+ *
+ * @return the tile height
+ * @since 2.2.0
+ */
+ public int getTileHeight() {
+ return tileHeight;
+ }
+
+ /**
+ * Sets the tile width of this sprite.
+ *
+ * @param tileWidth the new tile width
+ * @return this sprite
+ * @since 2.2.0
+ */
+ public WTiledSprite setTileWidth(int tileWidth) {
+ this.tileWidth = tileWidth;
+ return this;
+ }
+
+ /**
+ * Sets the tile height of this sprite.
+ *
+ * @param tileHeight the new tile height
+ * @return this sprite
+ * @since 2.2.0
+ */
+ public WTiledSprite setTileHeight(int tileHeight) {
+ this.tileHeight = tileHeight;
+ return this;
+ }
+
@Environment(EnvType.CLIENT)
@Override
public void paintFrame(int x, int y, Identifier texture) {
@@ -65,7 +109,7 @@ public class WTiledSprite extends WSprite {
x + tileXOffset, y + tileYOffset,
// but using the set tileWidth and tileHeight instead of the full height and
// width
- tileWidth, tileHeight,
+ getTileWidth(), getTileHeight(),
// render the current texture
texture,
// clips the texture if wanted
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java
index 9d1306f..b917d97 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java
@@ -2,11 +2,11 @@ package io.github.cottonmc.cotton.gui.widget;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
-import net.minecraft.class_5348;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.StringRenderable;
import net.minecraft.util.Identifier;
import io.github.cottonmc.cotton.gui.client.LibGuiClient;
@@ -25,7 +25,7 @@ public class WToggleButton extends WWidget {
protected Identifier offImage;
protected Identifier focusImage = DEFAULT_FOCUS_IMAGE;
- @Nullable protected class_5348 label = null;
+ @Nullable protected StringRenderable label = null;
protected boolean isOn = false;
@Nullable protected Consumer<Boolean> onToggle = null;
@@ -39,7 +39,7 @@ public class WToggleButton extends WWidget {
}
/** Defaults with text */
- public WToggleButton(class_5348 text) {
+ public WToggleButton(StringRenderable text) {
this(DEFAULT_ON_IMAGE, DEFAULT_OFF_IMAGE);
this.label = text;
}
@@ -51,7 +51,7 @@ public class WToggleButton extends WWidget {
}
/** Custom images, with default sizes and a label */
- public WToggleButton(Identifier onImage, Identifier offImage, class_5348 label) {
+ public WToggleButton(Identifier onImage, Identifier offImage, StringRenderable label) {
this.onImage = onImage;
this.offImage = offImage;
this.label = label;
@@ -118,11 +118,11 @@ public class WToggleButton extends WWidget {
}
@Nullable
- public class_5348 getLabel() {
+ public StringRenderable getLabel() {
return label;
}
- public WToggleButton setLabel(@Nullable class_5348 label) {
+ public WToggleButton setLabel(@Nullable StringRenderable label) {
this.label = label;
return this;
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java
index 7476c71..e615c53 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java
@@ -9,7 +9,7 @@ import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
-import net.minecraft.text.Text;
+import net.minecraft.text.StringRenderable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.glfw.GLFW;
@@ -310,9 +310,10 @@ public class WWidget {
/**
* Creates "heavyweight" component peers
* @param c the top-level Container that will hold the peers
+ * @deprecated All widget peers should be added in {@link #validate(GuiDescription)}.
*/
+ @Deprecated
public void createPeers(GuiDescription c) {
- host=c;
}
/**
@@ -348,7 +349,7 @@ public class WWidget {
*/
@Environment(EnvType.CLIENT)
public void renderTooltip(MatrixStack matrices, int x, int y, int tX, int tY) {
- List<Text> info = new ArrayList<>();
+ List<StringRenderable> info = new ArrayList<>();
addTooltip(info);
if (info.size() == 0)
@@ -361,16 +362,41 @@ public class WWidget {
/**
* Creates component peers, lays out children, and initializes animation data for this Widget and all its children.
* The host container must clear any heavyweight peers from its records before this method is called.
+ *
+ * @param host the host GUI description
*/
public void validate(GuiDescription host) {
- //valid = true;
+ this.host = host;
+ }
+
+ /**
+ * Gets the host of this widget.
+ *
+ * @return the host
+ * @see #host
+ * @since 2.1.0
+ */
+ @Nullable
+ public final GuiDescription getHost() {
+ return host;
+ }
+
+ /**
+ * Sets the host of this widget without creating peers.
+ *
+ * @param host the new host
+ * @see #host
+ * @since 2.1.0
+ */
+ public void setHost(@Nullable GuiDescription host) {
+ this.host = host;
}
/**
* Adds lines to this widget's tooltip. If the lines remain empty after this call, no tooltip will be drawn.
* @param tooltip List containing all previous tooltip data.
*/
- public void addTooltip(List<Text> tooltip) {
+ public void addTooltip(List<StringRenderable> tooltip) {
}
/**
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/data/Color.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/data/Color.java
index 9ed9d38..9b78ae9 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/data/Color.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/data/Color.java
@@ -176,6 +176,23 @@ public interface Color {
float c = getChroma()/255f;
return c / (1 - Math.abs(2*l - 1));
}
+
+ /**
+ * Calculates an interpolated value along the fraction t between 0.0 and 1.0. When t = 1.0, endVal is returned.
+ * Eg.: If this color is black, your endColor is white and t = 0.5 you get gray.
+ *
+ * @param endColor a Color to interpolate with
+ * @param t fraction between 0.0 and 1.0
+ *
+ * @since 2.0.0
+ */
+ public RGB interpolate(RGB endColor, double t){
+ double a = (endColor.getA() - this.getA()) * t + this.getA();
+ double r = (endColor.getR() - this.getR()) * t + this.getR();
+ double g = (endColor.getG() - this.getG()) * t + this.getG();
+ double b = (endColor.getB() - this.getB()) * t + this.getB();
+ return new RGB((int)a, (int)r, (int)g, (int)b);
+ }
}
public static class HSL implements Color {
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/data/Alignment.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/data/HorizontalAlignment.java
index 3e3420a..61c914d 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/data/Alignment.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/data/HorizontalAlignment.java
@@ -1,6 +1,6 @@
package io.github.cottonmc.cotton.gui.widget.data;
-public enum Alignment {
+public enum HorizontalAlignment {
LEFT,
CENTER,
RIGHT;
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/data/VerticalAlignment.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/data/VerticalAlignment.java
new file mode 100644
index 0000000..8123ad3
--- /dev/null
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/data/VerticalAlignment.java
@@ -0,0 +1,7 @@
+package io.github.cottonmc.cotton.gui.widget.data;
+
+public enum VerticalAlignment {
+ TOP,
+ CENTER,
+ BOTTOM;
+}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/Icon.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/Icon.java
new file mode 100644
index 0000000..ccf1bcc
--- /dev/null
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/Icon.java
@@ -0,0 +1,25 @@
+package io.github.cottonmc.cotton.gui.widget.icon;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.util.math.MatrixStack;
+
+/**
+ * A square icon for a widget such as a button.
+ *
+ * @see ItemIcon
+ * @see TextureIcon
+ * @since 2.2.0
+ */
+public interface Icon {
+ /**
+ * Paints this icon.
+ *
+ * @param matrices the GUI matrix stack
+ * @param x the X coordinate
+ * @param y the Y coordinate
+ * @param size the size of this icon in pixels (size N means a N*N square)
+ */
+ @Environment(EnvType.CLIENT)
+ void paint(MatrixStack matrices, int x, int y, int size);
+}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/ItemIcon.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/ItemIcon.java
new file mode 100644
index 0000000..3ce8eaa
--- /dev/null
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/ItemIcon.java
@@ -0,0 +1,42 @@
+package io.github.cottonmc.cotton.gui.widget.icon;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.item.ItemStack;
+
+/**
+ * An icon that draws an item stack.
+ *
+ * @since 2.2.0
+ */
+public class ItemIcon implements Icon {
+ private final ItemStack stack;
+
+ /**
+ * Constructs an item icon.
+ *
+ * @param stack the drawn item stack
+ */
+ public ItemIcon(ItemStack stack) {
+ this.stack = stack;
+ }
+
+ @Environment(EnvType.CLIENT)
+ @Override
+ public void paint(MatrixStack matrices, int x, int y, int size) {
+ MinecraftClient client = MinecraftClient.getInstance();
+ ItemRenderer renderer = client.getItemRenderer();
+
+ float scale = size != 16 ? ((float) size / 16f) : 1f;
+
+ RenderSystem.pushMatrix();
+ RenderSystem.translatef(x, y, 0);
+ RenderSystem.scalef(scale, scale, 1);
+ renderer.renderInGui(stack, 0, 0);
+ RenderSystem.popMatrix();
+ }
+}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/TextureIcon.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/TextureIcon.java
new file mode 100644
index 0000000..0876cb5
--- /dev/null
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/TextureIcon.java
@@ -0,0 +1,73 @@
+package io.github.cottonmc.cotton.gui.widget.icon;
+
+import io.github.cottonmc.cotton.gui.client.ScreenDrawing;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.util.Identifier;
+
+/**
+ * An icon that draws a texture.
+ *
+ * @since 2.2.0
+ */
+public class TextureIcon implements Icon {
+ private final Identifier texture;
+ private float opacity = 1f;
+ private int color = 0xFF_FFFFFF;
+
+ /**
+ * Constructs a new texture icon.
+ *
+ * @param texture the identifier of the icon texture
+ */
+ public TextureIcon(Identifier texture) {
+ this.texture = texture;
+ }
+
+ /**
+ * Gets the opacity of the texture.
+ *
+ * @return the opacity
+ */
+ public float getOpacity() {
+ return opacity;
+ }
+
+ /**
+ * Sets the opacity of the texture.
+ *
+ * @param opacity the new opacity between 0 (fully transparent) and 1 (fully opaque)
+ * @return this icon
+ */
+ public TextureIcon setOpacity(float opacity) {
+ this.opacity = opacity;
+ return this;
+ }
+
+ /**
+ * Gets the color tint of the texture.
+ *
+ * @return the color tint
+ */
+ public int getColor() {
+ return color;
+ }
+
+ /**
+ * Sets the color tint of the texture.
+ *
+ * @param color the new color tint
+ * @return this icon
+ */
+ public TextureIcon setColor(int color) {
+ this.color = color;
+ return this;
+ }
+
+ @Environment(EnvType.CLIENT)
+ @Override
+ public void paint(MatrixStack matrices, int x, int y, int size) {
+ ScreenDrawing.texturedRect(x, y, size, size, texture, color, opacity);
+ }
+}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/package-info.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/package-info.java
new file mode 100644
index 0000000..54bbc92
--- /dev/null
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/icon/package-info.java
@@ -0,0 +1,14 @@
+/**
+ * The icon API for displaying various icons on widgets.
+ *
+ * <p>For example, you can attach an icon to a button:
+ * <pre>
+ * {@code
+ * // This is a button with an apple item as the icon:
+ * WButton button = new WButton(new ItemIcon(new ItemStack(Items.APPLE)), new LiteralText("Apple button"));
+ * }
+ * </pre>
+ *
+ * @since 2.2.0
+ */
+package io.github.cottonmc.cotton.gui.widget.icon;