diff --git a/build.gradle b/build.gradle index 52a1b05b..324c29a2 100644 --- a/build.gradle +++ b/build.gradle @@ -83,8 +83,8 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' - compileOnly(fg.deobf("mezz.jei:jei-${config.mc_version}-common-api:${config.jei_version}")) - compileOnly(fg.deobf("mezz.jei:jei-${config.mc_version}-forge-api:${config.jei_version}")) + compileOnly(fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}")) + compileOnly(fg.deobf("mezz.jei:jei-${mc_version}-forge-api:${jei_version}")) } test { diff --git a/gradle.properties b/gradle.properties index 37d4aca9..6f3ff3aa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,3 +3,4 @@ org.gradle.daemon=false mc_version=1.20.1 forge_version=47.1.65 mod_version=4.4.0 +jei_version=15.2.0.27 diff --git a/src/main/java/codechicken/lib/colour/Colour.java b/src/main/java/codechicken/lib/colour/Colour.java index 00edece3..fa94af40 100644 --- a/src/main/java/codechicken/lib/colour/Colour.java +++ b/src/main/java/codechicken/lib/colour/Colour.java @@ -134,6 +134,78 @@ public Colour set(float[] floats) { return set(floats[0], floats[1], floats[2], floats[3]); } + public Colour r(float r) { + this.r = (byte) (255F * r); + return this; + } + + public Colour g(float g) { + this.g = (byte) (255F * g); + return this; + } + + public Colour b(float b) { + this.b = (byte) (255F * b); + return this; + } + + public Colour a(float a) { + this.a = (byte) (255F * a); + return this; + } + + public Colour r(int r) { + this.r = (byte) r; + return this; + } + + public Colour g(int g) { + this.g = (byte) g; + return this; + } + + public Colour b(int b) { + this.b = (byte) b; + return this; + } + + public Colour a(int a) { + this.a = (byte) a; + return this; + } + + public float r() { + return r / 255F; + } + + public float g() { + return g / 255F; + } + + public float b() { + return b / 255F; + } + + public float a() { + return a / 255F; + } + + public float rI() { + return r & 0xFF; + } + + public float gI() { + return g & 0xFF; + } + + public float bI() { + return b & 0xFF; + } + + public float aI() { + return a & 0xFF; + } + /** * Flips a color between ABGR and RGBA. * diff --git a/src/main/java/codechicken/lib/gui/modular/ModularGui.java b/src/main/java/codechicken/lib/gui/modular/ModularGui.java index 5b531a17..6fcb4e6f 100644 --- a/src/main/java/codechicken/lib/gui/modular/ModularGui.java +++ b/src/main/java/codechicken/lib/gui/modular/ModularGui.java @@ -6,6 +6,7 @@ import codechicken.lib.gui.modular.lib.geometry.Constraint; import codechicken.lib.gui.modular.lib.geometry.GeoParam; import codechicken.lib.gui.modular.lib.geometry.GuiParent; +import net.covers1624.quack.collection.FastStream; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.screens.Screen; @@ -55,7 +56,6 @@ public class ModularGui implements GuiParent { private Screen parentScreen; private Component guiTitle = Component.empty(); - private GuiElement focused; private ResourceLocation newCursor = null; private final Map> slotHandlers = new HashMap<>(); @@ -492,17 +492,6 @@ public double ySize() { //=== Other ===// -// @Override -// public void setFocused(@Nullable GuiElement element) { -// focused = element; -// } -// -// @Nullable -// @Override -// public GuiElement getFocused() { -// return focused; -// } - public double computeMouseX() { return mc.mouseHandler.xpos() * (double) mc.getWindow().getGuiScaledWidth() / (double) mc.getWindow().getScreenWidth(); } @@ -552,8 +541,8 @@ public void removeJEIExclude(GuiElement element) { jeiExclusions.remove(element); } - public Stream> getJeiExclusions() { - return jeiExclusions.stream().filter(GuiElement::isEnabled); + public FastStream> getJeiExclusions() { + return FastStream.of(jeiExclusions).filter(GuiElement::isEnabled); } /** diff --git a/src/main/java/codechicken/lib/gui/modular/ModularGuiContainer.java b/src/main/java/codechicken/lib/gui/modular/ModularGuiContainer.java index a2168912..a770f997 100644 --- a/src/main/java/codechicken/lib/gui/modular/ModularGuiContainer.java +++ b/src/main/java/codechicken/lib/gui/modular/ModularGuiContainer.java @@ -71,7 +71,6 @@ public void render(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float imageWidth = (int) root.getValue(GeoParam.WIDTH); imageHeight = (int) root.getValue(GeoParam.HEIGHT); - modularGui.setVanillaSlotRendering(false); if (modularGui.renderBackground()) { renderBackground(graphics); } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiButton.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiButton.java index 8b2cb051..b8df4d2b 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiButton.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiButton.java @@ -47,6 +47,106 @@ public GuiButton(@NotNull GuiParent parent) { super(parent); } + /** + * Creates a new gui button that looks and acts exactly like a standard vanilla button. + */ + public static GuiButton vanilla(@NotNull GuiParent parent, @Nullable Component label, Runnable onClick) { + return vanilla(parent, label).onClick(onClick); + } + + /** + * Creates a new gui button that looks and acts exactly like a standard vanilla button. + */ + public static GuiButton vanilla(@NotNull GuiParent parent, @Nullable Component label) { + GuiButton button = new GuiButton(parent); + GuiTexture texture = new GuiTexture(button, CCGuiTextures.getter(() -> button.toggleState() ? "dynamic/button_highlight" : "dynamic/button_vanilla")); + texture.dynamicTexture(); + GuiRectangle highlight = new GuiRectangle(button).border(() -> button.hoverTime() > 0 ? 0xFFFFFFFF : 0); + + Constraints.bind(texture, button); + Constraints.bind(highlight, button); + + if (label != null) { + button.setLabel(new GuiText(button, label)); + Constraints.bind(button.getLabel(), button, 0, 2, 0, 2); + } + + return button; + } + + /** + * Creates a vanilla button with a "press" animation. + */ + public static GuiButton vanillaAnimated(@NotNull GuiParent parent, Component label, Runnable onPress) { + return vanillaAnimated(parent, label == null ? null : () -> label, onPress); + } + + /** + * Creates a vanilla button with a "press" animation. + */ + public static GuiButton vanillaAnimated(@NotNull GuiParent parent, @Nullable Supplier label, Runnable onPress) { + return vanillaAnimated(parent, label).onPress(onPress); + } + + //TODO Could use a quad-sliced texture for this. + + /** + * Creates a vanilla button with a "press" animation. + */ + public static GuiButton vanillaAnimated(@NotNull GuiParent parent, Component label) { + return vanillaAnimated(parent, label == null ? null : () -> label); + } + + /** + * Creates a vanilla button with a "press" animation. + */ + public static GuiButton vanillaAnimated(@NotNull GuiParent parent, @Nullable Supplier label) { + GuiButton button = new GuiButton(parent); + GuiTexture texture = new GuiTexture(button, CCGuiTextures.getter(() -> button.toggleState() || button.isPressed() ? "dynamic/button_pressed" : "dynamic/button_vanilla")); + texture.dynamicTexture(); + GuiRectangle highlight = new GuiRectangle(button).border(() -> button.isMouseOver() ? 0xFFFFFFFF : 0); + + Constraints.bind(texture, button); + Constraints.bind(highlight, button); + + if (label != null) { + button.setLabel(new GuiText(button, label) + .constrain(TOP, Constraint.relative(button.get(TOP), () -> button.isPressed() ? -0.5D : 0.5D).precise()) + .constrain(LEFT, Constraint.relative(button.get(LEFT), () -> button.isPressed() ? 1.5D : 2.5D).precise()) + .constrain(WIDTH, Constraint.relative(button.get(WIDTH), -4)) + .constrain(HEIGHT, Constraint.match(button.get(HEIGHT))) + ); + } + + return button; + } + + /** + * Super simple button that is just a coloured rectangle with a label. + */ + public static GuiButton flatColourButton(@NotNull GuiParent parent, @Nullable Supplier label, Function buttonColour) { + return flatColourButton(parent, label, buttonColour, null); + } + + /** + * Super simple button that is just a coloured rectangle with a label. + */ + public static GuiButton flatColourButton(@NotNull GuiParent parent, @Nullable Supplier label, Function buttonColour, @Nullable Function borderColour) { + GuiButton button = new GuiButton(parent); + GuiRectangle background = new GuiRectangle(button) + .fill(() -> buttonColour.apply(button.isMouseOver() || button.toggleState() || button.isPressed())) + .border(borderColour == null ? null : () -> borderColour.apply(button.isMouseOver() || button.toggleState() || button.isPressed())); + Constraints.bind(background, button); + + if (label != null) { + GuiText text = new GuiText(button, label); + button.setLabel(text); + Constraints.bind(text, button, 0, 2, 0, 2); + } + + return button; + } + /** * When creating buttons with labels, use this method to store a reference to the label in the button fore easy retrival later. * @@ -232,104 +332,4 @@ public boolean mouseReleased(double mouseX, double mouseY, int button, boolean c pressed = false; return consumed; } - - /** - * Creates a new gui button that looks and acts exactly like a standard vanilla button. - */ - public static GuiButton vanilla(@NotNull GuiParent parent, @Nullable Component label, Runnable onClick) { - return vanilla(parent, label).onClick(onClick); - } - - /** - * Creates a new gui button that looks and acts exactly like a standard vanilla button. - */ - public static GuiButton vanilla(@NotNull GuiParent parent, @Nullable Component label) { - GuiButton button = new GuiButton(parent); - GuiTexture texture = new GuiTexture(button, CCGuiTextures.getter(() -> button.toggleState() ? "dynamic/button_highlight" : "dynamic/button_vanilla")); - texture.dynamicTexture(); - GuiRectangle highlight = new GuiRectangle(button).border(() -> button.hoverTime() > 0 ? 0xFFFFFFFF : 0); - - Constraints.bind(texture, button); - Constraints.bind(highlight, button); - - if (label != null) { - button.setLabel(new GuiText(button, label)); - Constraints.bind(button.getLabel(), button, 0, 2, 0, 2); - } - - return button; - } - - /** - * Creates a vanilla button with a "press" animation. - */ - public static GuiButton vanillaAnimated(@NotNull GuiParent parent, Component label, Runnable onPress) { - return vanillaAnimated(parent, label == null ? null : () -> label, onPress); - } - - /** - * Creates a vanilla button with a "press" animation. - */ - public static GuiButton vanillaAnimated(@NotNull GuiParent parent, @Nullable Supplier label, Runnable onPress) { - return vanillaAnimated(parent, label).onPress(onPress); - } - - //TODO Could use a quad-sliced texture for this. - - /** - * Creates a vanilla button with a "press" animation. - */ - public static GuiButton vanillaAnimated(@NotNull GuiParent parent, Component label) { - return vanillaAnimated(parent, label == null ? null : () -> label); - } - - /** - * Creates a vanilla button with a "press" animation. - */ - public static GuiButton vanillaAnimated(@NotNull GuiParent parent, @Nullable Supplier label) { - GuiButton button = new GuiButton(parent); - GuiTexture texture = new GuiTexture(button, CCGuiTextures.getter(() -> button.toggleState() || button.isPressed() ? "dynamic/button_pressed" : "dynamic/button_vanilla")); - texture.dynamicTexture(); - GuiRectangle highlight = new GuiRectangle(button).border(() -> button.isMouseOver() ? 0xFFFFFFFF : 0); - - Constraints.bind(texture, button); - Constraints.bind(highlight, button); - - if (label != null) { - button.setLabel(new GuiText(button, label) - .constrain(TOP, Constraint.relative(button.get(TOP), () -> button.isPressed() ? -0.5D : 0.5D).precise()) - .constrain(LEFT, Constraint.relative(button.get(LEFT), () -> button.isPressed() ? 1.5D : 2.5D).precise()) - .constrain(WIDTH, Constraint.relative(button.get(WIDTH), -4)) - .constrain(HEIGHT, Constraint.match(button.get(HEIGHT))) - ); - } - - return button; - } - - /** - * Super simple button that is just a coloured rectangle with a label. - */ - public static GuiButton flatColourButton(@NotNull GuiParent parent, @Nullable Supplier label, Function buttonColour) { - return flatColourButton(parent, label, buttonColour, null); - } - - /** - * Super simple button that is just a coloured rectangle with a label. - */ - public static GuiButton flatColourButton(@NotNull GuiParent parent, @Nullable Supplier label, Function buttonColour, @Nullable Function borderColour) { - GuiButton button = new GuiButton(parent); - GuiRectangle background = new GuiRectangle(button) - .fill(() -> buttonColour.apply(button.isMouseOver() || button.toggleState() || button.isPressed())) - .border(borderColour == null ? null : () -> borderColour.apply(button.isMouseOver() || button.toggleState() || button.isPressed())); - Constraints.bind(background, button); - - if (label != null) { - GuiText text = new GuiText(button, label); - button.setLabel(text); - Constraints.bind(text, button, 0, 2, 0, 2); - } - - return button; - } } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiColourPicker.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiColourPicker.java index bcc7c4d8..96f1a117 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiColourPicker.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiColourPicker.java @@ -1,5 +1,6 @@ package codechicken.lib.gui.modular.elements; +import codechicken.lib.colour.Colour; import codechicken.lib.gui.modular.lib.*; import codechicken.lib.gui.modular.lib.geometry.Axis; import codechicken.lib.gui.modular.lib.geometry.GuiParent; @@ -25,52 +26,12 @@ public GuiColourPicker(@NotNull GuiParent parent) { super(parent); } - public GuiColourPicker setColourState(ColourState colourState) { - this.colourState = colourState; - return this; - } - - public ColourState getState() { - return colourState; - } - - public SliderState sliderStateAlpha() { - return SliderState.forSlider(() -> (double) colourState.alpha(), e -> colourState.setAlpha(e.floatValue()), () -> -1D / (Screen.hasShiftDown() ? 16 : 64)); - } - - public SliderState sliderStateRed() { - return SliderState.forSlider(() -> (double) colourState.red(), e -> colourState.setRed(e.floatValue()), () -> -1D / (Screen.hasShiftDown() ? 16 : 64)); - } - - public SliderState sliderStateGreen() { - return SliderState.forSlider(() -> (double) colourState.green(), e -> colourState.setGreen(e.floatValue()), () -> -1D / (Screen.hasShiftDown() ? 16 : 64)); - } - - public SliderState sliderStateBlue() { - return SliderState.forSlider(() -> (double) colourState.blue(), e -> colourState.setBlue(e.floatValue()), () -> -1D / (Screen.hasShiftDown() ? 16 : 64)); - } - - public TextState getTextState() { - return TextState.create(colourState::getHexColour, colourState::setHexColour); - } - - public GuiButton getOkButton() { - return okButton; - } - - /** - * If cancel button is disabled, ok button will automatically resize. - * */ - public GuiButton getCancelButton() { - return cancelButton; - } - public static GuiColourPicker create(GuiParent guiParent, ColourState colourState) { return create(guiParent, colourState, true); } public static GuiColourPicker create(GuiParent guiParent, ColourState colourState, boolean hasAlpha) { - int initialColour = colourState.get(); + Colour initialColour = colourState.getColour(); GuiColourPicker picker = new GuiColourPicker(guiParent.getModularGui().getRoot()); picker.setOpaque(true); picker.setColourState(colourState); @@ -80,11 +41,11 @@ public static GuiColourPicker create(GuiParent guiParent, ColourState colourS Constraints.bind(background, picker.getContentElement()); var hexField = GuiTextField.create(background, 0xFF000000, 0xFF505050, 0xe0e0e0); - hexField.primary + hexField.field() .setTextState(picker.getTextState()) .setMaxLength(hasAlpha ? 8 : 6) .setFilter(s -> s.isEmpty() || validHex(s)); - hexField.container + hexField.container() .setOpaque(true) .constrain(HEIGHT, literal(12)) .constrain(TOP, relative(background.get(TOP), 4)) @@ -92,7 +53,7 @@ public static GuiColourPicker create(GuiParent guiParent, ColourState colourS .constrain(RIGHT, relative(background.get(RIGHT), -4)); SliderBG slider = makeSlider(background, 0xFFFF0000, picker.sliderStateRed()) - .constrain(TOP, relative(hexField.container.get(BOTTOM), 2)); + .constrain(TOP, relative(hexField.container().get(BOTTOM), 2)); slider = makeSlider(background, 0xFF00FF00, picker.sliderStateGreen()) .constrain(TOP, relative(slider.get(BOTTOM), 1)); @@ -104,7 +65,7 @@ public static GuiColourPicker create(GuiParent guiParent, ColourState colourS slider = makeSlider(background, 0xFFFFFFFF, picker.sliderStateAlpha()) .constrain(TOP, relative(slider.get(BOTTOM), 1)); } else { - colourState.setAlpha(0); + colourState.set(colourState.getColour().a(0)); } ColourPreview preview = new ColourPreview(background, () -> hasAlpha ? colourState.get() : (colourState.get() | 0xFF000000)) @@ -194,7 +155,7 @@ public boolean mouseReleased(double mouseX, double mouseY, int button, boolean c } @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { render.fill(xMin(), yMin(), xMin() + 1, yMax(), colour); render.fill(xMax() - 1, yMin(), xMax(), yMax(), colour); render.fill(xMin() + 1, yCenter() - 0.5, xMax() - 1, yCenter() + 0.5, colour); @@ -216,7 +177,7 @@ public ColourPreview(@NotNull GuiParent parent, Supplier colour) { } @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { render.pushScissorRect(xMin(), yMin(), xSize(), ySize()); for (int x = 0; xMin() + (x * 2) < xMax(); x++) { for (int y = 0; yMin() + (y * 2) < yMax(); y++) { @@ -228,6 +189,46 @@ public void renderBehind(GuiRender render, double mouseX, double mouseY, float p render.rect(getRectangle(), colour.get()); } } + + public GuiColourPicker setColourState(ColourState colourState) { + this.colourState = colourState; + return this; + } + + public ColourState getState() { + return colourState; + } + + public SliderState sliderStateAlpha() { + return SliderState.forSlider(() -> (double) colourState.getColour().a(), e -> colourState.set(colourState.getColour().a(e.floatValue())), () -> -1D / (Screen.hasShiftDown() ? 16 : 64)); + } + + public SliderState sliderStateRed() { + return SliderState.forSlider(() -> (double) colourState.getColour().r(), e -> colourState.set(colourState.getColour().r(e.floatValue())), () -> -1D / (Screen.hasShiftDown() ? 16 : 64)); + } + + public SliderState sliderStateGreen() { + return SliderState.forSlider(() -> (double) colourState.getColour().g(), e -> colourState.set(colourState.getColour().g(e.floatValue())), () -> -1D / (Screen.hasShiftDown() ? 16 : 64)); + } + + public SliderState sliderStateBlue() { + return SliderState.forSlider(() -> (double) colourState.getColour().b(), e -> colourState.set(colourState.getColour().b(e.floatValue())), () -> -1D / (Screen.hasShiftDown() ? 16 : 64)); + } + + public TextState getTextState() { + return TextState.create(colourState::getHexColour, colourState::setHexColour); + } + + public GuiButton getOkButton() { + return okButton; + } + + /** + * If cancel button is disabled, ok button will automatically resize. + * */ + public GuiButton getCancelButton() { + return cancelButton; + } } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiContextMenu.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiContextMenu.java index 122385c1..77c2b343 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiContextMenu.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiContextMenu.java @@ -36,6 +36,12 @@ public GuiContextMenu(ModularGui gui) { super(gui.getRoot()); } + public static GuiContextMenu tooltipStyleMenu(GuiParent parent) { + GuiContextMenu menu = new GuiContextMenu(parent.getModularGui()); + Constraints.bind(GuiRectangle.toolTipBackground(menu), menu); + return menu; + } + public GuiContextMenu setCloseOnItemClicked(boolean closeOnItemClicked) { this.closeOnItemClicked = closeOnItemClicked; return this; @@ -126,10 +132,4 @@ public GuiContextMenu setNormalizedPos(double x, double y) { constrain(TOP, dynamic(() -> Math.min(Math.max(y, 0), scaledScreenHeight() - ySize()))); return this; } - - public static GuiContextMenu tooltipStyleMenu(GuiParent parent) { - GuiContextMenu menu = new GuiContextMenu(parent.getModularGui()); - Constraints.bind(GuiRectangle.toolTipBackground(menu), menu); - return menu; - } } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiDialog.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiDialog.java index 7f39f9b4..064e1f9f 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiDialog.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiDialog.java @@ -31,6 +31,90 @@ protected GuiDialog(@NotNull GuiParent parent) { super(parent); } + /** + * Option dialog builder with pre-configured background and button builders. + * + * @param parent Can be any gui element (Will just be used to get the root element) + * @param title Sets a separate title that will be displayed above the main dialog text. (Optional) + * @param dialogText The main dialog text. + * @param width The dialog width, (Height will automatically adjust based on content.) + * @param options The list of options for this dialog. + */ + public static GuiDialog optionsDialog(@NotNull GuiParent parent, @Nullable Component title, Component dialogText, int width, Option... options) { + return optionsDialog(parent, title, dialogText, GuiRectangle::toolTipBackground, GuiDialog::defaultButton, width, options); + } + + /** + * Option dialog builder with pre-configured background and button builders. + * + * @param parent Can be any gui element (Will just be used to get the root element) + * @param dialogText The main dialog text. + * @param width The dialog width, (Height will automatically adjust based on content.) + * @param options The list of options for this dialog. + */ + public static GuiDialog optionsDialog(@NotNull GuiParent parent, Component dialogText, int width, Option... options) { + return optionsDialog(parent, null, dialogText, width, options); + } + + /** + * Creates a simple info dialog for displaying information to the user. + * The dialog has a single "Ok" button that will close the dialog + * + * @param parent Can be any gui element (Will just be used to get the root element) + * @param title Sets a separate title that will be displayed above the main dialog text. (Optional) + * @param dialogText The main dialog text. + * @param width The dialog width, (Height will automatically adjust based on content.) + */ + public static GuiDialog infoDialog(@NotNull GuiParent parent, @Nullable Component title, Component dialogText, int width, @Nullable Runnable okAction) { + return optionsDialog(parent, title, dialogText, width, neutral(Component.translatable("gui.ok"), okAction)); + } + + /** + * Creates a simple info dialog for displaying information to the user. + * The dialog has a single "Ok" button that will close the dialog + * + * @param parent Can be any gui element (Will just be used to get the root element) + * @param title Sets a separate title that will be displayed above the main dialog text. (Optional) + * @param dialogText The main dialog text. + * @param width The dialog width, (Height will automatically adjust based on content.) + */ + public static GuiDialog infoDialog(@NotNull GuiParent parent, @Nullable Component title, Component dialogText, int width) { + return infoDialog(parent, title, dialogText, width, null); + } + + /** + * Creates a simple info dialog for displaying information to the user. + * The dialog has a single "Ok" button that will close the dialog + * + * @param parent Can be any gui element (Will just be used to get the root element) + * @param dialogText The main dialog text. + * @param width The dialog width, (Height will automatically adjust based on content.) + */ + public static GuiDialog infoDialog(@NotNull GuiParent parent, Component dialogText, int width) { + return infoDialog(parent, null, dialogText, width); + } + + /** + * Create a green "Primary" button option. + */ + public static Option primary(Component text, @Nullable Runnable action) { + return new Option(text, action, hovered -> hovered ? 0xFF44AA44 : 0xFF118811); + } + + /** + * Create a grey "Neutral" button option. + */ + public static Option neutral(Component text, @Nullable Runnable action) { + return new Option(text, action, hovered -> hovered ? 0xFF909090 : 0xFF505050); + } + + /** + * Create a red "Caution" button option. + */ + public static Option caution(Component text, @Nullable Runnable action) { + return new Option(text, action, hovered -> hovered ? 0xFFAA4444 : 0xFF881111); + } + /** * @param blockKeyInput Prevent keyboard inputs from being sent to the rest of the gui while this dialog is open. * Default: true. @@ -153,91 +237,5 @@ private static GuiButton defaultButton(GuiDialog dialog, Option option) { return button; } - /** - * Option dialog builder with pre-configured background and button builders. - * - * @param parent Can be any gui element (Will just be used to get the root element) - * @param title Sets a separate title that will be displayed above the main dialog text. (Optional) - * @param dialogText The main dialog text. - * @param width The dialog width, (Height will automatically adjust based on content.) - * @param options The list of options for this dialog. - */ - public static GuiDialog optionsDialog(@NotNull GuiParent parent, @Nullable Component title, Component dialogText, int width, Option... options) { - return optionsDialog(parent, title, dialogText, GuiRectangle::toolTipBackground, GuiDialog::defaultButton, width, options); - } - - /** - * Option dialog builder with pre-configured background and button builders. - * - * @param parent Can be any gui element (Will just be used to get the root element) - * @param dialogText The main dialog text. - * @param width The dialog width, (Height will automatically adjust based on content.) - * @param options The list of options for this dialog. - */ - public static GuiDialog optionsDialog(@NotNull GuiParent parent, Component dialogText, int width, Option... options) { - return optionsDialog(parent, null, dialogText, width, options); - } - - /** - * Creates a simple info dialog for displaying information to the user. - * The dialog has a single "Ok" button that will close the dialog - * - * @param parent Can be any gui element (Will just be used to get the root element) - * @param title Sets a separate title that will be displayed above the main dialog text. (Optional) - * @param dialogText The main dialog text. - * @param width The dialog width, (Height will automatically adjust based on content.) - */ - public static GuiDialog infoDialog(@NotNull GuiParent parent, @Nullable Component title, Component dialogText, int width, @Nullable Runnable okAction) { - return optionsDialog(parent, title, dialogText, width, neutral(Component.translatable("gui.ok"), okAction)); - } - - /** - * Creates a simple info dialog for displaying information to the user. - * The dialog has a single "Ok" button that will close the dialog - * - * @param parent Can be any gui element (Will just be used to get the root element) - * @param title Sets a separate title that will be displayed above the main dialog text. (Optional) - * @param dialogText The main dialog text. - * @param width The dialog width, (Height will automatically adjust based on content.) - */ - public static GuiDialog infoDialog(@NotNull GuiParent parent, @Nullable Component title, Component dialogText, int width) { - return infoDialog(parent, title, dialogText, width, null); - } - - /** - * Creates a simple info dialog for displaying information to the user. - * The dialog has a single "Ok" button that will close the dialog - * - * @param parent Can be any gui element (Will just be used to get the root element) - * @param dialogText The main dialog text. - * @param width The dialog width, (Height will automatically adjust based on content.) - */ - public static GuiDialog infoDialog(@NotNull GuiParent parent, Component dialogText, int width) { - return infoDialog(parent, null, dialogText, width); - } - - /** - * Create a green "Primary" button option. - */ - public static Option primary(Component text, @Nullable Runnable action) { - return new Option(text, action, hovered -> hovered ? 0xFF44AA44 : 0xFF118811); - } - - /** - * Create a grey "Neutral" button option. - */ - public static Option neutral(Component text, @Nullable Runnable action) { - return new Option(text, action, hovered -> hovered ? 0xFF909090 : 0xFF505050); - } - - /** - * Create a red "Caution" button option. - */ - public static Option caution(Component text, @Nullable Runnable action) { - return new Option(text, action, hovered -> hovered ? 0xFFAA4444 : 0xFF881111); - } - - public record Option(Component text, @Nullable Runnable action, Function colour) { - - } + public record Option(Component text, @Nullable Runnable action, Function colour) {} } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiElement.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiElement.java index 5c51af86..5f5d6db8 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiElement.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiElement.java @@ -8,6 +8,7 @@ import codechicken.lib.gui.modular.lib.geometry.GuiParent; import codechicken.lib.gui.modular.lib.geometry.Position; import codechicken.lib.gui.modular.lib.geometry.Rectangle; +import net.covers1624.quack.util.SneakyUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.network.chat.Component; @@ -39,20 +40,19 @@ *

* Created by brandon3055 on 04/07/2023 */ -@SuppressWarnings ("unchecked") -public class GuiElement> extends ConstrainedGeometry implements ElementEvents, ToolTipHandler { +public class GuiElement> extends ConstrainedGeometry implements ElementEvents, TooltipHandler { @NotNull private GuiParent parent; private final List> addedQueue = new ArrayList<>(); - private final List> addedFirstQueue = new ArrayList<>(); private final List> removeQueue = new ArrayList<>(); private final List> childElements = new ArrayList<>(); + private final List> childElementsUnmodifiable = Collections.unmodifiableList(childElements); public boolean initialized = false; - private Font font; private Minecraft mc; + private Font font; private int screenWidth; private int screenHeight; @@ -83,18 +83,9 @@ public GuiParent getParent() { //=== Child Element Handling ===// - /** - * When creating custom gui elements, use this method to add any required child elements. - * With ModularGui v3 it is technically possible to add children in the constructor, - * But that may not always be supported. This is the preferred method. - */ - @Deprecated//I'm starting to just do everything in the element constructors. - protected void addChildElements() { - } - @Override public List> getChildren() { - return Collections.unmodifiableList(childElements); + return childElementsUnmodifiable; } /** @@ -138,10 +129,7 @@ protected void applyQueuedChildUpdates() { public void initElement(GuiParent parent) { removed = false; updateScreenData(parent.mc(), parent.font(), parent.scaledScreenWidth(), parent.scaledScreenHeight()); - if (!initialized) { - initialized = true; - addChildElements(); - } + initialized = true; } @Override @@ -210,12 +198,12 @@ protected void updateScreenData(Minecraft mc, Font font, int screenWidth, int sc public T setEnabled(boolean enabled) { this.enabled = () -> enabled; - return (T) this; + return SneakyUtils.unsafeCast(this); } public T setEnabled(@Nullable Supplier enabled) { this.enabled = enabled; - return (T) this; + return SneakyUtils.unsafeCast(this); } public boolean isEnabled() { @@ -228,7 +216,7 @@ public boolean isRemoved() { public T setEnableToolTip(Supplier enableToolTip) { this.enableToolTip = enableToolTip; - return (T) this; + return SneakyUtils.unsafeCast(this); } @Override @@ -266,7 +254,7 @@ public boolean isOpaque() { */ public T setOpaque(boolean opaque) { this.opaque = opaque; - return (T) this; + return SneakyUtils.unsafeCast(this); } /** @@ -299,7 +287,7 @@ public String toString() { */ public T jeiExclude() { getModularGui().jeiExclude(this); - return (T) this; + return SneakyUtils.unsafeCast(this); } /** @@ -307,7 +295,7 @@ public T jeiExclude() { */ public T removeJEIExclude() { getModularGui().removeJEIExclude(this); - return (T) this; + return SneakyUtils.unsafeCast(this); } //=== Render / Update ===// @@ -319,7 +307,7 @@ public T removeJEIExclude() { */ public T setRenderCull(@Nullable Rectangle renderCull) { this.renderCull = renderCull; - return (T) this; + return SneakyUtils.unsafeCast(this); } /** @@ -333,7 +321,7 @@ public T setRenderCull(@Nullable Rectangle renderCull) { */ public T setZStacking(boolean zStacking) { this.zStacking = zStacking; - return (T) this; + return SneakyUtils.unsafeCast(this); } public boolean zStacking() { @@ -383,7 +371,7 @@ public void render(GuiRender render, double mouseX, double mouseY, float partial applyQueuedChildUpdates(); if (this instanceof BackgroundRender bgr) { double depth = bgr.getBackgroundDepth(); - bgr.renderBehind(render, mouseX, mouseY, partialTicks); + bgr.renderBackground(render, mouseX, mouseY, partialTicks); if (depth > 0) { render.pose().translate(0, 0, depth); } @@ -409,7 +397,7 @@ public void render(GuiRender render, double mouseX, double mouseY, float partial if (this instanceof ForegroundRender fgr) { double depth = fgr.getForegroundDepth(); - fgr.renderInFront(render, mouseX, mouseY, partialTicks); + fgr.renderForeground(render, mouseX, mouseY, partialTicks); if (depth > 0) { render.pose().translate(0, 0, depth); } @@ -502,7 +490,7 @@ public Supplier> getTooltip() { @Override public T setTooltipDelay(int tooltipDelay) { this.hoverTextDelay = tooltipDelay; - return (T) this; + return SneakyUtils.unsafeCast(this); } @Override @@ -513,6 +501,6 @@ public int getTooltipDelay() { @Override public T setTooltip(@Nullable Supplier> tooltip) { this.toolTip = tooltip; - return (T) this; + return SneakyUtils.unsafeCast(this); } } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiEnergyBar.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiEnergyBar.java index 8c653e61..478e86a8 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiEnergyBar.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiEnergyBar.java @@ -1,12 +1,11 @@ package codechicken.lib.gui.modular.elements; -import codechicken.lib.gui.modular.sprite.CCGuiTextures; -import codechicken.lib.gui.modular.sprite.Material; -import codechicken.lib.gui.modular.lib.Assembly; import codechicken.lib.gui.modular.lib.BackgroundRender; import codechicken.lib.gui.modular.lib.Constraints; import codechicken.lib.gui.modular.lib.GuiRender; import codechicken.lib.gui.modular.lib.geometry.GuiParent; +import codechicken.lib.gui.modular.sprite.CCGuiTextures; +import codechicken.lib.gui.modular.sprite.Material; import codechicken.lib.util.FormatUtil; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; @@ -42,6 +41,50 @@ public GuiEnergyBar(@NotNull GuiParent parent) { setToolTipFormatter(defaultFormatter()); } + /** + * Creates a simple energy bar using a simple slot as a background to make it look nice. + */ + public static EnergyBar simpleBar(@NotNull GuiParent parent) { + GuiRectangle container = GuiRectangle.vanillaSlot(parent); + GuiEnergyBar energyBar = new GuiEnergyBar(container); + Constraints.bind(energyBar, container, 1); + return new EnergyBar(container, energyBar); + } + + public static BiFunction> defaultFormatter() { + return (energy, capacity) -> { + List tooltip = new ArrayList<>(); + tooltip.add(Component.translatable("energy_bar.polylib.energy_storage").withStyle(DARK_AQUA)); + boolean shift = Screen.hasShiftDown(); + tooltip.add(Component.translatable("energy_bar.polylib.capacity") + .withStyle(GOLD) + .append(" ") + .append(Component.literal(shift ? FormatUtil.addCommas(capacity) : FormatUtil.formatNumber(capacity)) + .withStyle(GRAY) + .append(" ") + .append(Component.translatable("energy_bar.polylib.rf") + .withStyle(GRAY) + ) + ) + ); + tooltip.add(Component.translatable("energy_bar.polylib.stored") + .withStyle(GOLD) + .append(" ") + .append(Component.literal(shift ? FormatUtil.addCommas(energy) : FormatUtil.formatNumber(energy)) + .withStyle(GRAY) + ) + .append(" ") + .append(Component.translatable("energy_bar.polylib.rf") + .withStyle(GRAY) + ) + .append(Component.literal(String.format(" (%.2f%%)", ((double) energy / (double) capacity) * 100D)) + .withStyle(GRAY) + ) + ); + return tooltip; + }; + } + public GuiEnergyBar setEmptyTexture(Material emptyTexture) { this.emptyTexture = emptyTexture; return this; @@ -88,57 +131,13 @@ public GuiEnergyBar setToolTipFormatter(BiFunction> } @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { - float p = 1/128F; + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { + float p = 1 / 128F; float height = getCapacity() <= 0 ? 0 : (float) ySize() * (getEnergy() / (float) getCapacity()); float texHeight = height * p; render.partialSprite(EMPTY.renderType(GuiRender::texColType), xMin(), yMin(), xMax(), yMax(), EMPTY.sprite(), 0F, 1F - (p * (float) ySize()), p * (float) xSize(), 1F, 0xFFFFFFFF); render.partialSprite(FULL.renderType(GuiRender::texColType), xMin(), yMin() + (ySize() - height), xMax(), yMax(), FULL.sprite(), 0F, 1F - texHeight, p * (float) xSize(), 1F, 0xFFFFFFFF); } - /** - * Creates a simple energy bar using a simple slot as a background to make it look nice. - */ - public static Assembly simpleBar(@NotNull GuiParent parent) { - GuiRectangle container = GuiRectangle.vanillaSlot(parent); - GuiEnergyBar energyBar = new GuiEnergyBar(container); - Constraints.bind(energyBar, container, 1); - return new Assembly<>(container, energyBar); - } - - - public static BiFunction> defaultFormatter() { - return (energy, capacity) -> { - List tooltip = new ArrayList<>(); - tooltip.add(Component.translatable("energy_bar.polylib.energy_storage").withStyle(DARK_AQUA)); - boolean shift = Screen.hasShiftDown(); - tooltip.add(Component.translatable("energy_bar.polylib.capacity") - .withStyle(GOLD) - .append(" ") - .append(Component.literal(shift ? FormatUtil.addCommas(capacity) : FormatUtil.formatNumber(capacity)) - .withStyle(GRAY) - .append(" ") - .append(Component.translatable("energy_bar.polylib.rf") - .withStyle(GRAY) - ) - ) - ); - tooltip.add(Component.translatable("energy_bar.polylib.stored") - .withStyle(GOLD) - .append(" ") - .append(Component.literal(shift ? FormatUtil.addCommas(energy) : FormatUtil.formatNumber(energy)) - .withStyle(GRAY) - ) - .append(" ") - .append(Component.translatable("energy_bar.polylib.rf") - .withStyle(GRAY) - ) - .append(Component.literal(String.format(" (%.2f%%)", ((double) energy / (double) capacity) * 100D)) - .withStyle(GRAY) - ) - ); - return tooltip; - }; - } - + public record EnergyBar(GuiRectangle container, GuiEnergyBar bar) {} } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiEntityRenderer.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiEntityRenderer.java index 1ead30fc..ac09f9b3 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiEntityRenderer.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiEntityRenderer.java @@ -165,7 +165,7 @@ public double getBackgroundDepth() { } @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { if (invalidEntity) return; try { @@ -261,61 +261,4 @@ public static void renderEntityInInventory(GuiRender render, double pX, double p render.pose().popPose(); Lighting.setupFor3DItems(); } - -// public void renderEntityOnScreen(GuiRender render, int xPos, int yPos, int scale, float mouseX, float mouseY, LivingEntity entity, double rotation, boolean trackMouse, boolean drawName, double zOffset) { -// render.pose().pushPose(); -// float lookX = trackMouse ? (float) Math.atan(mouseX / 40.0F) : 0; -// float lookY = trackMouse ? (float) Math.atan(mouseY / 40.0F) : 0; -// -// if (drawName && entity instanceof RemotePlayer && Minecraft.getInstance().player != null) { -// entity.setPos(Minecraft.getInstance().player.getX(), Minecraft.getInstance().player.getY(), Minecraft.getInstance().player.getZ()); -// } else if (entity instanceof RemotePlayer) { -// entity.setPos(0, -1000, 0); -// } -// -// PoseStack posestack = RenderSystem.getModelViewStack(); -// posestack.pushPose(); -// posestack.translate(0, 0, 0); -// posestack.scale(1.0F, 1.0F, -1.0F); -// RenderSystem.applyModelViewMatrix(); -// -// PoseStack posestack1 = render.pose(); -// posestack1.translate(xPos, yPos, zOffset); -// posestack1.scale((float) scale, (float) scale, (float) scale); -// Quaternionf quaternion = Axis.ZP.rotationDegrees(180.0F); -// posestack1.mulPose(quaternion); -// posestack1.mulPose(Axis.YP.rotationDegrees((float) rotation)); -// -// float lastYBodyRot = entity.yBodyRot; -// float lastYRot = entity.getYRot(); -// float lastXRot = entity.getXRot(); -// float lastYHeadRotO = entity.yHeadRotO; -// float lastYHeadRot = entity.yHeadRot; -// -// entity.yBodyRot = 180.0F + lookX * 20.0F; -// entity.setYRot(180.0F + lookX * 40.0F); -// entity.setXRot(-lookY * 20.0F); -// entity.yHeadRot = entity.getYRot(); -// entity.yHeadRotO = entity.getYRot(); -// -// Lighting.setupForEntityInInventory(); -// EntityRenderDispatcher entityrenderdispatcher = Minecraft.getInstance().getEntityRenderDispatcher(); -// entityrenderdispatcher.setRenderShadow(false); -// MultiBufferSource.BufferSource buffers = render.buffers(); -// RenderSystem.runAsFancy(() -> { -// entityrenderdispatcher.render(entity, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F, posestack1, buffers, 15728880); -// }); -// buffers.endBatch(); -// entityrenderdispatcher.setRenderShadow(true); -// entity.yBodyRot = lastYBodyRot; -// entity.setYRot(lastYRot); -// entity.setXRot(lastXRot); -// entity.yHeadRotO = lastYHeadRotO; -// entity.yHeadRot = lastYHeadRot; -// posestack.popPose(); -// RenderSystem.applyModelViewMatrix(); -// Lighting.setupFor3DItems(); -// -// render.pose().popPose(); -// } } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiFluidTank.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiFluidTank.java index a03c60e9..a2d4eb9a 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiFluidTank.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiFluidTank.java @@ -1,14 +1,12 @@ package codechicken.lib.gui.modular.elements; -import codechicken.lib.fluid.FluidUtils; -import codechicken.lib.util.FormatUtil; -import codechicken.lib.gui.modular.lib.Assembly; import codechicken.lib.gui.modular.lib.BackgroundRender; import codechicken.lib.gui.modular.lib.Constraints; import codechicken.lib.gui.modular.lib.GuiRender; import codechicken.lib.gui.modular.lib.geometry.GuiParent; -import codechicken.lib.gui.modular.sprite.Material; import codechicken.lib.gui.modular.sprite.CCGuiTextures; +import codechicken.lib.gui.modular.sprite.Material; +import codechicken.lib.util.FormatUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; @@ -17,11 +15,8 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -58,6 +53,16 @@ public GuiFluidTank(@NotNull GuiParent parent) { setToolTipFormatter(defaultFormatter()); } + /** + * Creates a simple tank using a simple slot as a background to make it look nice. + */ + public static FluidTank simpleTank(@NotNull GuiParent parent) { + GuiRectangle container = GuiRectangle.vanillaSlot(parent); + GuiFluidTank energyBar = new GuiFluidTank(container); + Constraints.bind(energyBar, container, 1); + return new FluidTank(container, energyBar); + } + /** * Sets the capacity of this tank in milli-buckets. */ @@ -132,7 +137,7 @@ public FluidStack getFluidStack() { } @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { FluidStack stack = getFluidStack(); Material fluidMat = Material.fromSprite(getStillTexture(stack)); @@ -174,16 +179,6 @@ private double computeGaugeSpacing() { return 0; } - /** - * Creates a simple tank using a simple slot as a background to make it look nice. - */ - public static Assembly simpleTank(@NotNull GuiParent parent) { - GuiRectangle container = GuiRectangle.vanillaSlot(parent); - GuiFluidTank energyBar = new GuiFluidTank(container); - Constraints.bind(energyBar, container, 1); - return new Assembly<>(container, energyBar); - } - public static BiFunction> defaultFormatter() { return (fluidStack, capacity) -> { List tooltip = new ArrayList<>(); @@ -253,4 +248,5 @@ public static TextureAtlasSprite getStillTexture(Fluid fluid) { return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture); } + public record FluidTank(GuiRectangle container, GuiFluidTank tank) {} } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiItemStack.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiItemStack.java index 82cb73f4..2ff85905 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiItemStack.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiItemStack.java @@ -96,7 +96,7 @@ public double getBackgroundDepth() { } @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { ItemStack stack = this.stack.get(); if (stack.isEmpty()) return; diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiManipulable.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiManipulable.java index 373d9ecf..d95835e4 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiManipulable.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiManipulable.java @@ -1,6 +1,7 @@ package codechicken.lib.gui.modular.elements; import codechicken.lib.gui.modular.lib.ContentElement; +import codechicken.lib.gui.modular.lib.CursorHelper; import codechicken.lib.gui.modular.lib.geometry.Constraint; import codechicken.lib.gui.modular.lib.geometry.GeoParam; import codechicken.lib.gui.modular.lib.geometry.GuiParent; @@ -42,7 +43,7 @@ public class GuiManipulable extends GuiElement implements Conten private boolean dragLeft = false; private boolean dragBottom = false; private boolean dragRight = false; - private ResourceLocation[] cursors = null; + private boolean enableCursors = false; //Made available for external position restraints public int xMin = 0; @@ -128,8 +129,7 @@ public GuiManipulable addResizeHandles(int handleSize, boolean includeTopHandle) } public GuiManipulable addTopHandle(int handleSize) { -// if (topHandle != null) throw new IllegalStateException("Top handle already exists!"); - this.topHandle/* = new GuiRectangle(contentElement)*/ + this.topHandle .constrain(TOP, match(contentElement.get(TOP))) .constrain(LEFT, match(contentElement.get(LEFT))) .constrain(RIGHT, match(contentElement.get(RIGHT))) @@ -138,8 +138,7 @@ public GuiManipulable addTopHandle(int handleSize) { } public GuiManipulable addBottomHandle(int handleSize) { -// if (bottomHandle != null) throw new IllegalStateException("Bottom handle already exists!"); - this.bottomHandle/* = new GuiRectangle(contentElement)*/ + this.bottomHandle .constrain(BOTTOM, match(contentElement.get(BOTTOM))) .constrain(LEFT, match(contentElement.get(LEFT))) .constrain(RIGHT, match(contentElement.get(RIGHT))) @@ -148,8 +147,7 @@ public GuiManipulable addBottomHandle(int handleSize) { } public GuiManipulable addLeftHandle(int handleSize) { -// if (leftHandle != null) throw new IllegalStateException("Left handle already exists!"); - this.leftHandle/* = new GuiRectangle(contentElement)*/ + this.leftHandle .constrain(LEFT, match(contentElement.get(LEFT))) .constrain(TOP, match(contentElement.get(TOP))) .constrain(BOTTOM, match(contentElement.get(BOTTOM))) @@ -158,8 +156,7 @@ public GuiManipulable addLeftHandle(int handleSize) { } public GuiManipulable addRightHandle(int handleSize) { -// if (rightHandle != null) throw new IllegalStateException("Left handle already exists!"); - this.rightHandle /*= new GuiRectangle(contentElement)*/ + this.rightHandle .constrain(RIGHT, match(contentElement.get(RIGHT))) .constrain(TOP, match(contentElement.get(TOP))) .constrain(BOTTOM, match(contentElement.get(BOTTOM))) @@ -168,8 +165,7 @@ public GuiManipulable addRightHandle(int handleSize) { } public GuiManipulable addMoveHandle(int handleSize) { -// if (moveHandle != null) throw new IllegalStateException("Move handle already exists!"); - this.moveHandle/* = new GuiRectangle(contentElement)*/ + this.moveHandle .constrain(TOP, match(contentElement.get(TOP))) .constrain(LEFT, match(contentElement.get(LEFT))) .constrain(RIGHT, match(contentElement.get(RIGHT))) @@ -218,12 +214,10 @@ public GuiElement getBottomHandle() { } /** - * Set an array of 5 mouse cursor icons to be used when manipulating the gui element. - * These cursors are (in order) Drag (Any direction), Drag-Horizontal, Drag-Vertical, Drag-Corner (Top Right/Bottom Left), Drag-Corner (Top Left/Bottom Right) + * Enables rendering of custom mouse cursors when hovering over a draggable handle. */ - public GuiManipulable setCursors(ResourceLocation[] cursors) { - if (cursors != null && cursors.length != 5) throw new IllegalStateException("Must provide 5 cursor icons, no more, no less. Found "+ cursors.length); - this.cursors = cursors; + public GuiManipulable enableCursors(boolean enableCursors) { + this.enableCursors = enableCursors; return this; } @@ -261,7 +255,7 @@ public Rectangle getMaxSize() { @Override public void tick(double mouseX, double mouseY) { - if (cursors != null) { + if (enableCursors) { boolean posFlag = moveHandle != null && moveHandle.isMouseOver(); boolean topFlag = topHandle != null && topHandle.isMouseOver(); boolean leftFlag = leftHandle != null && leftHandle.isMouseOver(); @@ -271,15 +265,15 @@ public void tick(double mouseX, double mouseY) { if (any) { if (posFlag) { - getModularGui().setCursor(cursors[0]); + getModularGui().setCursor(CursorHelper.DRAG); } else if ((topFlag && leftFlag) || (bottomFlag && rightFlag)) { - getModularGui().setCursor(cursors[4]); + getModularGui().setCursor(CursorHelper.RESIZE_TLBR); } else if ((topFlag && rightFlag) || (bottomFlag && leftFlag)) { - getModularGui().setCursor(cursors[3]); + getModularGui().setCursor(CursorHelper.RESIZE_TRBL); } else if (topFlag || bottomFlag) { - getModularGui().setCursor(cursors[2]); + getModularGui().setCursor(CursorHelper.RESIZE_V); } else { - getModularGui().setCursor(cursors[1]); + getModularGui().setCursor(CursorHelper.RESIZE_H); } } } @@ -294,8 +288,6 @@ public void startDragging() { dragYOffset = (int) (mouseY - yMin); isDragging = true; dragPos = true; - onStartMove(mouseX, mouseY); - onStartManipulation(mouseX, mouseY); } @Override @@ -314,19 +306,11 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { isDragging = true; if (posFlag) { dragPos = true; - if (onStartMove(mouseX, mouseY)) { - isDragging = false; - return true; - } } else { dragTop = topFlag; dragLeft = leftFlag; dragBottom = bottomFlag; dragRight = rightFlag; - onStartResized(mouseX, mouseY); - } - if (onStartManipulation(mouseX, mouseY)) { - dragPos = dragTop = dragLeft = dragBottom = dragRight = false; } return true; } @@ -346,7 +330,6 @@ public void mouseMoved(double mouseX, double mouseY) { yMin += yMove; yMax += yMove; validatePosition(); - validateMove(previous, (int) mouseX, (int) mouseY); onMoved(); } else { Rectangle min = getMinSize(); @@ -378,7 +361,6 @@ public void mouseMoved(double mouseX, double mouseY) { validatePosition(); onResized(); } - onManipulated(mouseX, mouseY); } super.mouseMoved(mouseX, mouseY); } @@ -387,12 +369,6 @@ public void mouseMoved(double mouseX, double mouseY) { public boolean mouseReleased(double mouseX, double mouseY, int button, boolean consumed) { if (isDragging) { validatePosition(); - if (dragPos) { - onFinishMove(mouseX, mouseY); - } else { - onFinishResized(mouseX, mouseY); - } - onFinishManipulation(mouseX, mouseY); } isDragging = dragPos = dragTop = dragLeft = dragBottom = dragRight = false; return super.mouseReleased(mouseX, mouseY, button, consumed); @@ -419,28 +395,6 @@ protected void onResized() { } } - //TODO, In v2 these were made available for elements that extend GuiManipulable, In v3 i probably just want to add listener hooks. - protected void onManipulated(double mouseX, double mouseY) {} - - protected boolean onStartManipulation(double mouseX, double mouseY) { - return false; - } - - protected void onFinishManipulation(double mouseX, double mouseY) {} - - protected boolean onStartMove(double mouseX, double mouseY) { - return false; - } - - protected void onStartResized(double mouseX, double mouseY) {} - - protected void onFinishMove(double mouseX, double mouseY) {} - - protected void onFinishResized(double mouseX, double mouseY) {} - - protected void validateMove(Rectangle previous, double mouseX, double mouseY) { - } - public interface PositionRestraint { void restrainPosition(GuiManipulable draggable); } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiProgressIcon.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiProgressIcon.java index 00449739..3e56ce61 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiProgressIcon.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiProgressIcon.java @@ -91,7 +91,7 @@ public double getProgress() { } @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { render.pose().pushPose(); double width = direction.getAxis() == Axis.X ? xSize() : ySize(); diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiRectangle.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiRectangle.java index b707d13f..0d034702 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiRectangle.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiRectangle.java @@ -31,6 +31,46 @@ public GuiRectangle(@NotNull GuiParent parent) { super(parent); } + /** + * Creates a rectangle that mimics the appearance of a vanilla inventory slot. + * Uses shadedRect to create the 3D "inset" look. + */ + public static GuiRectangle vanillaSlot(@NotNull GuiParent parent) { + return new GuiRectangle(parent).shadedRect(0xFF373737, 0xFFffffff, 0xFF8b8b8b, 0xFF8b8b8b); + } + + /** + * Creates a rectangle that mimics the appearance of a vanilla inventory slot, except inverted + * Uses shadedRect to create the 3D "popped out" appearance + */ + public static GuiRectangle invertedSlot(@NotNull GuiParent parent) { + return new GuiRectangle(parent).shadedRect(0xFFffffff, 0xFF373737, 0xFF8b8b8b, 0xFF8b8b8b); + } + + /** + * Creates a rectangle similar in appearance to a vanilla button, but with no texture and no black border. + */ + public static GuiRectangle planeButton(@NotNull GuiParent parent) { + return new GuiRectangle(parent).shadedRect(0xFFaaaaaa, 0xFF545454, 0xFF6f6f6f); + } + + public static GuiRectangle toolTipBackground(@NotNull GuiParent parent) { + return toolTipBackground(parent, 0xF0100010, 0x505000FF, 0x5028007f); + } + + public static GuiRectangle toolTipBackground(@NotNull GuiParent parent, int backgroundColour, int borderColourTop, int borderColourBottom) { + return toolTipBackground(parent, backgroundColour, backgroundColour, borderColourTop, borderColourBottom); + } + + public static GuiRectangle toolTipBackground(@NotNull GuiParent parent, int backgroundColourTop, int backgroundColourBottom, int borderColourTop, int borderColourBottom) { + return new GuiRectangle(parent) { + @Override + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { + render.toolTipBackground(xMin(), yMin(), xSize(), ySize(), backgroundColourTop, backgroundColourBottom, borderColourTop, borderColourBottom, false); + } + }; + } + public GuiRectangle border(int border) { return border(() -> border); } @@ -113,53 +153,13 @@ public double getBorderWidth() { } @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { if (shadeTopLeft != null && shadeBottomRight != null && shadeCorners != null) { render.shadedRect(getRectangle(), getBorderWidth(), shadeTopLeft.get(), shadeBottomRight.get(), shadeCorners.get(), fill == null ? 0 : fill.get()); - } else if (border != null){ + } else if (border != null) { render.borderRect(getRectangle(), getBorderWidth(), fill == null ? 0 : fill.get(), border.get()); } else if (fill != null) { render.rect(getRectangle(), fill.get()); } } - - /** - * Creates a rectangle that mimics the appearance of a vanilla inventory slot. - * Uses shadedRect to create the 3D "inset" look. - */ - public static GuiRectangle vanillaSlot(@NotNull GuiParent parent) { - return new GuiRectangle(parent).shadedRect(0xFF373737, 0xFFffffff, 0xFF8b8b8b, 0xFF8b8b8b); - } - - /** - * Creates a rectangle that mimics the appearance of a vanilla inventory slot, except inverted - * Uses shadedRect to create the 3D "popped out" appearance - */ - public static GuiRectangle invertedSlot(@NotNull GuiParent parent) { - return new GuiRectangle(parent).shadedRect(0xFFffffff, 0xFF373737, 0xFF8b8b8b, 0xFF8b8b8b); - } - - /** - * Creates a rectangle similar in appearance to a vanilla button, but with no texture and no black border. - */ - public static GuiRectangle planeButton(@NotNull GuiParent parent) { - return new GuiRectangle(parent).shadedRect(0xFFaaaaaa, 0xFF545454, 0xFF6f6f6f); - } - - public static GuiRectangle toolTipBackground(@NotNull GuiParent parent) { - return toolTipBackground(parent, 0xF0100010, 0x505000FF, 0x5028007f); - } - - public static GuiRectangle toolTipBackground(@NotNull GuiParent parent, int backgroundColour, int borderColourTop, int borderColourBottom) { - return toolTipBackground(parent, backgroundColour, backgroundColour, borderColourTop, borderColourBottom); - } - - public static GuiRectangle toolTipBackground(@NotNull GuiParent parent, int backgroundColourTop, int backgroundColourBottom, int borderColourTop, int borderColourBottom) { - return new GuiRectangle(parent) { - @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { - render.toolTipBackground(xMin(), yMin(), xSize(), ySize(), backgroundColourTop, backgroundColourBottom, borderColourTop, borderColourBottom, false); - } - }; - } } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiScrolling.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiScrolling.java index 8aa40767..c0c5f9e0 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiScrolling.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiScrolling.java @@ -1,6 +1,9 @@ package codechicken.lib.gui.modular.elements; -import codechicken.lib.gui.modular.lib.*; +import codechicken.lib.gui.modular.lib.Constraints; +import codechicken.lib.gui.modular.lib.ContentElement; +import codechicken.lib.gui.modular.lib.GuiRender; +import codechicken.lib.gui.modular.lib.SliderState; import codechicken.lib.gui.modular.lib.geometry.Axis; import codechicken.lib.gui.modular.lib.geometry.Constraint; import codechicken.lib.gui.modular.lib.geometry.GeoParam; @@ -173,7 +176,7 @@ public ContentElement constrain(GeoParam param, @Nullable Constraint constraint) } } - public static Assembly, GuiScrolling> simpleScrollWindow(@NotNull GuiParent parent, boolean verticalScrollBar, boolean horizontalScrollBar) { + public static ScrollWindow simpleScrollWindow(@NotNull GuiParent parent, boolean verticalScrollBar, boolean horizontalScrollBar) { GuiElement container = new GuiElement<>(parent); GuiRectangle background = GuiRectangle.vanillaSlot(container) .constrain(TOP, match(container.get(TOP))) @@ -184,32 +187,33 @@ public static Assembly, GuiScrolling> simpleScrollWindow GuiScrolling scroll = new GuiScrolling(background); Constraints.bind(scroll, background, 1); - var result = new Assembly<>(container, scroll); - + GuiSlider.ScrollBar verticalBar = null; if (verticalScrollBar) { - var bar = GuiSlider.vanillaScrollBar(container, Axis.Y); - bar.container + verticalBar = GuiSlider.vanillaScrollBar(container, Axis.Y); + verticalBar.container() .constrain(TOP, match(container.get(TOP))) .constrain(BOTTOM, relative(container.get(BOTTOM), horizontalScrollBar ? -10 : 0)) .constrain(RIGHT, match(container.get(RIGHT))) .constrain(WIDTH, Constraint.literal(9)); - bar.primary + verticalBar.slider() .setSliderState(scroll.scrollState(Axis.Y)) .setScrollableElement(scroll); - result.addParts(bar.container, bar.primary, bar.getPart(0)); } + GuiSlider.ScrollBar horizontalBar = null; if (horizontalScrollBar) { - var bar = GuiSlider.vanillaScrollBar(container, Axis.X); - bar.container + horizontalBar = GuiSlider.vanillaScrollBar(container, Axis.X); + horizontalBar.container() .constrain(BOTTOM, match(container.get(BOTTOM))) .constrain(LEFT, match(container.get(LEFT))) .constrain(RIGHT, relative(container.get(RIGHT), verticalScrollBar ? -10 : 0)) .constrain(HEIGHT, Constraint.literal(9)); - bar.primary + horizontalBar.slider() .setSliderState(scroll.scrollState(Axis.X)) .setScrollableElement(scroll); - result.addParts(bar.container, bar.primary, bar.getPart(0)); } - return result; + return new ScrollWindow(container, scroll, verticalBar, horizontalBar); + } + + public record ScrollWindow(GuiElement container, GuiScrolling scrolling, @Nullable GuiSlider.ScrollBar verticalBar, @Nullable GuiSlider.ScrollBar horizontalBar) { } } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiSlider.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiSlider.java index 47d94246..2157ccf8 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiSlider.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiSlider.java @@ -57,6 +57,29 @@ public GuiSlider(@NotNull GuiParent parent, Axis axis, GuiElement slider) installSlider(slider); } + /** + * Vanilla does not really seem to have a standard for its scroll bars, + * But this is something that should at least fit in to a typical vanilla gui. + */ + public static ScrollBar vanillaScrollBar(GuiElement parent, Axis axis) { + GuiRectangle background = GuiRectangle.vanillaSlot(parent); + + GuiSlider slider = new GuiSlider(background, axis); + Constraints.bind(slider, background, 1); + + slider.installSlider(GuiRectangle.planeButton(slider)) + .bindSliderLength() + .bindSliderWidth(); + + GuiRectangle sliderHighlight = new GuiRectangle(slider.getSlider()) + .fill(0x5000b6FF) + .setEnabled(() -> slider.getSlider().isMouseOver()); + + Constraints.bind(sliderHighlight, slider.getSlider()); + + return new ScrollBar(background, slider, sliderHighlight); + } + /** * Set the slider state used by this slider element. * The slider state is used to get and set the slider position. @@ -239,26 +262,5 @@ public boolean mouseScrolled(double mouseX, double mouseY, double scroll) { return false; } - /** - * Vanilla does not really seem to have a standard for its scroll bars, - * But this is something that should at least fit in to a typical vanilla gui. - */ - public static Assembly vanillaScrollBar(GuiElement parent, Axis axis) { - GuiRectangle background = GuiRectangle.vanillaSlot(parent); - - GuiSlider slider = new GuiSlider(background, axis); - Constraints.bind(slider, background, 1); - - slider.installSlider(GuiRectangle.planeButton(slider)) - .bindSliderLength() - .bindSliderWidth(); - - GuiRectangle sliderHighlight = new GuiRectangle(slider.getSlider()) - .fill(0x5000b6FF) - .setEnabled(() -> slider.getSlider().isMouseOver()); - - Constraints.bind(sliderHighlight, slider.getSlider()); - - return new Assembly<>(background, slider).addParts(sliderHighlight); - } + public record ScrollBar(GuiRectangle container, GuiSlider slider, GuiRectangle highlight) {} } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiSlots.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiSlots.java index 8c94d9da..9ce861eb 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiSlots.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiSlots.java @@ -1,6 +1,5 @@ package codechicken.lib.gui.modular.elements; -import codechicken.lib.gui.modular.lib.Assembly; import codechicken.lib.gui.modular.lib.BackgroundRender; import codechicken.lib.gui.modular.lib.GuiRender; import codechicken.lib.gui.modular.lib.container.ContainerScreenAccess; @@ -81,6 +80,101 @@ public GuiSlots(@NotNull GuiParent parent, ContainerScreenAccess screenAcc updateSlots(parent.getModularGui().getRoot()); } + //=== Construction Helpers ===// + + public static GuiSlots singleSlot(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup slots) { + return singleSlot(parent, screenAccess, slots, 0); + } + + public static GuiSlots singleSlot(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup slots, int index) { + return new GuiSlots(parent, screenAccess, slots, index, 1, 1); + } + + public static Player player(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots) { + return player(parent, screenAccess, mainSlots, hotBarSlots, 3); + } + + public static Player player(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots, int hotBarSpacing) { + int width = 18 * 9; + int height = 18 * 4 + hotBarSpacing; + GuiElement container = new GuiElement<>(parent) + .setZStacking(false) + .constrain(WIDTH, Constraint.literal(width)) + .constrain(HEIGHT, Constraint.literal(height)); + + GuiSlots main = new GuiSlots(container, screenAccess, mainSlots, 9) + .constrain(TOP, Constraint.midPoint(container.get(TOP), container.get(BOTTOM), height / -2D)) + .constrain(LEFT, Constraint.midPoint(container.get(LEFT), container.get(RIGHT), width / -2D)); + + GuiSlots bar = new GuiSlots(container, screenAccess, hotBarSlots, 9) + .constrain(TOP, relative(main.get(BOTTOM), hotBarSpacing)) + .constrain(LEFT, match(main.get(LEFT))); + return new Player(container, main, bar); + } + + public static PlayerWithArmor playerWithArmor(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots, SlotGroup armorSlots) { + return playerWithArmor(parent, screenAccess, mainSlots, hotBarSlots, armorSlots, 3, true); + } + + public static PlayerWithArmor playerWithArmor(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots, SlotGroup armorSlots, int groupSpacing, boolean slotIcons) { + int width = 18 * 10 + groupSpacing; + int height = 18 * 4 + groupSpacing; + GuiElement container = new GuiElement<>(parent) + .setZStacking(false) + .constrain(WIDTH, Constraint.literal(width)) + .constrain(HEIGHT, Constraint.literal(height)); + + GuiSlots armor = new GuiSlots(container, screenAccess, armorSlots, 1) + .setYSlotSpacing(groupSpacing / 3) + .setEmptyIcon(index -> slotIcons ? ARMOR_SLOTS[index] : null) + .constrain(TOP, Constraint.midPoint(container.get(TOP), container.get(BOTTOM), height / -2D)) + .constrain(LEFT, Constraint.midPoint(container.get(LEFT), container.get(RIGHT), width / -2D)); + + GuiSlots main = new GuiSlots(container, screenAccess, mainSlots, 9) + .constrain(TOP, match(armor.get(TOP))) + .constrain(LEFT, relative(armor.get(RIGHT), groupSpacing)); + + GuiSlots bar = new GuiSlots(container, screenAccess, hotBarSlots, 9) + .constrain(TOP, relative(main.get(BOTTOM), groupSpacing)) + .constrain(LEFT, match(main.get(LEFT))); + + return new PlayerWithArmor(container, main, bar, armor); + } + + public static PlayerAll playerAllSlots(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots, SlotGroup armorSlots, SlotGroup offhandSlots) { + return playerAllSlots(parent, screenAccess, mainSlots, hotBarSlots, armorSlots, offhandSlots, 3, true); + } + + public static PlayerAll playerAllSlots(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots, SlotGroup armorSlots, SlotGroup offhandSlots, int groupSpacing, boolean slotIcons) { + int width = 18 * 11 + groupSpacing * 2; + int height = 18 * 4 + groupSpacing; + GuiElement container = new GuiElement<>(parent) + .setZStacking(false) + .constrain(WIDTH, Constraint.literal(width)) + .constrain(HEIGHT, Constraint.literal(height)); + + GuiSlots armor = new GuiSlots(container, screenAccess, armorSlots, 1) + .setYSlotSpacing(groupSpacing / 3) + .setEmptyIcon(index -> slotIcons ? ARMOR_SLOTS[index] : null) + .constrain(TOP, Constraint.midPoint(container.get(TOP), container.get(BOTTOM), height / -2D)) + .constrain(LEFT, Constraint.midPoint(container.get(LEFT), container.get(RIGHT), width / -2D)); + + GuiSlots main = new GuiSlots(container, screenAccess, mainSlots, 9) + .constrain(TOP, match(armor.get(TOP))) + .constrain(LEFT, relative(armor.get(RIGHT), groupSpacing)); + + GuiSlots bar = new GuiSlots(container, screenAccess, hotBarSlots, 9) + .constrain(TOP, relative(main.get(BOTTOM), groupSpacing)) + .constrain(LEFT, match(main.get(LEFT))); + + GuiSlots offHand = new GuiSlots(container, screenAccess, offhandSlots, 1) + .setEmptyIcon(index -> slotIcons ? OFF_HAND_SLOT : null) + .constrain(TOP, match(bar.get(TOP))) + .constrain(LEFT, relative(bar.get(RIGHT), groupSpacing)); + + return new PlayerAll(container, main, bar, armor, offHand); + } + //=== Slots Setup ===// /** @@ -172,7 +266,7 @@ public void tick(double mouseX, double mouseY) { } @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { GuiElement root = getModularGui().getRoot(); updateSlots(root); @@ -210,98 +304,9 @@ public void renderBehind(GuiRender render, double mouseX, double mouseY, float p render.pose().popPose(); } - //=== Construction Helpers ===// - - public static GuiSlots singleSlot(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup slots) { - return singleSlot(parent, screenAccess, slots, 0); - } - - public static GuiSlots singleSlot(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup slots, int index) { - return new GuiSlots(parent, screenAccess, slots, index, 1, 1); - } - - public static Assembly, GuiSlots> player(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots) { - return player(parent, screenAccess, mainSlots, hotBarSlots, 3); - } - - public static Assembly, GuiSlots> player(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots, int hotBarSpacing) { - int width = 18 * 9; - int height = 18 * 4 + hotBarSpacing; - GuiElement container = new GuiElement<>(parent) - .setZStacking(false) - .constrain(WIDTH, Constraint.literal(width)) - .constrain(HEIGHT, Constraint.literal(height)); - - GuiSlots main = new GuiSlots(container, screenAccess, mainSlots, 9) - .constrain(TOP, Constraint.midPoint(container.get(TOP), container.get(BOTTOM), height / -2D)) - .constrain(LEFT, Constraint.midPoint(container.get(LEFT), container.get(RIGHT), width / -2D)); - - GuiSlots bar = new GuiSlots(container, screenAccess, hotBarSlots, 9) - .constrain(TOP, relative(main.get(BOTTOM), hotBarSpacing)) - .constrain(LEFT, match(main.get(LEFT))); - return new Assembly<>(container, main).addParts(bar); - } - - public static Assembly, GuiSlots> playerWithArmor(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots, SlotGroup armorSlots) { - return playerWithArmor(parent, screenAccess, mainSlots, hotBarSlots, armorSlots, 3, true); - } - - public static Assembly, GuiSlots> playerWithArmor(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots, SlotGroup armorSlots, int groupSpacing, boolean slotIcons) { - int width = 18 * 10 + groupSpacing; - int height = 18 * 4 + groupSpacing; - GuiElement container = new GuiElement<>(parent) - .setZStacking(false) - .constrain(WIDTH, Constraint.literal(width)) - .constrain(HEIGHT, Constraint.literal(height)); - - GuiSlots armor = new GuiSlots(container, screenAccess, armorSlots, 1) - .setYSlotSpacing(groupSpacing / 3) - .setEmptyIcon(index -> slotIcons ? ARMOR_SLOTS[index] : null) - .constrain(TOP, Constraint.midPoint(container.get(TOP), container.get(BOTTOM), height / -2D)) - .constrain(LEFT, Constraint.midPoint(container.get(LEFT), container.get(RIGHT), width / -2D)); - - GuiSlots main = new GuiSlots(container, screenAccess, mainSlots, 9) - .constrain(TOP, match(armor.get(TOP))) - .constrain(LEFT, relative(armor.get(RIGHT), groupSpacing)); - - GuiSlots bar = new GuiSlots(container, screenAccess, hotBarSlots, 9) - .constrain(TOP, relative(main.get(BOTTOM), groupSpacing)) - .constrain(LEFT, match(main.get(LEFT))); - - return new Assembly<>(container, main).addParts(bar, armor); - } - - public static Assembly, GuiSlots> playerAllSlots(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots, SlotGroup armorSlots, SlotGroup offhandSlots) { - return playerAllSlots(parent, screenAccess, mainSlots, hotBarSlots, armorSlots, offhandSlots, 3, true); - } - - public static Assembly, GuiSlots> playerAllSlots(@NotNull GuiParent parent, ContainerScreenAccess screenAccess, SlotGroup mainSlots, SlotGroup hotBarSlots, SlotGroup armorSlots, SlotGroup offhandSlots, int groupSpacing, boolean slotIcons) { - int width = 18 * 11 + groupSpacing * 2; - int height = 18 * 4 + groupSpacing; - GuiElement container = new GuiElement<>(parent) - .setZStacking(false) - .constrain(WIDTH, Constraint.literal(width)) - .constrain(HEIGHT, Constraint.literal(height)); - - GuiSlots armor = new GuiSlots(container, screenAccess, armorSlots, 1) - .setYSlotSpacing(groupSpacing / 3) - .setEmptyIcon(index -> slotIcons ? ARMOR_SLOTS[index] : null) - .constrain(TOP, Constraint.midPoint(container.get(TOP), container.get(BOTTOM), height / -2D)) - .constrain(LEFT, Constraint.midPoint(container.get(LEFT), container.get(RIGHT), width / -2D)); + public record Player(GuiElement container, GuiSlots main, GuiSlots hotBar) {} - GuiSlots main = new GuiSlots(container, screenAccess, mainSlots, 9) - .constrain(TOP, match(armor.get(TOP))) - .constrain(LEFT, relative(armor.get(RIGHT), groupSpacing)); + public record PlayerWithArmor(GuiElement container, GuiSlots main, GuiSlots hotBar, GuiSlots armor) {} - GuiSlots bar = new GuiSlots(container, screenAccess, hotBarSlots, 9) - .constrain(TOP, relative(main.get(BOTTOM), groupSpacing)) - .constrain(LEFT, match(main.get(LEFT))); - - GuiSlots offHand = new GuiSlots(container, screenAccess, offhandSlots, 1) - .setEmptyIcon(index -> slotIcons ? OFF_HAND_SLOT : null) - .constrain(TOP, match(bar.get(TOP))) - .constrain(LEFT, relative(bar.get(RIGHT), groupSpacing)); - - return new Assembly<>(container, main).addParts(bar, armor, offHand); - } + public record PlayerAll(GuiElement container, GuiSlots main, GuiSlots hotBar, GuiSlots armor, GuiSlots offHand) {} } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiText.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiText.java index 23a6f270..2776c2d5 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiText.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiText.java @@ -208,7 +208,7 @@ public double getForegroundDepth() { } @Override - public void renderInFront(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderForeground(GuiRender render, double mouseX, double mouseY, float partialTicks) { Component component = getText(); if (component == null) return; Font font = render.font(); @@ -265,30 +265,4 @@ else if (tooLong && scroll) { stack.popPose(); } } -} - - - - - - - - - - - - - - - - - - - - - - - - - - +} \ No newline at end of file diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiTextField.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiTextField.java index dea19d7e..680b918c 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiTextField.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiTextField.java @@ -1,6 +1,5 @@ package codechicken.lib.gui.modular.elements; -import codechicken.lib.gui.modular.lib.Assembly; import codechicken.lib.gui.modular.lib.BackgroundRender; import codechicken.lib.gui.modular.lib.GuiRender; import codechicken.lib.gui.modular.lib.TextState; @@ -71,6 +70,24 @@ public GuiTextField(@NotNull GuiParent parent) { super(parent); } + /** + * Creates a simple text box with a simple bordered background. + * Using colours 0xFF000000, 0xFFFFFFFF, 0xE0E0E0 will get you a text box identical to the one in a command block + */ + public static TextField create(GuiElement parent, int backgroundColour, int borderColour, int textColour) { + GuiRectangle background = new GuiRectangle(parent) + .rectangle(backgroundColour, borderColour); + + GuiTextField textField = new GuiTextField(background) + .setTextColor(textColour) + .constrain(TOP, Constraint.relative(background.get(TOP), 1)) + .constrain(BOTTOM, Constraint.relative(background.get(BOTTOM), -1)) + .constrain(LEFT, Constraint.relative(background.get(LEFT), 4)) + .constrain(RIGHT, Constraint.relative(background.get(RIGHT), -4)); + + return new TextField(background, textField); + } + //=== Text field setup ===// /** @@ -576,7 +593,7 @@ public double getBackgroundDepth() { } @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { String value = getValue(); int colour = textColor.get(); @@ -638,22 +655,6 @@ public void tick(double mouseX, double mouseY) { tick++; } - /** - * Creates a simple text box with a simple bordered background. - * Using colours 0xFF000000, 0xFFFFFFFF, 0xE0E0E0 will get you a text box identical to the one in a command block - */ - public static Assembly create(GuiElement parent, int backgroundColour, int borderColour, int textColour) { - GuiRectangle background = new GuiRectangle(parent) - .rectangle(backgroundColour, borderColour); - - GuiTextField textField = new GuiTextField(background) - .setTextColor(textColour) - .constrain(TOP, Constraint.relative(background.get(TOP), 1)) - .constrain(BOTTOM, Constraint.relative(background.get(BOTTOM), -1)) - .constrain(LEFT, Constraint.relative(background.get(LEFT), 4)) - .constrain(RIGHT, Constraint.relative(background.get(RIGHT), -4)); - - return new Assembly<>(background, textField); - } + public record TextField(GuiRectangle container, GuiTextField field) {} } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiTextList.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiTextList.java index 88efcb4f..865b935c 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiTextList.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiTextList.java @@ -147,7 +147,7 @@ public double getForegroundDepth() { } @Override - public void renderInFront(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderForeground(GuiRender render, double mouseX, double mouseY, float partialTicks) { List list = getText(); if (list.isEmpty()) return; Font font = render.font(); @@ -170,30 +170,4 @@ public void renderInFront(GuiRender render, double mouseX, double mouseY, float yPos += font.lineHeight + lineSpacing; } } -} - - - - - - - - - - - - - - - - - - - - - - - - - - +} \ No newline at end of file diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiTexture.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiTexture.java index a31967f7..da5c0577 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiTexture.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiTexture.java @@ -98,7 +98,7 @@ public GuiTexture setColour(Supplier colour) { } @Override - public void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks) { + public void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks) { Material material = getMaterial(); if (material == null) return; if (dynamicBorders != null) { diff --git a/src/main/java/codechicken/lib/gui/modular/lib/Assembly.java b/src/main/java/codechicken/lib/gui/modular/lib/Assembly.java deleted file mode 100644 index 634ef366..00000000 --- a/src/main/java/codechicken/lib/gui/modular/lib/Assembly.java +++ /dev/null @@ -1,52 +0,0 @@ -package codechicken.lib.gui.modular.lib; - -import codechicken.lib.gui.modular.elements.GuiElement; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * This represents multiple gui elements that have been assembled into a functional component. - * This is primarily for used by the built-in element builders. But could be used in custom builders. - *

- * This is needed because a builder method for an element, cant always return just the relevant element. - * Take the scroll bar for example. - * The builtin scroll bar construction consists of a background element, - * with the scroll bar itself being a child of the background element - * constrained to the background element. - *

- * So the create method for a scroll bar needs to return the background element - * so that you can constrain int appropriately, but it also needs to return the slider element - * so that you can actually use it. That's what this container class is for. - *

- * Created by brandon3055 on 03/09/2023 - */ -public class Assembly, E extends GuiElement> { - /** - * This is the root/container element, Apply any relevant constraints to this element. - */ - public final C container; - /** - * This is the actual primary / functional element. - */ - public final E primary; - /** - * Contains any other elements that are part of this assembly - */ - public final List> parts = new ArrayList<>(); - - public Assembly(C container, E primary) { - this.container = container; - this.primary = primary; - } - - public Assembly addParts(GuiElement... parts) { - this.parts.addAll(Arrays.asList(parts)); - return this; - } - - public GuiElement getPart(int index) { - return parts.get(index); - } -} diff --git a/src/main/java/codechicken/lib/gui/modular/lib/BackgroundRender.java b/src/main/java/codechicken/lib/gui/modular/lib/BackgroundRender.java index 5516a947..0291e8af 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/BackgroundRender.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/BackgroundRender.java @@ -12,7 +12,7 @@ public interface BackgroundRender { /** * Specifies the z depth of the background content. - * After {@link #renderBehind(GuiRender, double, double, float)} is called, the PoseStack will be translated by this amount in the z direction + * After {@link #renderBackground(GuiRender, double, double, float)} is called, the PoseStack will be translated by this amount in the z direction * before any assigned child elements are rendered. * Recommended minimum depth is 0.01 or 0.035 if this element renders text. (text shadows are rendered with a 0.03 offset) * @@ -29,6 +29,6 @@ default double getBackgroundDepth() { * * @param render Contains gui context information as well as essential render methods/utils including the PoseStack. */ - void renderBehind(GuiRender render, double mouseX, double mouseY, float partialTicks); + void renderBackground(GuiRender render, double mouseX, double mouseY, float partialTicks); } diff --git a/src/main/java/codechicken/lib/gui/modular/lib/ColourState.java b/src/main/java/codechicken/lib/gui/modular/lib/ColourState.java index bbd1d8f1..850e0f14 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/ColourState.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/ColourState.java @@ -1,5 +1,8 @@ package codechicken.lib.gui.modular.lib; +import codechicken.lib.colour.Colour; +import codechicken.lib.colour.ColourARGB; + import java.util.Locale; import java.util.function.Consumer; import java.util.function.Supplier; @@ -11,86 +14,14 @@ public interface ColourState { int get(); - void set(int colour); - - default void set(int a, int r, int g, int b) { - set(a << 24 | r << 16 | g << 8 | b); - } - - default void set(int r, int g, int b) { - set(r << 16 | g << 8 | b); - } - - default void set(float a, float r, float g, float b) { - set((int) (a * 255), (int) (r * 255), (int) (g * 255), (int) (b * 255)); - } - - default void set(float r, float g, float b) { - set((int) (r * 255), (int) (g * 255), (int) (b * 255)); - } - - default void setAlpha(int a) { - set(get() & 0x00FFFFFF | a << 24); - } - - default void setRed(int r) { - set(get() & 0xFF00FFFF | r << 16); - } - - default void setGreen(int g) { - set(get() & 0xFFFF00FF | g << 8); + default ColourARGB getColour() { + return new ColourARGB(get()); } - default void setBlue(int b) { - set(get() & 0xFFFFFF00 | b); - } - - default void setAlpha(float a) { - setAlpha((int) (a * 255)); - } - - default void setRed(float r) { - setRed((int) (r * 255)); - } - - default void setGreen(float g) { - setGreen((int) (g * 255)); - } - - default void setBlue(float b) { - setBlue((int) (b * 255)); - } - - default int alphaI() { - return get() >> 24 & 0xFF; - } - - default int redI() { - return get() >> 16 & 0xFF; - } - - default int greenI() { - return get() >> 8 & 0xFF; - } - - default int blueI() { - return get() & 0xFF; - } - - default float alpha() { - return alphaI() / 255F; - } - - default float red() { - return redI() / 255F; - } - - default float green() { - return greenI() / 255F; - } + void set(int colour); - default float blue() { - return blueI() / 255F; + default void set(Colour colour) { + set(colour.argb()); } default String getHexColour() { diff --git a/src/main/java/codechicken/lib/gui/modular/lib/CursorHelper.java b/src/main/java/codechicken/lib/gui/modular/lib/CursorHelper.java index 2836f0c2..4ef4cd96 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/CursorHelper.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/CursorHelper.java @@ -3,10 +3,14 @@ import codechicken.lib.CodeChickenLib; import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.Resource; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.Nullable; import org.lwjgl.BufferUtils; import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFWImage; +import org.lwjgl.system.MemoryUtil; import javax.imageio.ImageIO; import java.awt.*; @@ -14,22 +18,32 @@ import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; +import java.util.Optional; /** * Created by brandon3055 on 11/5/20. */ public class CursorHelper { + public static final Logger LOGGER = LogManager.getLogger(); - private static Map cursors = new HashMap<>(); + public static final ResourceLocation DRAG = new ResourceLocation(CodeChickenLib.MOD_ID, "textures/gui/cursors/drag.png"); + public static final ResourceLocation RESIZE_H = new ResourceLocation(CodeChickenLib.MOD_ID, "textures/gui/cursors/resize_h.png"); + public static final ResourceLocation RESIZE_V = new ResourceLocation(CodeChickenLib.MOD_ID, "textures/gui/cursors/resize_v.png"); + public static final ResourceLocation RESIZE_TRBL = new ResourceLocation(CodeChickenLib.MOD_ID, "textures/gui/cursors/resize_diag_trbl.png"); + public static final ResourceLocation RESIZE_TLBR = new ResourceLocation(CodeChickenLib.MOD_ID, "textures/gui/cursors/resize_diag_tlbr.png"); + + private static final Map cursors = new HashMap<>(); private static ResourceLocation active = null; - private static long createCursor(ResourceLocation resource) { + private static long createCursor(ResourceLocation cursorTexture) { try { - BufferedImage bufferedimage = ImageIO.read(Minecraft.getInstance().getResourceManager().getResource(resource).get().open()); + Resource resource = Minecraft.getInstance().getResourceManager().getResource(cursorTexture).orElse(null); + if (resource == null) return MemoryUtil.NULL; + BufferedImage bufferedimage = ImageIO.read(resource.open()); GLFWImage glfwImage = imageToGLFWImage(bufferedimage); return GLFW.glfwCreateCursor(glfwImage, 16, 16); } catch (Exception e) { - e.printStackTrace(); + LOGGER.warn("An error occurred while creating cursor", e); } return 0; } @@ -65,12 +79,7 @@ public static void setCursor(@Nullable ResourceLocation cursor) { active = cursor; long window = Minecraft.getInstance().getWindow().getWindow(); long newCursor = active == null ? 0 : cursors.computeIfAbsent(cursor, CursorHelper::createCursor); - try { - GLFW.glfwSetCursor(window, newCursor); - } - catch (Throwable e) { - e.printStackTrace(); - } + GLFW.glfwSetCursor(window, newCursor); } } @@ -79,4 +88,13 @@ public static void resetCursor() { setCursor(null); } } + + public static void onResourceReload() { + cursors.values().forEach(cursor -> { + if (cursor != MemoryUtil.NULL) { + GLFW.glfwDestroyCursor(cursor); + } + }); + cursors.clear(); + } } \ No newline at end of file diff --git a/src/main/java/codechicken/lib/gui/modular/lib/ForegroundRender.java b/src/main/java/codechicken/lib/gui/modular/lib/ForegroundRender.java index 58aa24d0..76dfcfb3 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/ForegroundRender.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/ForegroundRender.java @@ -28,5 +28,5 @@ default double getForegroundDepth() { * * @param render Contains gui context information as well as essential render methods/utils including the PoseStack. */ - void renderInFront(GuiRender render, double mouseX, double mouseY, float partialTicks); + void renderForeground(GuiRender render, double mouseX, double mouseY, float partialTicks); } diff --git a/src/main/java/codechicken/lib/gui/modular/lib/GuiRender.java b/src/main/java/codechicken/lib/gui/modular/lib/GuiRender.java index 83e61678..a91b7bd8 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/GuiRender.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/GuiRender.java @@ -35,7 +35,6 @@ import net.minecraft.network.chat.HoverEvent; import net.minecraft.network.chat.Style; import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.FastColor.ARGB32; import net.minecraft.util.FormattedCharSequence; import net.minecraft.util.Mth; import net.minecraft.world.entity.LivingEntity; @@ -236,14 +235,14 @@ public void gradientFillV(double xMin, double yMin, double xMax, double yMax, in */ public void gradientFillV(RenderType type, double xMin, double yMin, double xMax, double yMax, int topColour, int bottomColour) { VertexConsumer buffer = buffers().getBuffer(type); - float sA = (float) ARGB32.alpha(topColour) / 255.0F; - float sR = (float) ARGB32.red(topColour) / 255.0F; - float sG = (float) ARGB32.green(topColour) / 255.0F; - float sB = (float) ARGB32.blue(topColour) / 255.0F; - float eA = (float) ARGB32.alpha(bottomColour) / 255.0F; - float eR = (float) ARGB32.red(bottomColour) / 255.0F; - float eG = (float) ARGB32.green(bottomColour) / 255.0F; - float eB = (float) ARGB32.blue(bottomColour) / 255.0F; + float sA = a(topColour) / 255.0F; + float sR = r(topColour) / 255.0F; + float sG = g(topColour) / 255.0F; + float sB = b(topColour) / 255.0F; + float eA = a(bottomColour) / 255.0F; + float eR = r(bottomColour) / 255.0F; + float eG = g(bottomColour) / 255.0F; + float eB = b(bottomColour) / 255.0F; Matrix4f mat = pose.last().pose(); buffer.vertex(mat, (float) xMax, (float) yMax, 0).color(eR, eG, eB, eA).endVertex(); //R-B buffer.vertex(mat, (float) xMax, (float) yMin, 0).color(sR, sG, sB, sA).endVertex(); //R-T @@ -264,14 +263,14 @@ public void gradientFillH(double xMin, double yMin, double xMax, double yMax, in */ public void gradientFillH(RenderType type, double xMin, double yMin, double xMax, double yMax, int leftColour, int rightColour) { VertexConsumer buffer = buffers().getBuffer(type); - float sA = (float) ARGB32.alpha(leftColour) / 255.0F; - float sR = (float) ARGB32.red(leftColour) / 255.0F; - float sG = (float) ARGB32.green(leftColour) / 255.0F; - float sB = (float) ARGB32.blue(leftColour) / 255.0F; - float eA = (float) ARGB32.alpha(rightColour) / 255.0F; - float eR = (float) ARGB32.red(rightColour) / 255.0F; - float eG = (float) ARGB32.green(rightColour) / 255.0F; - float eB = (float) ARGB32.blue(rightColour) / 255.0F; + float sA = a(leftColour) / 255.0F; + float sR = r(leftColour) / 255.0F; + float sG = g(leftColour) / 255.0F; + float sB = b(leftColour) / 255.0F; + float eA = a(rightColour) / 255.0F; + float eR = r(rightColour) / 255.0F; + float eG = g(rightColour) / 255.0F; + float eB = b(rightColour) / 255.0F; Matrix4f mat = pose.last().pose(); buffer.vertex(mat, (float) xMax, (float) yMax, 0).color(eR, eG, eB, eA).endVertex(); //R-B buffer.vertex(mat, (float) xMax, (float) yMin, 0).color(eR, eG, eB, eA).endVertex(); //R-T @@ -1076,8 +1075,6 @@ public void dynamicTex(Material material, int x, int y, int width, int height, i } //Todo, This method can probably be made a lot more efficient. - // Also thinking a about a data generator to automatically stitch together these textures so there is no need to generate them dynamically. - // That would be a lot more efficient and more compatible with custom resource packs. private void dynamicTexInternal(Material material, int xPos, int yPos, int xSize, int ySize, int topBorder, int leftBorder, int bottomBorder, int rightBorder, float red, float green, float blue, float alpha) { TextureAtlasSprite sprite = material.sprite(); VertexConsumer buffer = material.buffer(buffers, GuiRender::texColType); @@ -1662,22 +1659,19 @@ public static int midColour(int colour1, int colour2) { } private static float r(int argb) { - return ARGB32.red(argb) / 255F; + return (argb >> 16 & 255) / 255F; } private static float g(int argb) { - return ARGB32.green(argb) / 255F; - + return (argb >> 8 & 255) / 255F; } private static float b(int argb) { - return ARGB32.blue(argb) / 255F; - + return (argb & 255) / 255F; } private static float a(int argb) { - return ARGB32.alpha(argb) / 255F; - + return (argb >>> 24) / 255F; } //Render Type Builders diff --git a/src/main/java/codechicken/lib/gui/modular/lib/SliderState.java b/src/main/java/codechicken/lib/gui/modular/lib/SliderState.java index c59c46ea..a9724798 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/SliderState.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/SliderState.java @@ -2,6 +2,7 @@ import codechicken.lib.gui.modular.lib.geometry.Axis; import net.minecraft.client.gui.screens.Screen; +import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; import java.util.function.Supplier; @@ -60,24 +61,7 @@ default boolean canScroll(Axis scrollAxis) { * Useful for things like simple slide control elements. */ static SliderState create(double speed) { - return new SliderState() { - double pos = 0; - - @Override - public double getPos() { - return pos; - } - - @Override - public void setPos(double pos) { - this.pos = pos; - } - - @Override - public double scrollSpeed() { - return speed; - } - }; + return create(speed, null); } /** @@ -85,7 +69,7 @@ public double scrollSpeed() { * And allows you to attach a change listener. * Useful for things like simple slide control elements. */ - static SliderState create(double speed, Consumer changeListener) { + static SliderState create(double speed, @Nullable Consumer changeListener) { return new SliderState() { double pos = 0; @@ -97,7 +81,9 @@ public double getPos() { @Override public void setPos(double pos) { this.pos = pos; - changeListener.accept(pos); + if (changeListener != null) { + changeListener.accept(pos); + } } @Override diff --git a/src/main/java/codechicken/lib/gui/modular/lib/TextState.java b/src/main/java/codechicken/lib/gui/modular/lib/TextState.java index ef9b9be5..f92af296 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/TextState.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/TextState.java @@ -1,6 +1,7 @@ package codechicken.lib.gui.modular.lib; import codechicken.lib.gui.modular.elements.GuiTextField; +import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; import java.util.function.Supplier; @@ -17,22 +18,10 @@ public interface TextState { void setText(String text); static TextState simpleState(String defaultValue) { - return new TextState() { - private String value = defaultValue; - - @Override - public String getText() { - return value; - } - - @Override - public void setText(String text) { - this.value = text; - } - }; + return simpleState(defaultValue, null); } - static TextState simpleState(String defaultValue, Consumer changeListener) { + static TextState simpleState(String defaultValue, @Nullable Consumer changeListener) { return new TextState() { private String value = defaultValue; @@ -44,7 +33,9 @@ public String getText() { @Override public void setText(String text) { this.value = text; - changeListener.accept(value); + if (changeListener != null) { + changeListener.accept(value); + } } }; } diff --git a/src/main/java/codechicken/lib/gui/modular/lib/ToolTipHandler.java b/src/main/java/codechicken/lib/gui/modular/lib/TooltipHandler.java similarity index 96% rename from src/main/java/codechicken/lib/gui/modular/lib/ToolTipHandler.java rename to src/main/java/codechicken/lib/gui/modular/lib/TooltipHandler.java index b0107b21..7bc1bb20 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/ToolTipHandler.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/TooltipHandler.java @@ -1,6 +1,7 @@ package codechicken.lib.gui.modular.lib; import codechicken.lib.gui.modular.elements.GuiElement; +import net.covers1624.quack.util.SneakyUtils; import net.minecraft.network.chat.Component; import org.jetbrains.annotations.Nullable; @@ -11,7 +12,7 @@ /** * Created by brandon3055 on 01/09/2023 */ -public interface ToolTipHandler> { +public interface TooltipHandler> { Supplier> getTooltip(); @@ -86,7 +87,7 @@ default T setTooltip(@Nullable List tooltip) { default T setTooltip(@Nullable Supplier> tooltip, int tooltipDelay) { setTooltip(tooltip); setTooltipDelay(tooltipDelay); - return (T) this; + return SneakyUtils.unsafeCast(this); } /** diff --git a/src/main/java/codechicken/lib/gui/modular/lib/container/DataSync.java b/src/main/java/codechicken/lib/gui/modular/lib/container/DataSync.java index c126b077..7355bdce 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/container/DataSync.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/container/DataSync.java @@ -1,8 +1,8 @@ package codechicken.lib.gui.modular.lib.container; -import codechicken.lib.gui.modular.lib.container.data.AbstractDataStore; +import codechicken.lib.data.MCDataInput; +import codechicken.lib.inventory.container.data.AbstractDataStore; import codechicken.lib.inventory.container.modular.ModularGuiContainerMenu; -import net.minecraft.network.FriendlyByteBuf; import java.util.function.Supplier; @@ -42,7 +42,7 @@ public void detectAndSend() { }); } - public void handleSyncPacket(FriendlyByteBuf buf) { + public void handleSyncPacket(MCDataInput buf) { dataStore.fromBytes(buf); } } diff --git a/src/main/java/codechicken/lib/gui/modular/lib/geometry/Borders.java b/src/main/java/codechicken/lib/gui/modular/lib/geometry/Borders.java index 073b9d5d..d9ef9ce7 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/geometry/Borders.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/geometry/Borders.java @@ -6,10 +6,10 @@ * Created by brandon3055 on 28/08/2023 */ public final class Borders { - private double top; - private double left; - private double bottom; - private double right; + public double top; + public double left; + public double bottom; + public double right; public Borders(double top, double left, double bottom, double right) { this.top = top; @@ -46,32 +46,32 @@ public double right() { return right; } - public Borders setTop(double top) { + public Borders top(double top) { this.top = top; return this; } - public Borders setLeft(double left) { + public Borders left(double left) { this.left = left; return this; } - public Borders setBottom(double bottom) { + public Borders bottom(double bottom) { this.bottom = bottom; return this; } - public Borders setRight(double right) { + public Borders right(double right) { this.right = right; return this; } public Borders setTopBottom(double topBottom) { - return setTop(topBottom).setBottom(topBottom); + return top(topBottom).bottom(topBottom); } public Borders setLeftRight(double leftRight) { - return setLeft(leftRight).setLeftRight(leftRight); + return left(leftRight).setLeftRight(leftRight); } public Borders setBorders(double borders) { diff --git a/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstrainedGeometry.java b/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstrainedGeometry.java index d633775f..b0c62353 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstrainedGeometry.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstrainedGeometry.java @@ -54,8 +54,9 @@ public abstract class ConstrainedGeometry> impl private AxisConfig yAxis = AxisConfig.NONE; //Permanently bound immutable position and rectangle elements. - private Position position = Position.create(this); - private Rectangle rectangle = Rectangle.create(this); + private final Position position = Position.create(this); + private final Rectangle rectangle = Rectangle.create(this); + private final Rectangle.Mutable childBounds = getRectangle().mutable(); private boolean strictMode = false; @@ -212,30 +213,6 @@ public GeoRef get(GeoParam param) { return new GeoRef(this, param); } - /** - * @param param The geometry parameter. - * @return The current value of the specified parameter. - */ - @Override - public double getValue(GeoParam param) { - switch (param) { - case LEFT: - return xMin(); - case RIGHT: - return xMax(); - case WIDTH: - return xSize(); - case TOP: - return yMin(); - case BOTTOM: - return yMax(); - case HEIGHT: - return ySize(); - default: - throw new IllegalStateException("Param: \"" + param + "\" Shouldn't Exist! Someone has broken my code! Go yell at them!"); - } - } - /** * @param param The geometry parameter to be constrained. * @param constraint The constraint to apply @@ -377,8 +354,6 @@ public Rectangle.Mutable addBoundsToRect(Rectangle.Mutable enclosingRect) { return enclosingRect; } - private Rectangle.Mutable childBounds = getRectangle().mutable(); - /** * @return a rectangle, the bounds of which enclose all enabled child elements. * If there are no enabled child elements the returned rect will have the position of this element, with zero size. diff --git a/src/main/java/codechicken/lib/gui/modular/lib/geometry/Constraint.java b/src/main/java/codechicken/lib/gui/modular/lib/geometry/Constraint.java index 6b30e8c7..63d80344 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/geometry/Constraint.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/geometry/Constraint.java @@ -16,7 +16,7 @@ * * @see ConstrainedGeometry */ -public interface Constraint { +public sealed interface Constraint permits ConstraintImpl { /** * This method will return the current value of this constraint. @@ -151,10 +151,4 @@ static ConstraintImpl.MidPoint midPoint(GeoRef start, GeoRef end, double offset) static ConstraintImpl.MidPointDynamic midPoint(GeoRef start, GeoRef end, Supplier offset) { return new ConstraintImpl.MidPointDynamic(start, end, offset); } - - //TODO - // Between with offset - // Will att more as i start to use this system and figure out whats needed. - // - } diff --git a/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstraintImpl.java b/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstraintImpl.java index eab280ea..646abe93 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstraintImpl.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstraintImpl.java @@ -8,7 +8,7 @@ /** * Created by brandon3055 on 04/07/2023 */ -public abstract class ConstraintImpl> implements Constraint { +public abstract non-sealed class ConstraintImpl> implements Constraint { protected boolean precise = false; protected Axis axis = null; diff --git a/src/main/java/codechicken/lib/gui/modular/lib/geometry/Direction.java b/src/main/java/codechicken/lib/gui/modular/lib/geometry/Direction.java index d8e5ce9e..9e2513e8 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/geometry/Direction.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/geometry/Direction.java @@ -9,6 +9,8 @@ public enum Direction { DOWN(Axis.Y), RIGHT(Axis.X); + private static Direction[] VALUES = values(); + private final Axis axis; Direction(Axis axis) { @@ -25,11 +27,11 @@ public Direction opposite() { } public Direction rotateCW() { - return values()[(ordinal() + values().length - 1) % values().length]; + return values()[(ordinal() + VALUES.length - 1) % VALUES.length]; } public Direction rotateCCW() { - return values()[(ordinal() + 1) % values().length]; + return values()[(ordinal() + 1) % VALUES.length]; } public double rotationTo(Direction other) { diff --git a/src/main/java/codechicken/lib/gui/modular/lib/geometry/GuiParent.java b/src/main/java/codechicken/lib/gui/modular/lib/geometry/GuiParent.java index e5348e9b..9a2b8d77 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/geometry/GuiParent.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/geometry/GuiParent.java @@ -1,10 +1,10 @@ package codechicken.lib.gui.modular.lib.geometry; -import com.google.common.annotations.Beta; import codechicken.lib.gui.modular.ModularGui; import codechicken.lib.gui.modular.elements.GuiElement; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; +import org.jetbrains.annotations.ApiStatus; import java.util.List; import java.util.function.Consumer; @@ -70,22 +70,14 @@ default GeoRef get(GeoParam param) { * @return The current value of the specified parameter. */ default double getValue(GeoParam param) { - switch (param) { - case LEFT: - return xMin(); - case RIGHT: - return xMax(); - case WIDTH: - return xSize(); - case TOP: - return yMin(); - case BOTTOM: - return yMax(); - case HEIGHT: - return ySize(); - default: - throw new IllegalStateException("Param: \"" + param + "\" Shouldn't Exist! Someone has broken my code! Go yell at them!"); - } + return switch (param) { + case LEFT -> xMin(); + case RIGHT -> xMax(); + case WIDTH -> xSize(); + case TOP -> yMin(); + case BOTTOM -> yMax(); + case HEIGHT -> ySize(); + }; } /** @@ -114,7 +106,7 @@ default double getValue(GeoParam param) { * @param createChild A consumer that is given this element to be used in the construction of the child element. * @return The parent element */ - @Beta + @ApiStatus.Experimental @SuppressWarnings ("unchecked") default T addChild(Consumer createChild) { createChild.accept((T) this); @@ -185,20 +177,6 @@ default void onScreenInit(Minecraft mc, Font font, int screenWidth, int screenHe getChildren().forEach(e -> e.onScreenInit(mc, font, screenWidth, screenHeight)); } - //TODO, May still keep this, but i currently have a different focus system in mind that *may* be better -// /** -// * Not sure how much this will get used, if at all, but allows an element to be specified as the globally focused element. -// * This does not have any effect at all on the base functionality of Modular Gui, it is up to individual elements to choose how they handle focus. -// * -// * @param element the element to be set as the current focused element, or null to clear focused element. -// */ -// void setFocused(@Nullable GuiElement element); -// -// /** -// * @return the current gloabally focused element, or null if no element is focused. -// */ -// @Nullable GuiElement getFocused(); - /** * Allows an element to override the {@link GuiElement#isMouseOver()} method of its children. * This is primarily used for things like scroll elements where mouseover interactions need to be blocked outside the view area. diff --git a/src/main/java/codechicken/lib/gui/modular/lib/geometry/Position.java b/src/main/java/codechicken/lib/gui/modular/lib/geometry/Position.java index 35b55ef6..c6187fbb 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/geometry/Position.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/geometry/Position.java @@ -37,25 +37,7 @@ static Position create(GuiParent parent) { return new Bound(parent); } - record Immutable(double xPos, double yPos) implements Position { - @Override - public double x() { - return xPos; - } - - @Override - public double y() { - return yPos; - } - - @Override - public String toString() { - return "Immutable{" + - "x=" + x() + - ", y=" + y() + - '}'; - } - } + record Immutable(@Override double x, @Override double y) implements Position { } record Bound(GuiParent parent) implements Position { @Override diff --git a/src/main/java/codechicken/lib/gui/modular/sprite/ModAtlasHolder.java b/src/main/java/codechicken/lib/gui/modular/sprite/ModAtlasHolder.java index aebeb8c3..9d361894 100644 --- a/src/main/java/codechicken/lib/gui/modular/sprite/ModAtlasHolder.java +++ b/src/main/java/codechicken/lib/gui/modular/sprite/ModAtlasHolder.java @@ -5,14 +5,18 @@ import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.PackResources; import net.minecraft.server.packs.resources.PreparableReloadListener; +import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.util.profiling.ProfilerFiller; import org.jetbrains.annotations.NotNull; -import java.util.Objects; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.function.Predicate; +import java.util.stream.Stream; /** * Created by brandon3055 on 20/08/2023 @@ -50,12 +54,12 @@ public TextureAtlasSprite getSprite(ResourceLocation resourceLocation) { } @Override - public final @NotNull CompletableFuture reload(PreparationBarrier prepParrier, ResourceManager resourceManager, ProfilerFiller profiler, ProfilerFiller profiler2, Executor executor, Executor executor2) { - Objects.requireNonNull(prepParrier); - SpriteLoader spriteLoader = ModSpriteLoader.create(this.textureAtlas, modid); - return spriteLoader.loadAndStitch(resourceManager, this.atlasInfoLocation, 0, executor) + public final @NotNull CompletableFuture reload(PreparationBarrier prepBarrier, ResourceManager resourceManager, ProfilerFiller profiler, ProfilerFiller profiler2, Executor executor, Executor executor2) { + Objects.requireNonNull(prepBarrier); + SpriteLoader spriteLoader = SpriteLoader.create(this.textureAtlas); + return spriteLoader.loadAndStitch(new ModResourceManager(resourceManager, modid), this.atlasInfoLocation, 0, executor) .thenCompose(SpriteLoader.Preparations::waitForUpload) - .thenCompose(prepParrier::wait) + .thenCompose(prepBarrier::wait) .thenAcceptAsync((preparations) -> this.apply(preparations, profiler2), executor2); } @@ -71,4 +75,27 @@ private void apply(SpriteLoader.Preparations preparations, ProfilerFiller profil public void close() { this.textureAtlas.clearTextureData(); } + + public static class ModResourceManager implements ResourceManager { + private final ResourceManager wrapped; + private final String modid; + + public ModResourceManager(ResourceManager wrapped, String modid) { + this.wrapped = wrapped; + this.modid = modid; + } + + @Override + public Map listResources(String pPath, Predicate pFilter) { + return wrapped.listResources(pPath, pFilter.and(e -> e.getNamespace().equals(modid))); + } + + //@formatter:off + @Override public Set getNamespaces() { return wrapped.getNamespaces(); } + @Override public List getResourceStack(ResourceLocation pLocation) { return wrapped.getResourceStack(pLocation); } + @Override public Map> listResourceStacks(String pPath, Predicate pFilter) { return wrapped.listResourceStacks(pPath, pFilter); } + @Override public Stream listPacks() { return wrapped.listPacks(); } + @Override public Optional getResource(ResourceLocation pLocation) { return wrapped.getResource(pLocation); } + //@formatter:on + } } diff --git a/src/main/java/codechicken/lib/gui/modular/sprite/ModSpriteLoader.java b/src/main/java/codechicken/lib/gui/modular/sprite/ModSpriteLoader.java deleted file mode 100644 index fcfe0a2f..00000000 --- a/src/main/java/codechicken/lib/gui/modular/sprite/ModSpriteLoader.java +++ /dev/null @@ -1,38 +0,0 @@ -package codechicken.lib.gui.modular.sprite; - -import net.minecraft.client.renderer.texture.SpriteLoader; -import net.minecraft.client.renderer.texture.TextureAtlas; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; - -/** - * Custom sprite loader that allows filtering of resources based on mod id. - *

- * Created by brandon3055 on 21/08/2023 - */ -public class ModSpriteLoader extends SpriteLoader { - private final String modid; - - public ModSpriteLoader(ResourceLocation resourceLocation, int i, int j, int k, String modid) { - super(resourceLocation, i, j, k); - this.modid = modid; - } - - public static SpriteLoader create(TextureAtlas textureAtlas, String modid) { - return new ModSpriteLoader(textureAtlas.location(), textureAtlas.maxSupportedTextureSize(), textureAtlas.getWidth(), textureAtlas.getHeight(), modid); - } - - @Override - public CompletableFuture loadAndStitch(ResourceManager resourceManager, ResourceLocation resourceLocation, int i, Executor executor) { - return CompletableFuture.supplyAsync(() -> { - return ModSpriteResourceLoader.load(resourceManager, resourceLocation, modid).list(resourceManager); - }, executor).thenCompose((list) -> { - return runSpriteSuppliers(list, executor); - }).thenApply((list) -> { - return this.stitch(list, i, executor); - }); - } -} diff --git a/src/main/java/codechicken/lib/gui/modular/sprite/ModSpriteResourceLoader.java b/src/main/java/codechicken/lib/gui/modular/sprite/ModSpriteResourceLoader.java deleted file mode 100644 index 0bdef65a..00000000 --- a/src/main/java/codechicken/lib/gui/modular/sprite/ModSpriteResourceLoader.java +++ /dev/null @@ -1,110 +0,0 @@ -package codechicken.lib.gui.modular.sprite; - -import com.google.common.collect.ImmutableList; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import com.mojang.logging.LogUtils; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.Dynamic; -import com.mojang.serialization.JsonOps; -import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; -import net.minecraft.client.renderer.texture.SpriteContents; -import net.minecraft.client.renderer.texture.atlas.SpriteSource; -import net.minecraft.client.renderer.texture.atlas.SpriteSources; -import net.minecraft.resources.FileToIdConverter; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.Resource; -import net.minecraft.server.packs.resources.ResourceManager; -import org.slf4j.Logger; - -import java.io.BufferedReader; -import java.util.*; -import java.util.function.Predicate; -import java.util.function.Supplier; - -/** - * Custom sprite resource loader that allows filtering of resources based on mod id. - *

- * Created by brandon3055 on 21/08/2023 - */ -public class ModSpriteResourceLoader { - private static final Logger LOGGER = LogUtils.getLogger(); - private static final FileToIdConverter ATLAS_INFO_CONVERTER = new FileToIdConverter("atlases", ".json"); - private final List sources; - private final String modid; - - private ModSpriteResourceLoader(List list, String modid) { - this.sources = list; - this.modid = modid; - } - - public List> list(ResourceManager arg) { - final Map map = new HashMap(); - SpriteSource.Output output = new SpriteSource.Output() { - public void add(ResourceLocation location, SpriteSource.SpriteSupplier arg2) { - if (location.getNamespace().equals(modid)) { - SpriteSource.SpriteSupplier spriteSupplier = map.put(location, arg2); - if (spriteSupplier != null) { - spriteSupplier.discard(); - } - } - } - - public void removeAll(Predicate predicate) { - Iterator> iterator = map.entrySet().iterator(); - - while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - if (predicate.test(entry.getKey())) { - entry.getValue().discard(); - iterator.remove(); - } - } - - } - }; - this.sources.forEach((arg3) -> arg3.run(arg, output)); - - ImmutableList.Builder> builder = ImmutableList.builder(); - builder.add(MissingTextureAtlasSprite::create); - builder.addAll(map.values()); - return builder.build(); - } - - public static ModSpriteResourceLoader load(ResourceManager arg, ResourceLocation arg2, String modid) { - ResourceLocation resourceLocation = ATLAS_INFO_CONVERTER.idToFile(arg2); - List list = new ArrayList<>(); - - for (Resource resource : arg.getResourceStack(resourceLocation)) { - try { - BufferedReader bufferedReader = resource.openAsReader(); - - try { - Dynamic dynamic = new Dynamic<>(JsonOps.INSTANCE, JsonParser.parseReader(bufferedReader)); - DataResult> var10001 = SpriteSources.FILE_CODEC.parse(dynamic); - Logger var10003 = LOGGER; - Objects.requireNonNull(var10003); - list.addAll(var10001.getOrThrow(false, var10003::error)); - } catch (Throwable var10) { - if (bufferedReader != null) { - try { - bufferedReader.close(); - } catch (Throwable var9) { - var10.addSuppressed(var9); - } - } - - throw var10; - } - - if (bufferedReader != null) { - bufferedReader.close(); - } - } catch (Exception var11) { - LOGGER.warn("Failed to parse atlas definition {} in pack {}", resourceLocation, resource.sourcePackId(), var11); - } - } - - return new ModSpriteResourceLoader(list, modid); - } -} diff --git a/src/main/java/codechicken/lib/internal/ClientInit.java b/src/main/java/codechicken/lib/internal/ClientInit.java index a0186ba8..e3414e88 100644 --- a/src/main/java/codechicken/lib/internal/ClientInit.java +++ b/src/main/java/codechicken/lib/internal/ClientInit.java @@ -3,6 +3,8 @@ import codechicken.lib.CodeChickenLib; import codechicken.lib.config.ConfigCategory; import codechicken.lib.config.ConfigSyncManager; +import codechicken.lib.gui.modular.lib.CursorHelper; +import codechicken.lib.gui.modular.sprite.CCGuiTextures; import codechicken.lib.model.CompositeItemModel; import codechicken.lib.model.ClassModelLoader; import codechicken.lib.render.CCRenderEventHandler; @@ -10,6 +12,7 @@ import net.covers1624.quack.util.CrashLock; import net.minecraftforge.client.event.ClientPlayerNetworkEvent; import net.minecraftforge.client.event.ModelEvent; +import net.minecraftforge.client.event.RegisterClientReloadListenersEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; @@ -36,6 +39,7 @@ public static void init() { bus.addListener(ClientInit::onClientSetup); bus.addListener(ClientInit::onRegisterGeometryLoaders); + bus.addListener(ClientInit::onResourceReload); } private static void onClientSetup(FMLClientSetupEvent event) { @@ -74,4 +78,9 @@ private static void onRegisterGeometryLoaders(ModelEvent.RegisterGeometryLoaders event.register("item_composite", new CompositeItemModel()); event.register("class", new ClassModelLoader()); } + + public static void onResourceReload(RegisterClientReloadListenersEvent event) { + event.registerReloadListener(CCGuiTextures.getAtlasHolder()); + CursorHelper.onResourceReload(); + } } diff --git a/src/main/java/codechicken/lib/internal/network/CCLNetwork.java b/src/main/java/codechicken/lib/internal/network/CCLNetwork.java index 99b73ea5..5fbd194b 100644 --- a/src/main/java/codechicken/lib/internal/network/CCLNetwork.java +++ b/src/main/java/codechicken/lib/internal/network/CCLNetwork.java @@ -15,6 +15,10 @@ public class CCLNetwork { //Client handled. public static final int C_ADD_LANDING_EFFECTS = 1; public static final int C_OPEN_CONTAINER = 10; + public static final int C_GUI_SYNC = 11; + + //Server handled. + public static final int S_GUI_SYNC = 1; //Login handled. public static final int L_CONFIG_SYNC = 1; @@ -22,8 +26,8 @@ public class CCLNetwork { public static void init() { netChannel = PacketCustomChannelBuilder.named(NET_CHANNEL)// .assignClientHandler(() -> ClientPacketHandler::new)// + .assignServerHandler(() -> ServerPacketHandler::new)// .assignLoginHandler(() -> LoginPacketHandler::new)// .build(); } - } diff --git a/src/main/java/codechicken/lib/internal/network/ClientPacketHandler.java b/src/main/java/codechicken/lib/internal/network/ClientPacketHandler.java index 8f7dd554..32bccf89 100644 --- a/src/main/java/codechicken/lib/internal/network/ClientPacketHandler.java +++ b/src/main/java/codechicken/lib/internal/network/ClientPacketHandler.java @@ -1,6 +1,7 @@ package codechicken.lib.internal.network; import codechicken.lib.inventory.container.ICCLContainerType; +import codechicken.lib.inventory.container.modular.ModularGuiContainerMenu; import codechicken.lib.packet.ICustomPacketHandler.IClientPacketHandler; import codechicken.lib.packet.PacketCustom; import codechicken.lib.render.particle.CustomParticleHandler; @@ -17,8 +18,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.registries.ForgeRegistries; -import static codechicken.lib.internal.network.CCLNetwork.C_ADD_LANDING_EFFECTS; -import static codechicken.lib.internal.network.CCLNetwork.C_OPEN_CONTAINER; +import static codechicken.lib.internal.network.CCLNetwork.*; /** * Created by covers1624 on 14/07/2017. @@ -36,6 +36,7 @@ public void handlePacket(PacketCustom packet, Minecraft mc, ClientPacketListener CustomParticleHandler.addLandingEffects(mc.level, pos, state, vec, numParticles); } case C_OPEN_CONTAINER -> handleOpenContainer(packet, mc); + case C_GUI_SYNC -> ModularGuiContainerMenu.handlePacketFromServer(mc.player, packet); } } diff --git a/src/main/java/codechicken/lib/internal/network/ServerPacketHandler.java b/src/main/java/codechicken/lib/internal/network/ServerPacketHandler.java new file mode 100644 index 00000000..4edab263 --- /dev/null +++ b/src/main/java/codechicken/lib/internal/network/ServerPacketHandler.java @@ -0,0 +1,22 @@ +package codechicken.lib.internal.network; + +import codechicken.lib.inventory.container.modular.ModularGuiContainerMenu; +import codechicken.lib.packet.ICustomPacketHandler.IServerPacketHandler; +import codechicken.lib.packet.PacketCustom; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; + +import static codechicken.lib.internal.network.CCLNetwork.S_GUI_SYNC; + +/** + * Created by covers1624 on 14/07/2017. + */ +public class ServerPacketHandler implements IServerPacketHandler { + + @Override + public void handlePacket(PacketCustom packet, ServerPlayer sender, ServerGamePacketListenerImpl handler) { + switch (packet.getType()) { + case S_GUI_SYNC -> ModularGuiContainerMenu.handlePacketFromClient(sender, packet); + } + } +} diff --git a/src/main/java/codechicken/lib/gui/modular/lib/container/data/AbstractDataStore.java b/src/main/java/codechicken/lib/inventory/container/data/AbstractDataStore.java similarity index 75% rename from src/main/java/codechicken/lib/gui/modular/lib/container/data/AbstractDataStore.java rename to src/main/java/codechicken/lib/inventory/container/data/AbstractDataStore.java index 3e895821..6120027d 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/container/data/AbstractDataStore.java +++ b/src/main/java/codechicken/lib/inventory/container/data/AbstractDataStore.java @@ -1,5 +1,7 @@ -package codechicken.lib.gui.modular.lib.container.data; +package codechicken.lib.inventory.container.data; +import codechicken.lib.data.MCDataInput; +import codechicken.lib.data.MCDataOutput; import net.minecraft.nbt.Tag; import net.minecraft.network.FriendlyByteBuf; @@ -10,7 +12,6 @@ * * Created by brandon3055 on 08/09/2023 */ -@Deprecated //Not sure if this will stay in CCL public abstract class AbstractDataStore { protected T value; @@ -30,9 +31,9 @@ public void setValue(T value) { public void markDirty(){} - public abstract void toBytes(FriendlyByteBuf buf); + public abstract void toBytes(MCDataOutput buf); - public abstract void fromBytes(FriendlyByteBuf buf); + public abstract void fromBytes(MCDataInput buf); public abstract Tag toTag(); diff --git a/src/main/java/codechicken/lib/gui/modular/lib/container/data/BooleanData.java b/src/main/java/codechicken/lib/inventory/container/data/BooleanData.java similarity index 76% rename from src/main/java/codechicken/lib/gui/modular/lib/container/data/BooleanData.java rename to src/main/java/codechicken/lib/inventory/container/data/BooleanData.java index 072ab113..23bc32c0 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/container/data/BooleanData.java +++ b/src/main/java/codechicken/lib/inventory/container/data/BooleanData.java @@ -1,5 +1,7 @@ -package codechicken.lib.gui.modular.lib.container.data; +package codechicken.lib.inventory.container.data; +import codechicken.lib.data.MCDataInput; +import codechicken.lib.data.MCDataOutput; import net.minecraft.nbt.ByteTag; import net.minecraft.nbt.NumericTag; import net.minecraft.nbt.Tag; @@ -8,7 +10,6 @@ /** * Created by brandon3055 on 09/09/2023 */ -@Deprecated //Not sure if this will stay in CCL public class BooleanData extends AbstractDataStore { public BooleanData() { @@ -20,12 +21,12 @@ public BooleanData(boolean defaultValue) { } @Override - public void toBytes(FriendlyByteBuf buf) { + public void toBytes(MCDataOutput buf) { buf.writeBoolean(value); } @Override - public void fromBytes(FriendlyByteBuf buf) { + public void fromBytes(MCDataInput buf) { value = buf.readBoolean(); } diff --git a/src/main/java/codechicken/lib/gui/modular/lib/container/data/ByteData.java b/src/main/java/codechicken/lib/inventory/container/data/ByteData.java similarity index 75% rename from src/main/java/codechicken/lib/gui/modular/lib/container/data/ByteData.java rename to src/main/java/codechicken/lib/inventory/container/data/ByteData.java index b7b93f65..c438282e 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/container/data/ByteData.java +++ b/src/main/java/codechicken/lib/inventory/container/data/ByteData.java @@ -1,5 +1,7 @@ -package codechicken.lib.gui.modular.lib.container.data; +package codechicken.lib.inventory.container.data; +import codechicken.lib.data.MCDataInput; +import codechicken.lib.data.MCDataOutput; import net.minecraft.nbt.ByteTag; import net.minecraft.nbt.NumericTag; import net.minecraft.nbt.Tag; @@ -8,7 +10,6 @@ /** * Created by brandon3055 on 09/09/2023 */ -@Deprecated //Not sure if this will stay in CCL public class ByteData extends AbstractDataStore { public ByteData() { @@ -20,12 +21,12 @@ public ByteData(byte defaultValue) { } @Override - public void toBytes(FriendlyByteBuf buf) { + public void toBytes(MCDataOutput buf) { buf.writeByte(value); } @Override - public void fromBytes(FriendlyByteBuf buf) { + public void fromBytes(MCDataInput buf) { value = buf.readByte(); } diff --git a/src/main/java/codechicken/lib/gui/modular/lib/container/data/DoubleData.java b/src/main/java/codechicken/lib/inventory/container/data/DoubleData.java similarity index 75% rename from src/main/java/codechicken/lib/gui/modular/lib/container/data/DoubleData.java rename to src/main/java/codechicken/lib/inventory/container/data/DoubleData.java index befd2f0d..990f9475 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/container/data/DoubleData.java +++ b/src/main/java/codechicken/lib/inventory/container/data/DoubleData.java @@ -1,5 +1,7 @@ -package codechicken.lib.gui.modular.lib.container.data; +package codechicken.lib.inventory.container.data; +import codechicken.lib.data.MCDataInput; +import codechicken.lib.data.MCDataOutput; import net.minecraft.nbt.DoubleTag; import net.minecraft.nbt.NumericTag; import net.minecraft.nbt.Tag; @@ -8,7 +10,6 @@ /** * Created by brandon3055 on 09/09/2023 */ -@Deprecated //Not sure if this will stay in CCL public class DoubleData extends AbstractDataStore { public DoubleData() { @@ -20,12 +21,12 @@ public DoubleData(double defaultValue) { } @Override - public void toBytes(FriendlyByteBuf buf) { + public void toBytes(MCDataOutput buf) { buf.writeDouble(value); } @Override - public void fromBytes(FriendlyByteBuf buf) { + public void fromBytes(MCDataInput buf) { value = buf.readDouble(); } diff --git a/src/main/java/codechicken/lib/gui/modular/lib/container/data/FloatData.java b/src/main/java/codechicken/lib/inventory/container/data/FloatData.java similarity index 75% rename from src/main/java/codechicken/lib/gui/modular/lib/container/data/FloatData.java rename to src/main/java/codechicken/lib/inventory/container/data/FloatData.java index d0adf0c1..6a135bca 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/container/data/FloatData.java +++ b/src/main/java/codechicken/lib/inventory/container/data/FloatData.java @@ -1,5 +1,7 @@ -package codechicken.lib.gui.modular.lib.container.data; +package codechicken.lib.inventory.container.data; +import codechicken.lib.data.MCDataInput; +import codechicken.lib.data.MCDataOutput; import net.minecraft.nbt.FloatTag; import net.minecraft.nbt.NumericTag; import net.minecraft.nbt.Tag; @@ -8,7 +10,6 @@ /** * Created by brandon3055 on 09/09/2023 */ -@Deprecated //Not sure if this will stay in CCL public class FloatData extends AbstractDataStore { public FloatData() { @@ -20,12 +21,12 @@ public FloatData(float defaultValue) { } @Override - public void toBytes(FriendlyByteBuf buf) { + public void toBytes(MCDataOutput buf) { buf.writeFloat(value); } @Override - public void fromBytes(FriendlyByteBuf buf) { + public void fromBytes(MCDataInput buf) { value = buf.readFloat(); } diff --git a/src/main/java/codechicken/lib/gui/modular/lib/container/data/FluidData.java b/src/main/java/codechicken/lib/inventory/container/data/FluidData.java similarity index 75% rename from src/main/java/codechicken/lib/gui/modular/lib/container/data/FluidData.java rename to src/main/java/codechicken/lib/inventory/container/data/FluidData.java index 4981b29a..62288a63 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/container/data/FluidData.java +++ b/src/main/java/codechicken/lib/inventory/container/data/FluidData.java @@ -1,5 +1,7 @@ -package codechicken.lib.gui.modular.lib.container.data; +package codechicken.lib.inventory.container.data; +import codechicken.lib.data.MCDataInput; +import codechicken.lib.data.MCDataOutput; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.network.FriendlyByteBuf; @@ -8,7 +10,6 @@ /** * Created by brandon3055 on 09/09/2023 */ -@Deprecated //Not sure if this will stay in CCL public class FluidData extends AbstractDataStore { public FluidData() { @@ -26,13 +27,13 @@ public void setValue(FluidStack value) { } @Override - public void toBytes(FriendlyByteBuf buf) { - value.writeToPacket(buf); + public void toBytes(MCDataOutput buf) { + buf.writeFluidStack(value); } @Override - public void fromBytes(FriendlyByteBuf buf) { - value = FluidStack.readFromPacket(buf); + public void fromBytes(MCDataInput buf) { + value = buf.readFluidStack(); } @Override diff --git a/src/main/java/codechicken/lib/gui/modular/lib/container/data/IntData.java b/src/main/java/codechicken/lib/inventory/container/data/IntData.java similarity index 75% rename from src/main/java/codechicken/lib/gui/modular/lib/container/data/IntData.java rename to src/main/java/codechicken/lib/inventory/container/data/IntData.java index 195f6175..fe43551a 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/container/data/IntData.java +++ b/src/main/java/codechicken/lib/inventory/container/data/IntData.java @@ -1,5 +1,7 @@ -package codechicken.lib.gui.modular.lib.container.data; +package codechicken.lib.inventory.container.data; +import codechicken.lib.data.MCDataInput; +import codechicken.lib.data.MCDataOutput; import net.minecraft.nbt.IntTag; import net.minecraft.nbt.NumericTag; import net.minecraft.nbt.Tag; @@ -8,7 +10,6 @@ /** * Created by brandon3055 on 09/09/2023 */ -@Deprecated //Not sure if this will stay in CCL public class IntData extends AbstractDataStore { public IntData() { @@ -20,12 +21,12 @@ public IntData(int defaultValue) { } @Override - public void toBytes(FriendlyByteBuf buf) { + public void toBytes(MCDataOutput buf) { buf.writeVarInt(value); } @Override - public void fromBytes(FriendlyByteBuf buf) { + public void fromBytes(MCDataInput buf) { value = buf.readVarInt(); } diff --git a/src/main/java/codechicken/lib/gui/modular/lib/container/data/LongData.java b/src/main/java/codechicken/lib/inventory/container/data/LongData.java similarity index 75% rename from src/main/java/codechicken/lib/gui/modular/lib/container/data/LongData.java rename to src/main/java/codechicken/lib/inventory/container/data/LongData.java index a92a6f80..9b928d9a 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/container/data/LongData.java +++ b/src/main/java/codechicken/lib/inventory/container/data/LongData.java @@ -1,5 +1,7 @@ -package codechicken.lib.gui.modular.lib.container.data; +package codechicken.lib.inventory.container.data; +import codechicken.lib.data.MCDataInput; +import codechicken.lib.data.MCDataOutput; import net.minecraft.nbt.LongTag; import net.minecraft.nbt.NumericTag; import net.minecraft.nbt.Tag; @@ -8,7 +10,6 @@ /** * Created by brandon3055 on 09/09/2023 */ -@Deprecated //Not sure if this will stay in CCL public class LongData extends AbstractDataStore { public LongData() { @@ -20,12 +21,12 @@ public LongData(long defaultValue) { } @Override - public void toBytes(FriendlyByteBuf buf) { + public void toBytes(MCDataOutput buf) { buf.writeVarLong(value); } @Override - public void fromBytes(FriendlyByteBuf buf) { + public void fromBytes(MCDataInput buf) { value = buf.readVarLong(); } diff --git a/src/main/java/codechicken/lib/gui/modular/lib/container/data/ShortData.java b/src/main/java/codechicken/lib/inventory/container/data/ShortData.java similarity index 75% rename from src/main/java/codechicken/lib/gui/modular/lib/container/data/ShortData.java rename to src/main/java/codechicken/lib/inventory/container/data/ShortData.java index 4c203c09..9a29d0dd 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/container/data/ShortData.java +++ b/src/main/java/codechicken/lib/inventory/container/data/ShortData.java @@ -1,5 +1,7 @@ -package codechicken.lib.gui.modular.lib.container.data; +package codechicken.lib.inventory.container.data; +import codechicken.lib.data.MCDataInput; +import codechicken.lib.data.MCDataOutput; import net.minecraft.nbt.NumericTag; import net.minecraft.nbt.ShortTag; import net.minecraft.nbt.Tag; @@ -8,7 +10,6 @@ /** * Created by brandon3055 on 09/09/2023 */ -@Deprecated //Not sure if this will stay in CCL public class ShortData extends AbstractDataStore { public ShortData() { @@ -20,12 +21,12 @@ public ShortData(short defaultValue) { } @Override - public void toBytes(FriendlyByteBuf buf) { + public void toBytes(MCDataOutput buf) { buf.writeShort(value); } @Override - public void fromBytes(FriendlyByteBuf buf) { + public void fromBytes(MCDataInput buf) { value = buf.readShort(); } diff --git a/src/main/java/codechicken/lib/inventory/container/modular/ModularGuiContainerMenu.java b/src/main/java/codechicken/lib/inventory/container/modular/ModularGuiContainerMenu.java index a2eb159c..f6f043cc 100644 --- a/src/main/java/codechicken/lib/inventory/container/modular/ModularGuiContainerMenu.java +++ b/src/main/java/codechicken/lib/inventory/container/modular/ModularGuiContainerMenu.java @@ -1,10 +1,15 @@ package codechicken.lib.inventory.container.modular; +import codechicken.lib.data.MCDataInput; +import codechicken.lib.data.MCDataOutput; import codechicken.lib.gui.modular.elements.GuiSlots; import codechicken.lib.gui.modular.lib.container.ContainerScreenAccess; import codechicken.lib.gui.modular.lib.container.DataSync; import codechicken.lib.gui.modular.lib.container.SlotGroup; import codechicken.lib.gui.modular.lib.geometry.GuiParent; +import codechicken.lib.internal.network.CCLNetwork; +import codechicken.lib.packet.PacketCustom; +import codechicken.lib.vec.Vector3; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Inventory; @@ -25,6 +30,8 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; +import static codechicken.lib.internal.network.CCLNetwork.*; + /** * The base abstract ContainerMenu for all modular gui containers. *

@@ -38,8 +45,6 @@ public abstract class ModularGuiContainerMenu extends AbstractContainerMenu { public final Map slotGroupMap = new HashMap<>(); public final Map> zonedSlots = new HashMap<>(); public final List> dataSyncs = new ArrayList<>(); - private BiConsumer> serverToClientPacketHandler; - private Consumer> clientToServerPacketHandler; protected ModularGuiContainerMenu(@Nullable MenuType menuType, int containerId, Inventory inventory) { super(menuType, containerId); @@ -91,73 +96,37 @@ protected SlotGroup remoteSlotGroup() { } //=== Network ===// - - /** - * Set the server to client packet handler. - * As polylib does not have its own network implementation, the implementor of ModularGuiContainerMenu must provide their own if - * they wish to use the network functionality built into ModularGuiContainerMenu. - *

- * An example imeplementation may look something like: - *

-     * setServerToClientPacketHandler((player, packetWriter) -> {
-     *     FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
-     *     packetWriter.accept(buf);
-     *     MyNetwork.sendModularGuiMenuPacketToPlayer(player, buf);
-     * });
-     * 
- * Then, in your client side packet handler you would call {@link ModularGuiContainerMenu#handlePacketFromServer(Player, FriendlyByteBuf)} - * The player can be the client side player. - * - *

- * A server to client packet handler is required for the {@link DataSync} system to work. - */ - public void setServerToClientPacketHandler(BiConsumer> serverToClientPacketHandler) { - this.serverToClientPacketHandler = serverToClientPacketHandler; - } - - /** - * This should be implemented similar to {@link #setServerToClientPacketHandler(BiConsumer)} - * The difference being this will be sending packets in the other direction. - */ - public void setClientToServerPacketHandler(Consumer> clientToServerPacketHandler) { - this.clientToServerPacketHandler = clientToServerPacketHandler; - } - /** * Send a packet to the client side container. - * Requires a server to client packet handler to be installed via {@link #setServerToClientPacketHandler(BiConsumer)} * * @param packetId message id, Can be any value from 0 to 254, 255 is used by the {@link DataSync} system. * @param packetWriter Use this callback to write your data to the packet. */ - public void sendPacketToClient(int packetId, Consumer packetWriter) { - if (serverToClientPacketHandler != null && inventory.player instanceof ServerPlayer serverPlayer) { - serverToClientPacketHandler.accept(serverPlayer, buf -> { - buf.writeByte(containerId); - buf.writeByte((byte) packetId); - packetWriter.accept(buf); - }); + public void sendPacketToClient(int packetId, Consumer packetWriter) { + if (inventory.player instanceof ServerPlayer serverPlayer) { + PacketCustom packet = new PacketCustom(CCLNetwork.NET_CHANNEL, C_GUI_SYNC); + packet.writeByte(containerId); + packet.writeByte((byte) packetId); + packetWriter.accept(packet); + packet.sendToPlayer(serverPlayer); } } /** * Send a packet to the server side container. - * Requires a client to server packet handler to be installed via {@link #setClientToServerPacketHandler(Consumer)} * * @param packetId message id, Can be any value from 0 to 255 * @param packetWriter Use this callback to write your data to the packet. */ - public void sendPacketToServer(int packetId, Consumer packetWriter) { - if (clientToServerPacketHandler != null) { - clientToServerPacketHandler.accept(buf -> { - buf.writeByte(containerId); - buf.writeByte((byte) packetId); - packetWriter.accept(buf); - }); - } + public void sendPacketToServer(int packetId, Consumer packetWriter) { + PacketCustom packet = new PacketCustom(CCLNetwork.NET_CHANNEL, S_GUI_SYNC); + packet.writeByte(containerId); + packet.writeByte((byte) packetId); + packetWriter.accept(packet); + packet.sendToServer(); } - public static void handlePacketFromClient(Player player, FriendlyByteBuf packet) { + public static void handlePacketFromClient(Player player, MCDataInput packet) { int containerId = packet.readByte(); int packetId = packet.readByte() & 0xFF; if (player.containerMenu instanceof ModularGuiContainerMenu menu && menu.containerId == containerId) { @@ -167,13 +136,12 @@ public static void handlePacketFromClient(Player player, FriendlyByteBuf packet) /** * Override this in your container menu implementation in order to receive packets sent via {@link #sendPacketToServer(int, Consumer)} - * Requires a client to server packet handler to be installed via {@link #setClientToServerPacketHandler(Consumer)} */ - public void handlePacketFromClient(Player player, int packetId, FriendlyByteBuf packet) { + public void handlePacketFromClient(Player player, int packetId, MCDataInput packet) { } - public static void handlePacketFromServer(Player player, FriendlyByteBuf packet) { + public static void handlePacketFromServer(Player player, MCDataInput packet) { int containerId = packet.readByte(); int packetId = packet.readByte() & 0xFF; if (player.containerMenu instanceof ModularGuiContainerMenu menu && menu.containerId == containerId) { @@ -183,11 +151,10 @@ public static void handlePacketFromServer(Player player, FriendlyByteBuf packet) /** * Override this in your container menu implementation in order to receive packets sent via {@link #sendPacketToServer(int, Consumer)} - * Requires a server to client packet handler to be installed via {@link #setServerToClientPacketHandler(BiConsumer)} *

* Don't forget to call super if you plan on using the {@link DataSync} system. */ - public void handlePacketFromServer(Player player, int packetId, FriendlyByteBuf packet) { + public void handlePacketFromServer(Player player, int packetId, MCDataInput packet) { if (packetId == 255) { int index = packet.readByte() & 0xFF; if (dataSyncs.size() > index) { diff --git a/src/main/resources/assets/codechickenlib/atlases/gui.json b/src/main/resources/assets/codechickenlib/atlases/gui.json new file mode 100644 index 00000000..5da82735 --- /dev/null +++ b/src/main/resources/assets/codechickenlib/atlases/gui.json @@ -0,0 +1,9 @@ +{ + "sources": [ + { + "type": "directory", + "source": "gui", + "prefix": "gui/" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/codechickenlib/textures/gui/cursors/drag.png b/src/main/resources/assets/codechickenlib/textures/gui/cursors/drag.png new file mode 100644 index 00000000..1e8c3266 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/cursors/drag.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_diag_tlbr.png b/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_diag_tlbr.png new file mode 100644 index 00000000..2714f3f8 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_diag_tlbr.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_diag_trbl.png b/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_diag_trbl.png new file mode 100644 index 00000000..b306c6ba Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_diag_trbl.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_h.png b/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_h.png new file mode 100644 index 00000000..07baa61c Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_h.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_v.png b/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_v.png new file mode 100644 index 00000000..363aca47 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/cursors/resize_v.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_borderless.png b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_borderless.png new file mode 100644 index 00000000..f1484440 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_borderless.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_borderless_pressed.png b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_borderless_pressed.png new file mode 100644 index 00000000..7273c079 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_borderless_pressed.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_highlight.png b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_highlight.png new file mode 100644 index 00000000..11877644 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_highlight.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_highlight_borderless.png b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_highlight_borderless.png new file mode 100644 index 00000000..677d04c1 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_highlight_borderless.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_highlight_pressed.png b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_highlight_pressed.png new file mode 100644 index 00000000..02dd3d8b Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_highlight_pressed.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_pressed.png b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_pressed.png new file mode 100644 index 00000000..aab7096a Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_pressed.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_vanilla.png b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_vanilla.png new file mode 100644 index 00000000..5e64e34b Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_vanilla.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_vanilla_disabled.png b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_vanilla_disabled.png new file mode 100644 index 00000000..aa29d997 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/button_vanilla_disabled.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/dynamic/gui_borderless.png b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/gui_borderless.png new file mode 100644 index 00000000..87a64d8b Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/gui_borderless.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/dynamic/gui_vanilla.png b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/gui_vanilla.png new file mode 100644 index 00000000..3962fe08 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/dynamic/gui_vanilla.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/widgets/energy_empty.png b/src/main/resources/assets/codechickenlib/textures/gui/widgets/energy_empty.png new file mode 100644 index 00000000..bf499615 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/widgets/energy_empty.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/widgets/energy_full.png b/src/main/resources/assets/codechickenlib/textures/gui/widgets/energy_full.png new file mode 100644 index 00000000..4af15eef Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/widgets/energy_full.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/widgets/progress_arrow_empty.png b/src/main/resources/assets/codechickenlib/textures/gui/widgets/progress_arrow_empty.png new file mode 100644 index 00000000..7ade208c Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/widgets/progress_arrow_empty.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/widgets/progress_arrow_full.png b/src/main/resources/assets/codechickenlib/textures/gui/widgets/progress_arrow_full.png new file mode 100644 index 00000000..87b54615 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/widgets/progress_arrow_full.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/widgets/slot.png b/src/main/resources/assets/codechickenlib/textures/gui/widgets/slot.png new file mode 100644 index 00000000..65ab3081 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/widgets/slot.png differ diff --git a/src/main/resources/assets/codechickenlib/textures/gui/widgets/slot_large.png b/src/main/resources/assets/codechickenlib/textures/gui/widgets/slot_large.png new file mode 100644 index 00000000..61c28017 Binary files /dev/null and b/src/main/resources/assets/codechickenlib/textures/gui/widgets/slot_large.png differ