From 270453ffd582576c2c6149c2f0e08f4cb031dee5 Mon Sep 17 00:00:00 2001 From: Roundaround Date: Wed, 17 Jul 2024 16:11:41 -0400 Subject: [PATCH] Lots of RoundaLib migration work --- assets/icons-18.psd | Bin 0 -> 455650 bytes assets/icons-20.psd | Bin 0 -> 217291 bytes .../client/gui/MessageRenderer.java | 5 +- .../gui/screen/AbstractArmorStandScreen.java | 231 +++++----- .../gui/screen/ArmorStandInventoryScreen.java | 23 +- .../gui/screen/ArmorStandMoveScreen.java | 288 ++++++------- .../gui/screen/ArmorStandPoseScreen.java | 268 +++++------- .../gui/screen/ArmorStandPresetsScreen.java | 301 ++++++------- .../gui/screen/ArmorStandRotateScreen.java | 402 +++++++++--------- .../gui/screen/ArmorStandUtilitiesScreen.java | 216 +++++----- .../gui/widget/AdjustPoseSliderWidget.java | 4 +- .../gui/widget/ArmorStandLayoutWidget.java | 58 +++ .../client/gui/widget/FlagToggleWidget.java | 2 +- .../client/gui/widget/MoveButtonWidget.java | 48 --- .../gui/widget/NavigationButtonWidget.java | 40 -- .../armorstands/network/ScreenType.java | 23 +- .../textures/gui/sprites/icon/body.png | Bin 0 -> 1237 bytes .../textures/gui/sprites/icon/copy.png | Bin 0 -> 1160 bytes .../textures/gui/sprites/icon/flag.png | Bin 0 -> 1235 bytes .../textures/gui/sprites/icon/head.png | Bin 0 -> 1188 bytes .../textures/gui/sprites/icon/inventory.png | Bin 0 -> 1257 bytes .../textures/gui/sprites/icon/leftarm.png | Bin 0 -> 1282 bytes .../textures/gui/sprites/icon/leftleg.png | Bin 0 -> 1144 bytes .../textures/gui/sprites/icon/paste.png | Bin 0 -> 1322 bytes .../textures/gui/sprites/icon/pose.png | Bin 0 -> 1286 bytes .../textures/gui/sprites/icon/rightarm.png | Bin 0 -> 1342 bytes .../textures/gui/sprites/icon/rightleg.png | Bin 0 -> 1149 bytes .../textures/gui/sprites/selection.png | Bin 0 -> 1924 bytes 28 files changed, 898 insertions(+), 1011 deletions(-) create mode 100644 assets/icons-18.psd create mode 100644 assets/icons-20.psd create mode 100644 src/main/java/me/roundaround/armorstands/client/gui/widget/ArmorStandLayoutWidget.java delete mode 100644 src/main/java/me/roundaround/armorstands/client/gui/widget/MoveButtonWidget.java delete mode 100644 src/main/java/me/roundaround/armorstands/client/gui/widget/NavigationButtonWidget.java create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/icon/body.png create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/icon/copy.png create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/icon/flag.png create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/icon/head.png create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/icon/inventory.png create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/icon/leftarm.png create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/icon/leftleg.png create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/icon/paste.png create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/icon/pose.png create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/icon/rightarm.png create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/icon/rightleg.png create mode 100644 src/main/resources/assets/armorstands/textures/gui/sprites/selection.png diff --git a/assets/icons-18.psd b/assets/icons-18.psd new file mode 100644 index 0000000000000000000000000000000000000000..c37a5221c62f27554b4b029430d90be121245f50 GIT binary patch literal 455650 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¥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 literal 0 HcmV?d00001 diff --git a/src/main/java/me/roundaround/armorstands/client/gui/MessageRenderer.java b/src/main/java/me/roundaround/armorstands/client/gui/MessageRenderer.java index adc8ce2..f40da3f 100644 --- a/src/main/java/me/roundaround/armorstands/client/gui/MessageRenderer.java +++ b/src/main/java/me/roundaround/armorstands/client/gui/MessageRenderer.java @@ -1,12 +1,11 @@ package me.roundaround.armorstands.client.gui; import com.mojang.blaze3d.systems.RenderSystem; -import me.roundaround.armorstands.client.gui.widget.NavigationButtonWidget; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.text.Text; import net.minecraft.util.math.MathHelper; @@ -77,7 +76,7 @@ public void render(Screen screen, DrawContext context) { TextRenderer textRenderer = client.textRenderer; int width = textRenderer.getWidth(text); int x = (screen.width - width) / 2; - int y = screen.height - NavigationButtonWidget.HEIGHT - 1 - 6 - textRenderer.fontHeight; + int y = screen.height - ButtonWidget.DEFAULT_HEIGHT - 1 - 6 - textRenderer.fontHeight; float opacity = MathHelper.clamp(timeRemaining / 10f, 0f, 1f); int backgroundAlpha = client.options.getTextBackgroundColor(0) >> 24 & 0xFF; diff --git a/src/main/java/me/roundaround/armorstands/client/gui/screen/AbstractArmorStandScreen.java b/src/main/java/me/roundaround/armorstands/client/gui/screen/AbstractArmorStandScreen.java index cd0db10..4b6d9db 100644 --- a/src/main/java/me/roundaround/armorstands/client/gui/screen/AbstractArmorStandScreen.java +++ b/src/main/java/me/roundaround/armorstands/client/gui/screen/AbstractArmorStandScreen.java @@ -4,9 +4,7 @@ import me.roundaround.armorstands.ArmorStandsMod; import me.roundaround.armorstands.client.ArmorStandsClientMod; import me.roundaround.armorstands.client.gui.MessageRenderer; -import me.roundaround.armorstands.client.gui.widget.HelpButtonWidget; -import me.roundaround.armorstands.client.gui.widget.IconButtonWidget; -import me.roundaround.armorstands.client.gui.widget.NavigationButtonWidget; +import me.roundaround.armorstands.client.gui.widget.ArmorStandLayoutWidget; import me.roundaround.armorstands.client.network.ClientNetworking; import me.roundaround.armorstands.mixin.ArmorStandEntityAccessor; import me.roundaround.armorstands.mixin.InGameHudAccessor; @@ -15,14 +13,18 @@ import me.roundaround.armorstands.network.ScreenType; import me.roundaround.armorstands.network.UtilityAction; import me.roundaround.armorstands.screen.ArmorStandScreenHandler; -import me.roundaround.roundalib.client.gui.GuiUtil; +import me.roundaround.roundalib.asset.icon.BuiltinIcon; +import me.roundaround.roundalib.asset.icon.CustomIcon; +import me.roundaround.roundalib.client.gui.layout.IntRect; +import me.roundaround.roundalib.client.gui.widget.DrawableWidget; +import me.roundaround.roundalib.client.gui.widget.IconButtonWidget; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.Element; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.client.util.InputUtil; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.sound.SoundEvents; @@ -30,24 +32,21 @@ import net.minecraft.util.Identifier; import org.lwjgl.glfw.GLFW; -import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; import java.util.Optional; public abstract class AbstractArmorStandScreen extends HandledScreen implements PassesEventsThrough { - protected static final Identifier SELECTION_TEXTURE = new Identifier( - ArmorStandsMod.MOD_ID, "textures/gui/selection_frame.png"); - - protected static final int NAV_BUTTON_BOTTOM_PADDING = 1; - protected static final int NAV_BUTTON_SPACING = 0; + protected static final Identifier SELECTION_TEXTURE = new Identifier(ArmorStandsMod.MOD_ID, "selection"); + protected static final CustomIcon COPY_ICON = new CustomIcon("copy", 20); + protected static final CustomIcon PASTE_ICON = new CustomIcon("paste", 20); + protected final ArmorStandLayoutWidget layout = new ArmorStandLayoutWidget(this); protected final ArmorStandEntity armorStand; protected final MessageRenderer messageRenderer; - protected final ArrayList navigationButtons = new ArrayList<>(); - protected NavigationButtonWidget activeButton; + protected IconButtonWidget activeButton; protected boolean supportsUndoRedo = false; protected boolean utilizesInventory = false; protected boolean passEvents = true; @@ -80,15 +79,96 @@ public boolean shouldPassEvents() { @Override public void init() { - initStart(); + this.populateLayout(); + this.collectChildren(); + this.initTabNavigation(); + } - super.init(); + protected void populateLayout() { + this.initUtilityButtons(); + this.initNavigationButtons(); + } - initLeft(); - initNavigationButtons(); - initRight(); + protected void initUtilityButtons() { + if (!this.supportsUndoRedo) { + return; + } - initEnd(); + this.layout.topLeft.add(IconButtonWidget.builder(BuiltinIcon.HELP_18, ArmorStandsMod.MOD_ID) + .large() + .messageAndTooltip(this.buildHelpTooltipText()) + .build()); + this.layout.topLeft.add(IconButtonWidget.builder(COPY_ICON, ArmorStandsMod.MOD_ID) + .large() + .messageAndTooltip(Text.translatable("armorstands.utility.copy")) + .onPress((button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.COPY)) + .build()); + this.layout.topLeft.add(IconButtonWidget.builder(PASTE_ICON, ArmorStandsMod.MOD_ID) + .large() + .messageAndTooltip(Text.translatable("armorstands.utility.paste")) + .onPress((button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.PASTE)) + .build()); + this.layout.topLeft.add(IconButtonWidget.builder(BuiltinIcon.UNDO_18, ArmorStandsMod.MOD_ID) + .large() + .messageAndTooltip(Text.translatable("armorstands.utility.undo")) + .onPress((button) -> ClientNetworking.sendUndoPacket(false)) + .build()); + this.layout.topLeft.add(IconButtonWidget.builder(BuiltinIcon.REDO_18, ArmorStandsMod.MOD_ID) + .large() + .messageAndTooltip(Text.translatable("armorstands.utility.redo")) + .onPress((button) -> ClientNetworking.sendUndoPacket(true)) + .build()); + } + + private Text buildHelpTooltipText() { + String alt = Text.translatable("armorstands.help.alt").getString(); + String inventory = Objects.requireNonNull(this.client).options.inventoryKey.getBoundKeyLocalizedText().getString(); + String left = InputUtil.fromKeyCode(GLFW.GLFW_KEY_LEFT, 0).getLocalizedText().getString(); + String right = InputUtil.fromKeyCode(GLFW.GLFW_KEY_RIGHT, 0).getLocalizedText().getString(); + String highlight = ArmorStandsClientMod.highlightArmorStandKeyBinding.getBoundKeyLocalizedText().getString(); + String control = Text.translatable("armorstands.help." + (MinecraftClient.IS_SYSTEM_MAC ? "cmd" : "ctrl")) + .getString(); + String z = InputUtil.fromKeyCode(GLFW.GLFW_KEY_Z, 0).getLocalizedText().getString(); + String shift = Text.translatable("armorstands.help.shift").getString(); + String c = InputUtil.fromKeyCode(GLFW.GLFW_KEY_C, 0).getLocalizedText().getString(); + String v = InputUtil.fromKeyCode(GLFW.GLFW_KEY_V, 0).getLocalizedText().getString(); + + return Text.translatable("armorstands.help", alt, inventory, left, right, highlight, control, z, control, shift, z, + control, c, control, v + ); + } + + protected void initNavigationButtons() { + for (ScreenType screenType : ScreenType.values()) { + IconButtonWidget navButton = IconButtonWidget.builder(screenType.getIcon(), ArmorStandsMod.MOD_ID) + .onPress((button) -> ClientNetworking.sendRequestScreenPacket(this.getArmorStand(), screenType)) + .build(); + if (this.getScreenType() == screenType) { + navButton.active = false; + } + this.layout.navRow.add(navButton); + } + } + + protected void collectChildren() { + this.layout.forEachChild(this::addDrawableChild); + this.addDrawableChild(new DrawableWidget() { + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + IconButtonWidget activeButton = AbstractArmorStandScreen.this.activeButton; + if (activeButton == null) { + return; + } + + RenderSystem.setShaderColor(1f, 1f, 1f, 1f); + context.drawGuiTexture(SELECTION_TEXTURE, activeButton.getX() - 2, activeButton.getY() - 2, 24, 24); + } + }); + } + + @Override + protected void initTabNavigation() { + this.layout.refreshPositions(); } @Override @@ -118,8 +198,6 @@ public void render(DrawContext drawContext, int mouseX, int mouseY, float delta) super.render(drawContext, adjustedMouseX, adjustedMouseY, delta); - renderActivePageButtonHighlight(drawContext); - this.messageRenderer.render(drawContext); } @@ -197,22 +275,20 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) { } @Override - public boolean mouseScrolled( - double mouseX, double mouseY, double horizontalAmount, double verticalAmount - ) { + public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { if (this.cursorLocked) { return false; } - for (NavigationButtonWidget button : this.navigationButtons) { - if (button.isMouseOverIgnoreState(mouseX, mouseY)) { - if (verticalAmount > 0) { - goToPreviousScreen(); - } else { - goToNextScreen(); - } - return true; + + if (IntRect.fromWidget(this.layout.navRow).contains(mouseX, mouseY)) { + if (verticalAmount > 0) { + goToPreviousScreen(); + } else { + goToNextScreen(); } + return true; } + return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); } @@ -286,17 +362,13 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { return true; } - for (int i = 0; i < this.navigationButtons.size(); i++) { - NavigationButtonWidget button = this.navigationButtons.get(i); - ScreenType screenType = button.getScreenType(); - + for (ScreenType screenType : ScreenType.values()) { if (screenType == this.getScreenType()) { continue; } - - if (this.client.options.hotbarKeys[i].matchesKey(keyCode, scanCode)) { + if (this.client.options.hotbarKeys[screenType.getId()].matchesKey(keyCode, scanCode)) { playClickSound(); - button.onPress(); + ClientNetworking.sendRequestScreenPacket(this.armorStand, screenType); return true; } } @@ -355,87 +427,6 @@ public void updateDisabledSlotsOnClient(int disabledSlots) { ((ArmorStandEntityAccessor) this.armorStand).setDisabledSlots(disabledSlots); } - protected void initStart() { - this.navigationButtons.clear(); - } - - protected void initUtilityButtons() { - if (!this.supportsUndoRedo) { - return; - } - - addDrawableChild(new HelpButtonWidget(GuiUtil.PADDING, GuiUtil.PADDING)); - addDrawableChild( - new IconButtonWidget(GuiUtil.PADDING + IconButtonWidget.WIDTH + (GuiUtil.PADDING / 2), GuiUtil.PADDING, 14, - Text.translatable("armorstands.utility.copy"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.COPY) - )); - addDrawableChild( - new IconButtonWidget(GuiUtil.PADDING + 2 * (IconButtonWidget.WIDTH + (GuiUtil.PADDING / 2)), GuiUtil.PADDING, - 15, Text.translatable("armorstands.utility.paste"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.PASTE) - )); - addDrawableChild( - new IconButtonWidget(GuiUtil.PADDING + 3 * (IconButtonWidget.WIDTH + (GuiUtil.PADDING / 2)), GuiUtil.PADDING, - 17, Text.translatable("armorstands.utility.undo"), (button) -> ClientNetworking.sendUndoPacket(false) - )); - addDrawableChild( - new IconButtonWidget(GuiUtil.PADDING + 4 * (IconButtonWidget.WIDTH + (GuiUtil.PADDING / 2)), GuiUtil.PADDING, - 18, Text.translatable("armorstands.utility.redo"), (button) -> ClientNetworking.sendUndoPacket(true) - )); - } - - protected void initLeft() { - initUtilityButtons(); - } - - protected void initNavigationButtons() { - ScreenType[] screenTypes = ScreenType.values(); - int totalWidth = screenTypes.length * NavigationButtonWidget.WIDTH + (screenTypes.length - 1) * NAV_BUTTON_SPACING; - - int x = (width - totalWidth) / 2 - 2 * NAV_BUTTON_SPACING; - int y = height - NAV_BUTTON_BOTTOM_PADDING - NavigationButtonWidget.HEIGHT; - - for (ScreenType screenType : screenTypes) { - NavigationButtonWidget button = new NavigationButtonWidget(this, x, y, screenType); - - if (getScreenType() == screenType) { - this.activeButton = button; - addDrawable(button); - } else { - addDrawableChild(button); - } - - x += NAV_BUTTON_SPACING + NavigationButtonWidget.WIDTH; - - this.navigationButtons.add(button); - } - } - - protected void initRight() { - } - - protected void initEnd() { - } - - protected void renderActivePageButtonHighlight(DrawContext drawContext) { - if (this.activeButton == null) { - return; - } - - RenderSystem.setShaderColor(1f, 1f, 1f, 1f); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - - MatrixStack matrixStack = drawContext.getMatrices(); - matrixStack.push(); - matrixStack.translate(0, 0, 100); - drawContext.drawTexture(SELECTION_TEXTURE, this.activeButton.getX() - 2, this.activeButton.getY() - 2, 0, 0, 24, 24, - 24, 24 - ); - matrixStack.pop(); - } - protected void playClickSound() { Objects.requireNonNull(this.client) .getSoundManager() diff --git a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandInventoryScreen.java b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandInventoryScreen.java index 512ebb2..a5c21da 100644 --- a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandInventoryScreen.java +++ b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandInventoryScreen.java @@ -38,24 +38,23 @@ public ScreenType getScreenType() { return ScreenType.INVENTORY; } - @Override - protected void initRight() { - this.showArmsToggle = addDrawableChild(new FlagToggleWidget(this.textRenderer, ArmorStandFlag.SHOW_ARMS, - ArmorStandFlag.SHOW_ARMS.getValue(this.armorStand), this.width - GuiUtil.PADDING, - this.height - GuiUtil.PADDING - 2 * FlagToggleWidget.WIDGET_HEIGHT - (GuiUtil.PADDING / 2) - )); - this.lockInventoryToggle = addDrawableChild(new FlagToggleWidget(this.textRenderer, ArmorStandFlag.LOCK_INVENTORY, - ArmorStandFlag.LOCK_INVENTORY.getValue(this.armorStand), this.width - GuiUtil.PADDING, - this.height - GuiUtil.PADDING - FlagToggleWidget.WIDGET_HEIGHT - )); + protected void populateLayout() { +// this.showArmsToggle = this.layout.bottomRight.add(new FlagToggleWidget(this.textRenderer, ArmorStandFlag.SHOW_ARMS, +// ArmorStandFlag.SHOW_ARMS.getValue(this.armorStand), this.width - GuiUtil.PADDING, +// this.height - GuiUtil.PADDING - 2 * FlagToggleWidget.WIDGET_HEIGHT - (GuiUtil.PADDING / 2) +// )); +// this.lockInventoryToggle = this.layout.bottomRight.add(new FlagToggleWidget(this.textRenderer, ArmorStandFlag.LOCK_INVENTORY, +// ArmorStandFlag.LOCK_INVENTORY.getValue(this.armorStand), this.width - GuiUtil.PADDING, +// this.height - GuiUtil.PADDING - FlagToggleWidget.WIDGET_HEIGHT +// )); } @Override public void handledScreenTick() { super.handledScreenTick(); - this.showArmsToggle.setValue(ArmorStandFlag.SHOW_ARMS.getValue(this.armorStand)); - this.lockInventoryToggle.setValue(ArmorStandFlag.LOCK_INVENTORY.getValue(this.armorStand)); +// this.showArmsToggle.setValue(ArmorStandFlag.SHOW_ARMS.getValue(this.armorStand)); +// this.lockInventoryToggle.setValue(ArmorStandFlag.LOCK_INVENTORY.getValue(this.armorStand)); } @Override diff --git a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandMoveScreen.java b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandMoveScreen.java index 9c3de8d..c9ad2b7 100644 --- a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandMoveScreen.java +++ b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandMoveScreen.java @@ -1,7 +1,5 @@ package me.roundaround.armorstands.client.gui.screen; -import me.roundaround.armorstands.client.gui.widget.IconButtonWidget; -import me.roundaround.armorstands.client.gui.widget.MoveButtonWidget; import me.roundaround.armorstands.client.network.ClientNetworking; import me.roundaround.armorstands.network.ScreenType; import me.roundaround.armorstands.network.UtilityAction; @@ -10,6 +8,7 @@ import me.roundaround.armorstands.util.MoveUnits; import me.roundaround.roundalib.client.gui.GuiUtil; import me.roundaround.roundalib.client.gui.widget.LabelWidget; +import me.roundaround.roundalib.client.gui.widget.layout.LinearLayoutWidget; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.CyclingButtonWidget; import net.minecraft.entity.Entity; @@ -19,6 +18,7 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.List; public class ArmorStandMoveScreen extends AbstractArmorStandScreen { private static final int MINI_BUTTON_WIDTH = 28; @@ -27,12 +27,10 @@ public class ArmorStandMoveScreen extends AbstractArmorStandScreen { private static final int BUTTON_HEIGHT = 16; private final HashMap directionLabels = new HashMap<>(); - private final ArrayList moveButtons = new ArrayList<>(); + private final ArrayList moveButtons = new ArrayList<>(); - private LabelWidget playerPosLabel; - private LabelWidget playerBlockPosLabel; - private LabelWidget standPosLabel; - private LabelWidget standBlockPosLabel; + private LabelWidget playerLabel; + private LabelWidget standLabel; private LabelWidget facingLabel; private CyclingButtonWidget unitsButton; private MoveMode mode = MoveMode.RELATIVE; @@ -49,186 +47,115 @@ public ScreenType getScreenType() { } @Override - protected void initStart() { - super.initStart(); + protected void populateLayout() { + super.populateLayout(); - directionLabels.clear(); - moveButtons.clear(); - } - - @Override - protected void initLeft() { - super.initLeft(); - - initCurrentStatus(); - initSnapButtons(); - } - - private void initCurrentStatus() { - ArrayList playerLines = new ArrayList<>(); - playerLines.add(Text.translatable("armorstands.current.player")); - playerLines.add(this.getCurrentPosText(this.client.player)); - playerLines.add(this.getCurrentBlockPosText(this.client.player)); - this.addDrawable(LabelWidget.builder(this.textRenderer, playerLines) - .refPosition(this.width, 0) - .alignedTop() - .justifiedRight() - .build()); - - ArrayList standLines = new ArrayList<>(); - standLines.add(Text.translatable("armorstands.current.stand")); - standLines.add(this.getCurrentPosText(this.armorStand)); - standLines.add(this.getCurrentBlockPosText(this.armorStand)); - this.addDrawable(LabelWidget.builder(this.textRenderer, standLines) - .refPosition(this.width, 0) - .alignedTop() - .justifiedRight() - .build()); - - addLabel(LabelWidget.builder(Text.translatable("armorstands.current.stand"), GuiUtil.PADDING, - GuiUtil.PADDING + IconButtonWidget.HEIGHT + 5 * LabelWidget.HEIGHT_WITH_PADDING - ).alignedTop().justifiedLeft().shiftForPadding().build()); - - this.standPosLabel = addLabel(LabelWidget.builder(getCurrentPosText(this.armorStand), GuiUtil.PADDING, - GuiUtil.PADDING + IconButtonWidget.HEIGHT + 6 * LabelWidget.HEIGHT_WITH_PADDING - ).alignedTop().justifiedLeft().shiftForPadding().build()); - - this.standBlockPosLabel = addLabel(LabelWidget.builder(getCurrentBlockPosText(this.armorStand), GuiUtil.PADDING, - GuiUtil.PADDING + IconButtonWidget.HEIGHT + 7 * LabelWidget.HEIGHT_WITH_PADDING - ).alignedTop().justifiedLeft().shiftForPadding().build()); + this.initSnapButtons(); + this.initLabels(); + this.initCore(); } private void initSnapButtons() { - addLabel(LabelWidget.builder(Text.translatable("armorstands.move.snap"), GuiUtil.PADDING, - this.height - GuiUtil.PADDING - 2 * (BUTTON_HEIGHT + (GuiUtil.PADDING / 2)) - ).shiftForPadding().justifiedLeft().alignedBottom().build()); - - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.move.snap.standing"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.SNAP_STANDING) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING, this.height - GuiUtil.PADDING - 2 * BUTTON_HEIGHT - (GuiUtil.PADDING / 2)) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.move.snap.sitting"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.SNAP_SITTING) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING + BUTTON_WIDTH + (GuiUtil.PADDING / 2), - this.height - GuiUtil.PADDING - 2 * BUTTON_HEIGHT - (GuiUtil.PADDING / 2) - ) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.move.snap.corner"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.SNAP_CORNER) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING, this.height - GuiUtil.PADDING - BUTTON_HEIGHT) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.move.snap.center"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.SNAP_CENTER) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING + BUTTON_WIDTH + (GuiUtil.PADDING / 2), this.height - GuiUtil.PADDING - BUTTON_HEIGHT) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.move.snap.player"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.SNAP_PLAYER) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING + 2 * (BUTTON_WIDTH + (GuiUtil.PADDING / 2)), this.height - GuiUtil.PADDING - BUTTON_HEIGHT) - .build()); + this.layout.bottomLeft.add( + LabelWidget.builder(this.textRenderer, Text.translatable("armorstands.move.snap")).build()); + + LinearLayoutWidget firstRow = LinearLayoutWidget.horizontal().alignLeft().spacing(GuiUtil.PADDING); + firstRow.add(ButtonWidget.builder(Text.translatable("armorstands.move.snap.standing"), + (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.SNAP_STANDING) + ).size(BUTTON_WIDTH, BUTTON_HEIGHT).build()); + firstRow.add(ButtonWidget.builder(Text.translatable("armorstands.move.snap.sitting"), + (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.SNAP_SITTING) + ).size(BUTTON_WIDTH, BUTTON_HEIGHT).build()); + this.layout.bottomLeft.add(firstRow); + + LinearLayoutWidget secondRow = LinearLayoutWidget.horizontal().alignLeft().spacing(GuiUtil.PADDING); + secondRow.add(ButtonWidget.builder(Text.translatable("armorstands.move.snap.corner"), + (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.SNAP_CORNER) + ).size(BUTTON_WIDTH, BUTTON_HEIGHT).build()); + secondRow.add(ButtonWidget.builder(Text.translatable("armorstands.move.snap.center"), + (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.SNAP_CENTER) + ).size(BUTTON_WIDTH, BUTTON_HEIGHT).build()); + secondRow.add(ButtonWidget.builder(Text.translatable("armorstands.move.snap.player"), + (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.SNAP_PLAYER) + ).size(BUTTON_WIDTH, BUTTON_HEIGHT).build()); + this.layout.bottomLeft.add(secondRow); } - @Override - protected void initRight() { - super.initRight(); - - int topOfMoveButtons = this.height - GuiUtil.PADDING - 6 * MINI_BUTTON_HEIGHT - 5 * (GuiUtil.PADDING / 2); + private void initLabels() { + LinearLayoutWidget labels = LinearLayoutWidget.vertical().spacing(GuiUtil.PADDING).alignTop().alignRight(); + this.playerLabel = labels.add( + LabelWidget.builder(this.textRenderer, this.getPlayerLines()).justifiedRight().lineSpacing(1).build()); + this.standLabel = labels.add( + LabelWidget.builder(this.textRenderer, this.getArmorStandLines()).justifiedRight().lineSpacing(1).build()); + this.layout.topRight.add(labels); + } - addDrawableChild(CyclingButtonWidget.builder(MoveMode::getOptionValueText) + private void initCore() { + this.layout.bottomRight.add(CyclingButtonWidget.builder(MoveMode::getOptionValueText) .values(MoveMode.values()) .initially(this.mode) - .build(this.width - GuiUtil.PADDING - 120, - topOfMoveButtons - LabelWidget.HEIGHT_WITH_PADDING - 3 * (GuiUtil.PADDING / 2) - 2 * MINI_BUTTON_HEIGHT, 120, - MINI_BUTTON_HEIGHT, MoveMode.getOptionLabelText(), (button, mode) -> { - this.mode = mode; - this.units = this.mode.getDefaultUnits(); - - this.facingLabel.setText( - getCurrentFacingText(this.mode.equals(MoveMode.LOCAL_TO_STAND) ? this.armorStand : client.player)); - this.directionLabels.forEach((direction, label) -> { - label.setText(this.mode.getDirectionText(direction)); - }); - - this.unitsButton.setValue(this.units); - this.moveButtons.forEach((moveButton) -> { - moveButton.setUnits(this.units); - }); - } - )); - - this.unitsButton = addDrawableChild(CyclingButtonWidget.builder(MoveUnits::getOptionValueText) + .build(MoveMode.getOptionLabelText(), (button, mode) -> { + this.mode = mode; + this.units = this.mode.getDefaultUnits(); + + this.unitsButton.setValue(this.units); + this.facingLabel.setText(this.getCurrentFacingText()); + this.directionLabels.forEach((direction, label) -> label.setText(this.mode.getDirectionText(direction))); + this.moveButtons.forEach((moveButton) -> moveButton.setUnits(this.units)); + })); + + this.unitsButton = this.layout.bottomRight.add(CyclingButtonWidget.builder(MoveUnits::getOptionValueText) .values(MoveUnits.values()) .initially(this.units) - .build(this.width - GuiUtil.PADDING - 120, - topOfMoveButtons - LabelWidget.HEIGHT_WITH_PADDING - 2 * (GuiUtil.PADDING / 2) - MINI_BUTTON_HEIGHT, 120, - MINI_BUTTON_HEIGHT, MoveUnits.getOptionLabelText(), (button, units) -> { - this.units = units; - this.moveButtons.forEach((moveButton) -> { - moveButton.setUnits(this.units); - }); - } - )); - - this.facingLabel = addLabel(LabelWidget.builder( - getCurrentFacingText(this.mode.equals(MoveMode.LOCAL_TO_STAND) ? this.armorStand : this.client.player), - this.width - GuiUtil.PADDING, topOfMoveButtons - (GuiUtil.PADDING / 2) - ).shiftForPadding().alignedBottom().justifiedRight().build()); + .build(MoveUnits.getOptionLabelText(), (button, units) -> { + this.units = units; + this.moveButtons.forEach((moveButton) -> moveButton.setUnits(this.units)); + })); + + this.facingLabel = this.layout.bottomRight.add( + LabelWidget.builder(this.textRenderer, this.getCurrentFacingText()).build()); Direction[] directions = new Direction[]{ Direction.UP, Direction.DOWN, Direction.SOUTH, Direction.NORTH, Direction.EAST, Direction.WEST }; - for (int i = directions.length - 1; i >= 0; i--) { - addRowOfButtons(directions[directions.length - i - 1], i); - } - } + for (Direction direction : directions) { + LinearLayoutWidget row = LinearLayoutWidget.horizontal().spacing(GuiUtil.PADDING).alignRight().alignCenterY(); + + LabelWidget label = LabelWidget.builder(this.textRenderer, this.mode.getDirectionText(direction)).build(); + this.directionLabels.put(direction, label); + row.add(label); - private void addRowOfButtons(Direction direction, int index) { - int refX = this.width - GuiUtil.PADDING; - int refY = this.height - GuiUtil.PADDING - MINI_BUTTON_HEIGHT - index * ((GuiUtil.PADDING / 2) + MINI_BUTTON_HEIGHT); - - directionLabels.put(direction, addLabel( - LabelWidget.builder(this.mode.getDirectionText(direction), refX - 3 * ((GuiUtil.PADDING / 2) + MINI_BUTTON_WIDTH), - refY + MINI_BUTTON_HEIGHT / 2 - ).justifiedRight().alignedMiddle().shiftForPadding().build())); - - moveButtons.add(addDrawableChild( - new MoveButtonWidget(refX - 3 * MINI_BUTTON_WIDTH - 2 * (GuiUtil.PADDING / 2), refY, MINI_BUTTON_WIDTH, - MINI_BUTTON_HEIGHT, direction, 1, this.mode, this.units - ))); - - moveButtons.add(addDrawableChild( - new MoveButtonWidget(refX - 2 * MINI_BUTTON_WIDTH - (GuiUtil.PADDING / 2), refY, MINI_BUTTON_WIDTH, MINI_BUTTON_HEIGHT, - direction, 2, this.mode, this.units - ))); - - moveButtons.add(addDrawableChild( - new MoveButtonWidget(refX - MINI_BUTTON_WIDTH, refY, MINI_BUTTON_WIDTH, MINI_BUTTON_HEIGHT, direction, 3, - this.mode, this.units - ))); + MoveButtonRef one = new MoveButtonRef(direction, 1, this.mode, this.units); + this.moveButtons.add(one); + row.add(one.getButton()); + + this.layout.bottomRight.add(row); + } } @Override public void handledScreenTick() { super.handledScreenTick(); - this.playerPosLabel.setText(getCurrentPosText(this.client.player)); - this.playerBlockPosLabel.setText(getCurrentBlockPosText(this.client.player)); - this.standPosLabel.setText(getCurrentPosText(this.armorStand)); - this.standBlockPosLabel.setText(getCurrentBlockPosText(this.armorStand)); + this.playerLabel.setText(this.getPlayerLines()); + this.standLabel.setText(this.getArmorStandLines()); this.facingLabel.setText( getCurrentFacingText(this.mode.equals(MoveMode.LOCAL_TO_STAND) ? this.armorStand : this.client.player)); } + private List getPlayerLines() { + return List.of(Text.translatable("armorstands.current.player"), this.getCurrentPosText(this.client.player), + this.getCurrentBlockPosText(this.client.player) + ); + } + + private List getArmorStandLines() { + return List.of(Text.translatable("armorstands.current.stand"), this.getCurrentPosText(this.armorStand), + this.getCurrentBlockPosText(this.armorStand) + ); + } + private Text getCurrentPosText(Entity entity) { String xStr = String.format("%.2f", entity.getX()); String yStr = String.format("%.2f", entity.getY()); @@ -241,6 +168,10 @@ private Text getCurrentBlockPosText(Entity entity) { return Text.translatable("armorstands.current.block", pos.getX(), pos.getY(), pos.getZ()); } + private Text getCurrentFacingText() { + return this.getCurrentFacingText(this.mode.equals(MoveMode.LOCAL_TO_STAND) ? this.armorStand : this.client.player); + } + private Text getCurrentFacingText(Entity entity) { float currentRotation = entity.getYaw(); Direction currentFacing = Direction.fromRotation(currentRotation); @@ -253,4 +184,41 @@ private Text getCurrentFacingText(Entity entity) { Text towards = Text.translatable("armorstands.current.facing." + towardsI18n); return Text.translatable("armorstands.current.facing", currentFacing.toString(), towards.getString()); } + + private static class MoveButtonRef { + private final ButtonWidget button; + private final Direction direction; + private final int amount; + private final MoveMode mode; + + private MoveUnits units; + + public MoveButtonRef(Direction direction, int amount, MoveMode mode, MoveUnits units) { + this.direction = direction; + this.amount = amount; + this.mode = mode; + this.units = units; + + this.button = ButtonWidget.builder(this.getMessage(), this::onPress) + .size(MINI_BUTTON_WIDTH, MINI_BUTTON_HEIGHT) + .build(); + } + + public ButtonWidget getButton() { + return this.button; + } + + public void setUnits(MoveUnits units) { + this.units = units; + this.button.setMessage(this.units.getButtonText(this.amount)); + } + + private Text getMessage() { + return this.units.getButtonText(this.amount); + } + + private void onPress(ButtonWidget button) { + ClientNetworking.sendAdjustPosPacket(this.direction, this.amount, this.mode, this.units); + } + } } diff --git a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandPoseScreen.java b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandPoseScreen.java index 1380d9d..187a2fb 100644 --- a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandPoseScreen.java +++ b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandPoseScreen.java @@ -1,21 +1,25 @@ package me.roundaround.armorstands.client.gui.screen; import com.mojang.blaze3d.systems.RenderSystem; +import me.roundaround.armorstands.ArmorStandsMod; import me.roundaround.armorstands.client.gui.widget.AdjustPoseSliderWidget; -import me.roundaround.armorstands.client.gui.widget.IconButtonWidget; -import me.roundaround.armorstands.client.gui.widget.LabelWidget; import me.roundaround.armorstands.client.network.ClientNetworking; import me.roundaround.armorstands.network.EulerAngleParameter; import me.roundaround.armorstands.network.PosePart; import me.roundaround.armorstands.network.ScreenType; import me.roundaround.armorstands.screen.ArmorStandScreenHandler; import me.roundaround.armorstands.util.Pose; +import me.roundaround.roundalib.asset.icon.CustomIcon; import me.roundaround.roundalib.client.gui.GuiUtil; +import me.roundaround.roundalib.client.gui.layout.Spacing; +import me.roundaround.roundalib.client.gui.widget.DrawableWidget; +import me.roundaround.roundalib.client.gui.widget.IconButtonWidget; +import me.roundaround.roundalib.client.gui.widget.LabelWidget; +import me.roundaround.roundalib.client.gui.widget.layout.LinearLayoutWidget; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.CyclingButtonWidget; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.text.Text; @@ -24,13 +28,15 @@ public class ArmorStandPoseScreen extends AbstractArmorStandScreen { private static final int SLIDER_HEIGHT = 16; private static final int BUTTON_HEIGHT = 16; private static final int BUTTON_WIDTH = 16; - private static final int ROW_PAD = 6; - private static final int PART_PAD_VERTICAL = 10; - private static final int PART_PAD_HORIZONTAL = 4; + protected static final CustomIcon HEAD_ICON = new CustomIcon("head", 20); + protected static final CustomIcon BODY_ICON = new CustomIcon("body", 20); + protected static final CustomIcon RIGHT_ARM_ICON = new CustomIcon("rightarm", 20); + protected static final CustomIcon LEFT_ARM_ICON = new CustomIcon("leftarm", 20); + protected static final CustomIcon RIGHT_LEG_ICON = new CustomIcon("rightleg", 20); + protected static final CustomIcon LEFT_LEG_ICON = new CustomIcon("leftleg", 20); private PosePart posePart = PosePart.HEAD; - private IconButtonWidget activePosePartButton; - + private ButtonWidget activePosePartButton; private LabelWidget posePartLabel; private AdjustPoseSliderWidget pitchSlider; private AdjustPoseSliderWidget yawSlider; @@ -61,158 +67,118 @@ public ScreenType getScreenType() { } @Override - protected void initLeft() { - super.initLeft(); + protected void collectChildren() { + super.collectChildren(); + this.addDrawableChild(new DrawableWidget() { + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + ButtonWidget activeButton = ArmorStandPoseScreen.this.activePosePartButton; + if (activeButton == null) { + return; + } + + RenderSystem.setShaderColor(1f, 1f, 1f, 1f); + context.drawGuiTexture(SELECTION_TEXTURE, activeButton.getX() - 2, activeButton.getY() - 2, 24, 24); + } + }); + } - int offset = (CONTROL_WIDTH - 3 * IconButtonWidget.WIDTH - 2 * PART_PAD_HORIZONTAL) / 2; + @Override + protected void populateLayout() { + super.populateLayout(); - IconButtonWidget headButton = new IconButtonWidget( - offset + GuiUtil.PADDING + IconButtonWidget.WIDTH + PART_PAD_HORIZONTAL, - this.height - GuiUtil.PADDING - 3 * IconButtonWidget.HEIGHT - 2 * PART_PAD_VERTICAL - PART_PAD_VERTICAL - - BUTTON_HEIGHT, 6, PosePart.HEAD.getDisplayName(), (button) -> { - setActivePosePart(PosePart.HEAD); - this.activePosePartButton.active = true; - this.activePosePartButton = (IconButtonWidget) button; - this.activePosePartButton.active = false; - } - ); - headButton.active = false; - this.activePosePartButton = headButton; - addDrawableChild(headButton); + this.initPartPicker(); + this.initCore(); + } - IconButtonWidget rightArmButton = new IconButtonWidget(offset + GuiUtil.PADDING, - this.height - GuiUtil.PADDING - 2 * IconButtonWidget.HEIGHT - PART_PAD_VERTICAL - PART_PAD_VERTICAL - - BUTTON_HEIGHT, 8, PosePart.RIGHT_ARM.getDisplayName(), (button) -> { - setActivePosePart(PosePart.RIGHT_ARM); - this.activePosePartButton.active = true; - this.activePosePartButton = (IconButtonWidget) button; - this.activePosePartButton.active = false; - } - ); - addDrawableChild(rightArmButton); + private void initPartPicker() { + this.layout.bottomLeft.alignCenterX().spacing(2 * GuiUtil.PADDING); - IconButtonWidget bodyButton = new IconButtonWidget( - offset + GuiUtil.PADDING + IconButtonWidget.WIDTH + PART_PAD_HORIZONTAL, - this.height - GuiUtil.PADDING - 2 * IconButtonWidget.HEIGHT - PART_PAD_VERTICAL - PART_PAD_VERTICAL - - BUTTON_HEIGHT, 7, PosePart.BODY.getDisplayName(), (button) -> { - setActivePosePart(PosePart.BODY); - this.activePosePartButton.active = true; - this.activePosePartButton = (IconButtonWidget) button; - this.activePosePartButton.active = false; - } - ); - addDrawableChild(bodyButton); + IconButtonWidget headButton = this.layout.bottomLeft.add(IconButtonWidget.builder(HEAD_ICON, ArmorStandsMod.MOD_ID) + .onPress((button) -> setActivePosePart(button, PosePart.HEAD)) + .build()); + headButton.active = false; + this.activePosePartButton = headButton; - IconButtonWidget leftArmButton = new IconButtonWidget( - offset + GuiUtil.PADDING + 2 * IconButtonWidget.WIDTH + 2 * PART_PAD_HORIZONTAL, - this.height - GuiUtil.PADDING - 2 * IconButtonWidget.HEIGHT - PART_PAD_VERTICAL - PART_PAD_VERTICAL - - BUTTON_HEIGHT, 9, PosePart.LEFT_ARM.getDisplayName(), (button) -> { - setActivePosePart(PosePart.LEFT_ARM); - this.activePosePartButton.active = true; - this.activePosePartButton = (IconButtonWidget) button; - this.activePosePartButton.active = false; - } - ); - addDrawableChild(leftArmButton); + LinearLayoutWidget torsoRow = LinearLayoutWidget.horizontal().spacing(GuiUtil.PADDING).alignCenterX(); + torsoRow.add(IconButtonWidget.builder(RIGHT_ARM_ICON, ArmorStandsMod.MOD_ID) + .onPress((button) -> setActivePosePart(button, PosePart.RIGHT_ARM)) + .build()); + torsoRow.add(IconButtonWidget.builder(BODY_ICON, ArmorStandsMod.MOD_ID) + .onPress((button) -> setActivePosePart(button, PosePart.BODY)) + .build()); + torsoRow.add(IconButtonWidget.builder(LEFT_ARM_ICON, ArmorStandsMod.MOD_ID) + .onPress((button) -> setActivePosePart(button, PosePart.LEFT_ARM)) + .build()); + this.layout.bottomLeft.add(torsoRow); - IconButtonWidget rightLegButton = new IconButtonWidget( - offset + GuiUtil.PADDING + (IconButtonWidget.WIDTH + PART_PAD_HORIZONTAL) / 2, - this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT - PART_PAD_VERTICAL - BUTTON_HEIGHT, 11, - PosePart.RIGHT_LEG.getDisplayName(), (button) -> { - setActivePosePart(PosePart.RIGHT_LEG); - this.activePosePartButton.active = true; - this.activePosePartButton = (IconButtonWidget) button; - this.activePosePartButton.active = false; - } - ); - addDrawableChild(rightLegButton); - - IconButtonWidget leftLegButton = new IconButtonWidget( - offset + GuiUtil.PADDING + (IconButtonWidget.WIDTH + PART_PAD_HORIZONTAL) / 2 + IconButtonWidget.WIDTH + - PART_PAD_HORIZONTAL, - this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT - PART_PAD_VERTICAL - BUTTON_HEIGHT, 10, - PosePart.LEFT_LEG.getDisplayName(), (button) -> { - setActivePosePart(PosePart.LEFT_LEG); - this.activePosePartButton.active = true; - this.activePosePartButton = (IconButtonWidget) button; - this.activePosePartButton.active = false; - } - ); - addDrawableChild(leftLegButton); + LinearLayoutWidget feetRow = LinearLayoutWidget.horizontal().spacing(GuiUtil.PADDING).alignCenterX(); + feetRow.add(IconButtonWidget.builder(RIGHT_LEG_ICON, ArmorStandsMod.MOD_ID) + .onPress((button) -> setActivePosePart(button, PosePart.RIGHT_LEG)) + .build()); + feetRow.add(IconButtonWidget.builder(LEFT_LEG_ICON, ArmorStandsMod.MOD_ID) + .onPress((button) -> setActivePosePart(button, PosePart.LEFT_LEG)) + .build()); + this.layout.bottomLeft.add(feetRow); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.pose.mirror"), (button) -> { - ClientNetworking.sendSetPosePacket(new Pose(this.armorStand).mirror()); + this.layout.bottomLeft.add(ButtonWidget.builder(Text.translatable("armorstands.pose.mirror"), (button) -> { + ClientNetworking.sendSetPosePacket(new Pose(this.armorStand).mirror()); - this.pitchSlider.refresh(); - this.yawSlider.refresh(); - this.rollSlider.refresh(); - }) - .size(CONTROL_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING, this.height - GuiUtil.PADDING - BUTTON_HEIGHT) - .build()); + this.pitchSlider.refresh(); + this.yawSlider.refresh(); + this.rollSlider.refresh(); + }).size(CONTROL_WIDTH, BUTTON_HEIGHT).build()); } - @Override - protected void initRight() { - super.initRight(); + private void initCore() { + this.posePartLabel = this.layout.bottomRight.add(LabelWidget.builder(this.textRenderer, + Text.translatable("armorstands.pose.editing", this.posePart.getDisplayName()) + ).build()); - addDrawableChild(CyclingButtonWidget.builder(SliderRange::getDisplayName) + this.layout.bottomRight.add(CyclingButtonWidget.builder(SliderRange::getDisplayName) .initially(SliderRange.FULL) .values(SliderRange.values()) .omitKeyText() - .build(this.width - GuiUtil.PADDING - CONTROL_WIDTH, - this.height - GuiUtil.PADDING - 3 * SLIDER_HEIGHT - 3 * BUTTON_HEIGHT - 3 * (GuiUtil.PADDING / 2) - 3 * ROW_PAD - - 2 * LabelWidget.HEIGHT_WITH_PADDING, CONTROL_WIDTH, BUTTON_HEIGHT, - Text.translatable("armorstands.pose.range"), (button, value) -> { - this.pitchSlider.setRange(value.getMin(), value.getMax()); - this.yawSlider.setRange(value.getMin(), value.getMax()); - this.rollSlider.setRange(value.getMin(), value.getMax()); - } - )); - - this.posePartLabel = addLabel( - LabelWidget.builder(Text.translatable("armorstands.pose.editing", this.posePart.getDisplayName().getString()), - this.width - GuiUtil.PADDING, - this.height - GuiUtil.PADDING - 3 * SLIDER_HEIGHT - 3 * BUTTON_HEIGHT - 4 * (GuiUtil.PADDING / 2) - 3 * ROW_PAD - - 2 * LabelWidget.HEIGHT_WITH_PADDING - ).shiftForPadding().alignedBottom().justifiedRight().build()); - - this.pitchSlider = addAdjustSlider(EulerAngleParameter.PITCH, 2); - this.yawSlider = addAdjustSlider(EulerAngleParameter.YAW, 1); - this.rollSlider = addAdjustSlider(EulerAngleParameter.ROLL, 0); + .build(Text.translatable("armorstands.pose.range"), (button, value) -> { + this.pitchSlider.setRange(value.getMin(), value.getMax()); + this.yawSlider.setRange(value.getMin(), value.getMax()); + this.rollSlider.setRange(value.getMin(), value.getMax()); + }), (adder) -> { + adder.layoutHook((parent, self) -> self.setDimensions(CONTROL_WIDTH, BUTTON_HEIGHT)); + adder.margin(Spacing.of(0, 0, 2 * GuiUtil.PADDING, 0)); + }); + + this.pitchSlider = addAdjustSlider(EulerAngleParameter.PITCH); + this.yawSlider = addAdjustSlider(EulerAngleParameter.YAW); + this.rollSlider = addAdjustSlider(EulerAngleParameter.ROLL); } - private AdjustPoseSliderWidget addAdjustSlider(EulerAngleParameter parameter, int index) { - int refRight = this.width - GuiUtil.PADDING; - int refLeft = refRight - CONTROL_WIDTH; - int refY = - this.height - GuiUtil.PADDING - SLIDER_HEIGHT - index * (SLIDER_HEIGHT + BUTTON_HEIGHT + (GuiUtil.PADDING / 2) + ROW_PAD); + private AdjustPoseSliderWidget addAdjustSlider(EulerAngleParameter parameter) { + AdjustPoseSliderWidget slider = new AdjustPoseSliderWidget( + CONTROL_WIDTH, SLIDER_HEIGHT, this.posePart, parameter, this.armorStand); - AdjustPoseSliderWidget slider = new AdjustPoseSliderWidget(refLeft, refY, CONTROL_WIDTH, SLIDER_HEIGHT, - this.posePart, parameter, this.armorStand + LinearLayoutWidget firstRow = LinearLayoutWidget.horizontal().alignBottom().spacing(GuiUtil.PADDING); + firstRow.add( + LabelWidget.builder(this.textRenderer, parameter.getDisplayName()).justifiedLeft().alignedBottom().build(), + (parent, self) -> { + self.setWidth(CONTROL_WIDTH - 3 * (BUTTON_WIDTH + parent.getSpacing())); + } ); - - addLabel(LabelWidget.builder(parameter.getDisplayName(), refLeft, refY - (GuiUtil.PADDING / 2)) - .alignedBottom() - .justifiedLeft() - .shiftForPadding() - .build()); - addDrawableChild(ButtonWidget.builder(Text.literal("-"), (button) -> slider.decrement()) + firstRow.add(ButtonWidget.builder(Text.literal("-"), (button) -> slider.decrement()) .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(refRight - 3 * BUTTON_WIDTH - 2 * (GuiUtil.PADDING / 2), refY - (GuiUtil.PADDING / 2) - BUTTON_HEIGHT) .tooltip(Tooltip.of(Text.translatable("armorstands.pose.subtract"))) .build()); - addDrawableChild(ButtonWidget.builder(Text.literal("+"), (button) -> slider.increment()) + firstRow.add(ButtonWidget.builder(Text.literal("+"), (button) -> slider.increment()) .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(refRight - 2 * BUTTON_WIDTH - (GuiUtil.PADDING / 2), refY - (GuiUtil.PADDING / 2) - BUTTON_HEIGHT) .tooltip(Tooltip.of(Text.translatable("armorstands.pose.add"))) .build()); - addDrawableChild(ButtonWidget.builder(Text.literal("0"), (button) -> slider.zero()) + firstRow.add(ButtonWidget.builder(Text.literal("0"), (button) -> slider.zero()) .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(refRight - BUTTON_WIDTH, refY - (GuiUtil.PADDING / 2) - BUTTON_HEIGHT) .tooltip(Tooltip.of(Text.translatable("armorstands.pose.zero"))) .build()); - addDrawableChild(slider); + this.layout.bottomRight.add(firstRow, (adder) -> adder.margin(Spacing.of(GuiUtil.PADDING, 0, 0, 0))); + + this.layout.bottomRight.add(slider); return slider; } @@ -242,43 +208,27 @@ protected void handledScreenTick() { this.rollSlider.tick(); } - @Override - protected void renderActivePageButtonHighlight(DrawContext drawContext) { - super.renderActivePageButtonHighlight(drawContext); - - if (this.activePosePartButton == null) { - return; - } - - RenderSystem.setShaderColor(1f, 1f, 1f, 1f); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - - MatrixStack matrixStack = drawContext.getMatrices(); - matrixStack.push(); - matrixStack.translate(0, 0, 100); - drawContext.drawTexture(SELECTION_TEXTURE, this.activePosePartButton.getX() - 2, - this.activePosePartButton.getY() - 2, 0, 0, 24, 24, 24, 24 - ); - matrixStack.pop(); - } - - private void setActivePosePart(PosePart part) { + private void setActivePosePart(ButtonWidget button, PosePart part) { this.posePart = part; this.pitchSlider.setPart(part); this.yawSlider.setPart(part); this.rollSlider.setPart(part); - this.posePartLabel.setText( - Text.translatable("armorstands.pose.editing", this.posePart.getDisplayName().getString())); + this.posePartLabel.setText(Text.translatable("armorstands.pose.editing", this.posePart.getDisplayName())); + + if (this.activePosePartButton != null) { + this.activePosePartButton.active = true; + } + this.activePosePartButton = button; + this.activePosePartButton.active = false; } - private static enum SliderRange { + private enum SliderRange { FULL(-180, 180), HALF(-90, 90), TIGHT(-35, 35); private final int min; private final int max; - private SliderRange(int min, int max) { + SliderRange(int min, int max) { this.min = min; this.max = max; } diff --git a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandPresetsScreen.java b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandPresetsScreen.java index 94ce1d7..ce589c0 100644 --- a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandPresetsScreen.java +++ b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandPresetsScreen.java @@ -41,152 +41,157 @@ public ScreenType getScreenType() { return ScreenType.PRESETS; } - @Override - protected void initStart() { - super.initStart(); - - this.presetButtons.clear(); - } - - @Override - protected void initRight() { - super.initRight(); - - addLabel(LabelWidget.builder(Text.translatable("armorstands.presets.source.label"), this.width - GuiUtil.PADDING, - this.height - GuiUtil.PADDING - (BUTTONS_PER_PAGE + 2) * CONTROL_HEIGHT - (BUTTONS_PER_PAGE + 3) * (GuiUtil.PADDING / 2) - - IconButtonWidget.HEIGHT - CONTROL_HEIGHT - LabelWidget.HEIGHT_WITH_PADDING - 3 * (GuiUtil.PADDING / 2) - ).alignedBottom().justifiedRight().shiftForPadding().build()); - addDrawableChild(CyclingButtonWidget.builder(Source::getDisplayName) - .values(Source.getSources()) - .initially(Source.ALL) - .omitKeyText() - .build(this.width - GuiUtil.PADDING - CONTROL_WIDTH, - this.height - GuiUtil.PADDING - (BUTTONS_PER_PAGE + 2) * CONTROL_HEIGHT - - (BUTTONS_PER_PAGE + 2) * (GuiUtil.PADDING / 2) - IconButtonWidget.HEIGHT - CONTROL_HEIGHT - - LabelWidget.HEIGHT_WITH_PADDING - 3 * (GuiUtil.PADDING / 2), CONTROL_WIDTH, CONTROL_HEIGHT, - Text.translatable("armorstands.presets.source.label"), (button, source) -> { - filter(source); - } - )); - - addLabel(LabelWidget.builder(Text.translatable("armorstands.presets.category.label"), this.width - GuiUtil.PADDING, - this.height - GuiUtil.PADDING - (BUTTONS_PER_PAGE + 2) * CONTROL_HEIGHT - (BUTTONS_PER_PAGE + 3) * (GuiUtil.PADDING / 2) - - IconButtonWidget.HEIGHT - ).alignedBottom().justifiedRight().shiftForPadding().build()); - addDrawableChild(CyclingButtonWidget.builder(Category::getDisplayName) - .values(Category.getCategories()) - .initially(Category.ALL) - .omitKeyText() - .build(this.width - GuiUtil.PADDING - CONTROL_WIDTH, - this.height - GuiUtil.PADDING - (BUTTONS_PER_PAGE + 2) * CONTROL_HEIGHT - - (BUTTONS_PER_PAGE + 2) * (GuiUtil.PADDING / 2) - IconButtonWidget.HEIGHT, CONTROL_WIDTH, CONTROL_HEIGHT, - Text.translatable("armorstands.presets.category.label"), (button, category) -> { - filter(category); - } - )); - - for (int i = BUTTONS_PER_PAGE; i > 0; i--) { - this.presetButtons.add(addDrawableChild(new PresetPoseButtonWidget(this.width - GuiUtil.PADDING - CONTROL_WIDTH, - this.height - GuiUtil.PADDING - i * CONTROL_HEIGHT - i * (GuiUtil.PADDING / 2) - IconButtonWidget.HEIGHT, CONTROL_WIDTH, - CONTROL_HEIGHT - ))); - } - - this.prevPageButton = addDrawableChild(new IconButtonWidget(this.width - GuiUtil.PADDING - CONTROL_WIDTH, - this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT, 12, Text.translatable("armorstands.presets.previous"), - (button) -> previousPage() - )); - this.nextPageButton = addDrawableChild(new IconButtonWidget(this.width - GuiUtil.PADDING - IconButtonWidget.WIDTH, - this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT, 13, Text.translatable("armorstands.presets.next"), - (button) -> nextPage() - )); - - int maxPage = - MathHelper.ceil(PosePreset.getPresets(this.source, this.category).size() / (float) BUTTONS_PER_PAGE) - 1; - this.pageLabel = addLabel( - LabelWidget.builder(Text.translatable("armorstands.presets.page", this.page + 1, maxPage + 1), - this.width - GuiUtil.PADDING - CONTROL_WIDTH / 2, - this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT / 2 - ).alignedMiddle().justifiedCenter().build()); - } - - @Override - protected void initEnd() { - updateFilters(); - } - - @Override - public boolean mouseScrolled( - double mouseX, double mouseY, double horizontalAmount, double verticalAmount - ) { - if (isMouseOverList(mouseX, mouseY)) { - if (verticalAmount < 0) { - nextPage(); - } else { - previousPage(); - } - return true; - } - return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); - } - - private void filter(Source source) { - this.source = source; - updateFilters(); - } - - private void filter(Category category) { - this.category = category; - updateFilters(); - } - - private void updateFilters() { - this.matchingPresets = PosePreset.getPresets(this.source, this.category); - setPage(0); - } - - private void setPage(int page) { - int maxPage = Math.max(0, MathHelper.ceil(this.matchingPresets.size() / (float) BUTTONS_PER_PAGE) - 1); - - this.page = page; - List presets = this.matchingPresets.subList(page * BUTTONS_PER_PAGE, - Math.min((page + 1) * BUTTONS_PER_PAGE, this.matchingPresets.size()) - ); - - for (int i = 0; i < BUTTONS_PER_PAGE; i++) { - if (i < presets.size()) { - this.presetButtons.get(i).setPose(presets.get(i)); - this.presetButtons.get(i).visible = true; - } else { - this.presetButtons.get(i).visible = false; - } - } - - if (this.presetButtons.contains(getFocused())) { - setFocused(this.presetButtons.get(0)); - } - - this.prevPageButton.active = this.page > 0; - this.nextPageButton.active = this.page < maxPage; - this.pageLabel.setText(Text.translatable("armorstands.presets.page", this.page + 1, maxPage + 1)); - } - - private void nextPage() { - int maxPage = MathHelper.ceil(this.matchingPresets.size() / (float) BUTTONS_PER_PAGE) - 1; - if (this.page < maxPage) { - setPage(this.page + 1); - } - } - - private void previousPage() { - if (this.page > 0) { - setPage(this.page - 1); - } - } - - private boolean isMouseOverList(double mouseX, double mouseY) { - return mouseX >= this.width - GuiUtil.PADDING - CONTROL_WIDTH && mouseX < this.width - GuiUtil.PADDING && mouseY >= - this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT - BUTTONS_PER_PAGE * CONTROL_HEIGHT - - (BUTTONS_PER_PAGE + 1) * (GuiUtil.PADDING / 2) && mouseY < this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT; - } +// @Override +// protected void initStart() { +// super.initStart(); +// +// this.presetButtons.clear(); +// } +// +// @Override +// protected void initRight() { +// super.initRight(); +// +// // addLabel(LabelWidget.builder(Text.translatable("armorstands.presets.source.label"), this.width - GuiUtil +// // .PADDING, +// // this.height - GuiUtil.PADDING - (BUTTONS_PER_PAGE + 2) * CONTROL_HEIGHT - (BUTTONS_PER_PAGE + 3) * +// // (GuiUtil.PADDING / 2) - +// // IconButtonWidget.HEIGHT - CONTROL_HEIGHT - LabelWidget.HEIGHT_WITH_PADDING - 3 * (GuiUtil.PADDING / 2) +// // ).alignedBottom().justifiedRight().shiftForPadding().build()); +// addDrawableChild(CyclingButtonWidget.builder(Source::getDisplayName) +// .values(Source.getSources()) +// .initially(Source.ALL) +// .omitKeyText() +// .build(this.width - GuiUtil.PADDING - CONTROL_WIDTH, +// this.height - GuiUtil.PADDING - (BUTTONS_PER_PAGE + 2) * CONTROL_HEIGHT - +// (BUTTONS_PER_PAGE + 2) * (GuiUtil.PADDING / 2) - IconButtonWidget.HEIGHT - CONTROL_HEIGHT - +// LabelWidget.HEIGHT_WITH_PADDING - 3 * (GuiUtil.PADDING / 2), CONTROL_WIDTH, CONTROL_HEIGHT, +// Text.translatable("armorstands.presets.source.label"), (button, source) -> { +// filter(source); +// } +// )); +// +// // addLabel(LabelWidget.builder(Text.translatable("armorstands.presets.category.label"), this.width - GuiUtil +// // .PADDING, +// // this.height - GuiUtil.PADDING - (BUTTONS_PER_PAGE + 2) * CONTROL_HEIGHT - (BUTTONS_PER_PAGE + 3) * +// // (GuiUtil.PADDING / 2) - +// // IconButtonWidget.HEIGHT +// // ).alignedBottom().justifiedRight().shiftForPadding().build()); +// addDrawableChild(CyclingButtonWidget.builder(Category::getDisplayName) +// .values(Category.getCategories()) +// .initially(Category.ALL) +// .omitKeyText() +// .build(this.width - GuiUtil.PADDING - CONTROL_WIDTH, +// this.height - GuiUtil.PADDING - (BUTTONS_PER_PAGE + 2) * CONTROL_HEIGHT - +// (BUTTONS_PER_PAGE + 2) * (GuiUtil.PADDING / 2) - IconButtonWidget.HEIGHT, CONTROL_WIDTH, CONTROL_HEIGHT, +// Text.translatable("armorstands.presets.category.label"), (button, category) -> { +// filter(category); +// } +// )); +// +// for (int i = BUTTONS_PER_PAGE; i > 0; i--) { +// this.presetButtons.add(addDrawableChild(new PresetPoseButtonWidget(this.width - GuiUtil.PADDING - CONTROL_WIDTH, +// this.height - GuiUtil.PADDING - i * CONTROL_HEIGHT - i * (GuiUtil.PADDING / 2) - IconButtonWidget.HEIGHT, +// CONTROL_WIDTH, CONTROL_HEIGHT +// ))); +// } +// +// this.prevPageButton = addDrawableChild(new IconButtonWidget(this.width - GuiUtil.PADDING - CONTROL_WIDTH, +// this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT, 12, Text.translatable("armorstands.presets.previous"), +// (button) -> previousPage() +// )); +// this.nextPageButton = addDrawableChild(new IconButtonWidget(this.width - GuiUtil.PADDING - IconButtonWidget.WIDTH, +// this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT, 13, Text.translatable("armorstands.presets.next"), +// (button) -> nextPage() +// )); +// +// int maxPage = +// MathHelper.ceil(PosePreset.getPresets(this.source, this.category).size() / (float) BUTTONS_PER_PAGE) - 1; +// // this.pageLabel = addLabel( +// // LabelWidget.builder(Text.translatable("armorstands.presets.page", this.page + 1, maxPage + 1), +// // this.width - GuiUtil.PADDING - CONTROL_WIDTH / 2, +// // this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT / 2 +// // ).alignedMiddle().justifiedCenter().build()); +// } +// +// @Override +// protected void initEnd() { +// updateFilters(); +// } +// +// @Override +// public boolean mouseScrolled( +// double mouseX, double mouseY, double horizontalAmount, double verticalAmount +// ) { +// if (isMouseOverList(mouseX, mouseY)) { +// if (verticalAmount < 0) { +// nextPage(); +// } else { +// previousPage(); +// } +// return true; +// } +// return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); +// } +// +// private void filter(Source source) { +// this.source = source; +// updateFilters(); +// } +// +// private void filter(Category category) { +// this.category = category; +// updateFilters(); +// } +// +// private void updateFilters() { +// this.matchingPresets = PosePreset.getPresets(this.source, this.category); +// setPage(0); +// } +// +// private void setPage(int page) { +// int maxPage = Math.max(0, MathHelper.ceil(this.matchingPresets.size() / (float) BUTTONS_PER_PAGE) - 1); +// +// this.page = page; +// List presets = this.matchingPresets.subList(page * BUTTONS_PER_PAGE, +// Math.min((page + 1) * BUTTONS_PER_PAGE, this.matchingPresets.size()) +// ); +// +// for (int i = 0; i < BUTTONS_PER_PAGE; i++) { +// if (i < presets.size()) { +// this.presetButtons.get(i).setPose(presets.get(i)); +// this.presetButtons.get(i).visible = true; +// } else { +// this.presetButtons.get(i).visible = false; +// } +// } +// +// if (this.presetButtons.contains(getFocused())) { +// setFocused(this.presetButtons.get(0)); +// } +// +// this.prevPageButton.active = this.page > 0; +// this.nextPageButton.active = this.page < maxPage; +// // this.pageLabel.setText(Text.translatable("armorstands.presets.page", this.page + 1, maxPage + 1)); +// } +// +// private void nextPage() { +// int maxPage = MathHelper.ceil(this.matchingPresets.size() / (float) BUTTONS_PER_PAGE) - 1; +// if (this.page < maxPage) { +// setPage(this.page + 1); +// } +// } +// +// private void previousPage() { +// if (this.page > 0) { +// setPage(this.page - 1); +// } +// } +// +// private boolean isMouseOverList(double mouseX, double mouseY) { +// return mouseX >= this.width - GuiUtil.PADDING - CONTROL_WIDTH && mouseX < this.width - GuiUtil.PADDING && mouseY >= +// this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT - BUTTONS_PER_PAGE * CONTROL_HEIGHT - +// (BUTTONS_PER_PAGE + 1) * (GuiUtil.PADDING / 2) && +// mouseY < this.height - GuiUtil.PADDING - IconButtonWidget.HEIGHT; +// } } diff --git a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandRotateScreen.java b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandRotateScreen.java index f1579bb..39facc1 100644 --- a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandRotateScreen.java +++ b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandRotateScreen.java @@ -41,207 +41,207 @@ public ScreenType getScreenType() { return ScreenType.ROTATE; } - @Override - protected void initLeft() { - super.initLeft(); - - initCurrentStatus(); - initSnapButtons(); - initFaceButtons(); - } - - private void initCurrentStatus() { - addLabel(LabelWidget.builder(Text.translatable("armorstands.current.player"), GuiUtil.PADDING, - GuiUtil.PADDING + IconButtonWidget.HEIGHT + LabelWidget.HEIGHT_WITH_PADDING - ).alignedTop().justifiedLeft().shiftForPadding().build()); - - this.playerFacingLabel = addLabel(LabelWidget.builder(getCurrentFacingText(this.client.player), GuiUtil.PADDING, - GuiUtil.PADDING + IconButtonWidget.HEIGHT + 2 * LabelWidget.HEIGHT_WITH_PADDING - ).alignedTop().justifiedLeft().shiftForPadding().build()); - - this.playerRotationLabel = addLabel(LabelWidget.builder(getCurrentRotationText(this.client.player), GuiUtil.PADDING, - GuiUtil.PADDING + IconButtonWidget.HEIGHT + 3 * LabelWidget.HEIGHT_WITH_PADDING - ).alignedTop().justifiedLeft().shiftForPadding().build()); - - addLabel(LabelWidget.builder(Text.translatable("armorstands.current.stand"), GuiUtil.PADDING, - GuiUtil.PADDING + IconButtonWidget.HEIGHT + 5 * LabelWidget.HEIGHT_WITH_PADDING - ).alignedTop().justifiedLeft().shiftForPadding().build()); - - this.standFacingLabel = addLabel(LabelWidget.builder(getCurrentFacingText(this.armorStand), GuiUtil.PADDING, - GuiUtil.PADDING + IconButtonWidget.HEIGHT + 6 * LabelWidget.HEIGHT_WITH_PADDING - ).alignedTop().justifiedLeft().shiftForPadding().build()); - - this.standRotationLabel = addLabel(LabelWidget.builder(getCurrentRotationText(this.armorStand), GuiUtil.PADDING, - GuiUtil.PADDING + IconButtonWidget.HEIGHT + 7 * LabelWidget.HEIGHT_WITH_PADDING - ).alignedTop().justifiedLeft().shiftForPadding().build()); - } - - private void initSnapButtons() { - addLabel(LabelWidget.builder(Text.translatable("armorstands.rotate.snap"), GuiUtil.PADDING, - this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 4 * (GuiUtil.PADDING / 2) - LabelWidget.HEIGHT_WITH_PADDING - ).shiftForPadding().justifiedLeft().alignedBottom().build()); - - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.snap." + Direction.SOUTH.getName()), - (button) -> ClientNetworking.sendSetYawPacket(MathHelper.wrapDegrees(Direction.SOUTH.asRotation())) - ) - .size(DIRECTION_BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING, - this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 3 * (GuiUtil.PADDING / 2) - LabelWidget.HEIGHT_WITH_PADDING - ) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.snap." + Direction.NORTH.getName()), - (button) -> ClientNetworking.sendSetYawPacket(MathHelper.wrapDegrees(Direction.NORTH.asRotation())) - ) - .size(DIRECTION_BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING + DIRECTION_BUTTON_WIDTH + (GuiUtil.PADDING / 2), - this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 3 * (GuiUtil.PADDING / 2) - LabelWidget.HEIGHT_WITH_PADDING - ) - .build()); - - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.snap." + Direction.EAST.getName()), - (button) -> ClientNetworking.sendSetYawPacket(MathHelper.wrapDegrees(Direction.EAST.asRotation())) - ) - .size(DIRECTION_BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING, - this.height - GuiUtil.PADDING - 2 * BUTTON_HEIGHT - 2 * (GuiUtil.PADDING / 2) - LabelWidget.HEIGHT_WITH_PADDING - ) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.snap." + Direction.WEST.getName()), - (button) -> ClientNetworking.sendSetYawPacket(MathHelper.wrapDegrees(Direction.WEST.asRotation())) - ) - .size(DIRECTION_BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING + DIRECTION_BUTTON_WIDTH + (GuiUtil.PADDING / 2), - this.height - GuiUtil.PADDING - 2 * BUTTON_HEIGHT - 2 * (GuiUtil.PADDING / 2) - LabelWidget.HEIGHT_WITH_PADDING - ) - .build()); - } - - private void initFaceButtons() { - addLabel(LabelWidget.builder(Text.translatable("armorstands.rotate.face"), GuiUtil.PADDING, - this.height - GuiUtil.PADDING - BUTTON_HEIGHT - (GuiUtil.PADDING / 2) - ).shiftForPadding().justifiedLeft().alignedBottom().build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.face.toward"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.FACE_TOWARD) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING, this.height - GuiUtil.PADDING - BUTTON_HEIGHT) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.face.away"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.FACE_AWAY) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING + BUTTON_WIDTH + (GuiUtil.PADDING / 2), this.height - GuiUtil.PADDING - BUTTON_HEIGHT) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.face.with"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.FACE_WITH) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING + 2 * (BUTTON_WIDTH + (GuiUtil.PADDING / 2)), this.height - GuiUtil.PADDING - BUTTON_HEIGHT) - .build()); - } - - @Override - protected void initRight() { - super.initRight(); - - addRowOfButtons(RotateDirection.CLOCKWISE, 1); - addRowOfButtons(RotateDirection.COUNTERCLOCKWISE, 0); - - this.rotateSlider = addDrawableChild(new RotateSliderWidget(this, this.width - GuiUtil.PADDING - SLIDER_WIDTH, - this.height - GuiUtil.PADDING - SLIDER_HEIGHT, SLIDER_WIDTH, SLIDER_HEIGHT, this.armorStand - )); - } - - private void addRowOfButtons(RotateDirection direction, int index) { - int refX = this.width - GuiUtil.PADDING - MINI_BUTTON_WIDTH; - int refY = this.height - GuiUtil.PADDING - SLIDER_HEIGHT - 2 * (GuiUtil.PADDING / 2) - MINI_BUTTON_HEIGHT - - index * (2 * (GuiUtil.PADDING / 2) + MINI_BUTTON_HEIGHT + LabelWidget.HEIGHT_WITH_PADDING); - String modifier = direction.equals(RotateDirection.CLOCKWISE) ? "+" : "-"; - - addLabel(LabelWidget.builder(direction.getLabel(), this.width - GuiUtil.PADDING, refY - (GuiUtil.PADDING / 2)) - .justifiedRight() - .alignedBottom() - .shiftForPadding() - .build()); - addDrawableChild(ButtonWidget.builder(Text.literal(modifier + "1"), - (button) -> ClientNetworking.sendAdjustYawPacket(direction.offset()) - ) - .size(MINI_BUTTON_WIDTH, MINI_BUTTON_HEIGHT) - .position(refX - 3 * ((GuiUtil.PADDING / 2) + MINI_BUTTON_WIDTH), refY) - .build()); - addDrawableChild(ButtonWidget.builder(Text.literal(modifier + "5"), - (button) -> ClientNetworking.sendAdjustYawPacket(direction.offset() * 5) - ) - .size(MINI_BUTTON_WIDTH, MINI_BUTTON_HEIGHT) - .position(refX - 2 * ((GuiUtil.PADDING / 2) + MINI_BUTTON_WIDTH), refY) - .build()); - addDrawableChild(ButtonWidget.builder(Text.literal(modifier + "15"), - (button) -> ClientNetworking.sendAdjustYawPacket(direction.offset() * 15) - ) - .size(MINI_BUTTON_WIDTH, MINI_BUTTON_HEIGHT) - .position(refX - ((GuiUtil.PADDING / 2) + MINI_BUTTON_WIDTH), refY) - .build()); - addDrawableChild(ButtonWidget.builder(Text.literal(modifier + "45"), - (button) -> ClientNetworking.sendAdjustYawPacket(direction.offset() * 45) - ) - .size(MINI_BUTTON_WIDTH, MINI_BUTTON_HEIGHT) - .position(refX, refY) - .build()); - } - - @Override - public void handledScreenTick() { - super.handledScreenTick(); - - this.playerFacingLabel.setText(getCurrentFacingText(this.client.player)); - this.playerRotationLabel.setText(getCurrentRotationText(this.client.player)); - this.standFacingLabel.setText(getCurrentFacingText(this.armorStand)); - this.standRotationLabel.setText(getCurrentRotationText(this.armorStand)); - this.rotateSlider.tick(); - } - - @Override - public void updateYawOnClient(float yaw) { - if (this.rotateSlider != null && this.rotateSlider.isPending(this)) { - return; - } - - super.updateYawOnClient(yaw); - - if (this.rotateSlider != null) { - this.rotateSlider.setAngle(yaw); - } - } - - @Override - public void onPong() { - super.onPong(); - - if (this.rotateSlider != null) { - this.rotateSlider.onPong(); - } - } - - private Text getCurrentFacingText(Entity entity) { - float currentRotation = entity.getYaw(); - Direction currentFacing = Direction.fromRotation(currentRotation); - String towardsI18n = switch (currentFacing) { - case NORTH -> "negZ"; - case SOUTH -> "posZ"; - case WEST -> "negX"; - case EAST -> "posX"; - default -> "posX"; - }; - Text towards = Text.translatable("armorstands.current.facing." + towardsI18n); - return Text.translatable("armorstands.current.facing", currentFacing.toString(), towards.getString()); - } - - private Text getCurrentRotationText(Entity entity) { - float currentRotation = entity.getYaw(); - return Text.translatable("armorstands.current.rotation", - String.format(Locale.ROOT, "%.1f", MathHelper.wrapDegrees(currentRotation)) - ); - } +// @Override +// protected void initLeft() { +// super.initLeft(); +// +// initCurrentStatus(); +// initSnapButtons(); +// initFaceButtons(); +// } +// +// private void initCurrentStatus() { +//// addLabel(LabelWidget.builder(Text.translatable("armorstands.current.player"), GuiUtil.PADDING, +//// GuiUtil.PADDING + IconButtonWidget.HEIGHT + LabelWidget.HEIGHT_WITH_PADDING +//// ).alignedTop().justifiedLeft().shiftForPadding().build()); +//// +//// this.playerFacingLabel = addLabel(LabelWidget.builder(getCurrentFacingText(this.client.player), GuiUtil.PADDING, +//// GuiUtil.PADDING + IconButtonWidget.HEIGHT + 2 * LabelWidget.HEIGHT_WITH_PADDING +//// ).alignedTop().justifiedLeft().shiftForPadding().build()); +//// +//// this.playerRotationLabel = addLabel(LabelWidget.builder(getCurrentRotationText(this.client.player), GuiUtil.PADDING, +//// GuiUtil.PADDING + IconButtonWidget.HEIGHT + 3 * LabelWidget.HEIGHT_WITH_PADDING +//// ).alignedTop().justifiedLeft().shiftForPadding().build()); +//// +//// addLabel(LabelWidget.builder(Text.translatable("armorstands.current.stand"), GuiUtil.PADDING, +//// GuiUtil.PADDING + IconButtonWidget.HEIGHT + 5 * LabelWidget.HEIGHT_WITH_PADDING +//// ).alignedTop().justifiedLeft().shiftForPadding().build()); +//// +//// this.standFacingLabel = addLabel(LabelWidget.builder(getCurrentFacingText(this.armorStand), GuiUtil.PADDING, +//// GuiUtil.PADDING + IconButtonWidget.HEIGHT + 6 * LabelWidget.HEIGHT_WITH_PADDING +//// ).alignedTop().justifiedLeft().shiftForPadding().build()); +//// +//// this.standRotationLabel = addLabel(LabelWidget.builder(getCurrentRotationText(this.armorStand), GuiUtil.PADDING, +//// GuiUtil.PADDING + IconButtonWidget.HEIGHT + 7 * LabelWidget.HEIGHT_WITH_PADDING +//// ).alignedTop().justifiedLeft().shiftForPadding().build()); +// } +// +// private void initSnapButtons() { +//// addLabel(LabelWidget.builder(Text.translatable("armorstands.rotate.snap"), GuiUtil.PADDING, +//// this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 4 * (GuiUtil.PADDING / 2) - LabelWidget.HEIGHT_WITH_PADDING +//// ).shiftForPadding().justifiedLeft().alignedBottom().build()); +// +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.snap." + Direction.SOUTH.getName()), +// (button) -> ClientNetworking.sendSetYawPacket(MathHelper.wrapDegrees(Direction.SOUTH.asRotation())) +// ) +// .size(DIRECTION_BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING, +// this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 3 * (GuiUtil.PADDING / 2) - LabelWidget.HEIGHT_WITH_PADDING +// ) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.snap." + Direction.NORTH.getName()), +// (button) -> ClientNetworking.sendSetYawPacket(MathHelper.wrapDegrees(Direction.NORTH.asRotation())) +// ) +// .size(DIRECTION_BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING + DIRECTION_BUTTON_WIDTH + (GuiUtil.PADDING / 2), +// this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 3 * (GuiUtil.PADDING / 2) - LabelWidget.HEIGHT_WITH_PADDING +// ) +// .build()); +// +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.snap." + Direction.EAST.getName()), +// (button) -> ClientNetworking.sendSetYawPacket(MathHelper.wrapDegrees(Direction.EAST.asRotation())) +// ) +// .size(DIRECTION_BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING, +// this.height - GuiUtil.PADDING - 2 * BUTTON_HEIGHT - 2 * (GuiUtil.PADDING / 2) - LabelWidget.HEIGHT_WITH_PADDING +// ) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.snap." + Direction.WEST.getName()), +// (button) -> ClientNetworking.sendSetYawPacket(MathHelper.wrapDegrees(Direction.WEST.asRotation())) +// ) +// .size(DIRECTION_BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING + DIRECTION_BUTTON_WIDTH + (GuiUtil.PADDING / 2), +// this.height - GuiUtil.PADDING - 2 * BUTTON_HEIGHT - 2 * (GuiUtil.PADDING / 2) - LabelWidget.HEIGHT_WITH_PADDING +// ) +// .build()); +// } +// +// private void initFaceButtons() { +//// addLabel(LabelWidget.builder(Text.translatable("armorstands.rotate.face"), GuiUtil.PADDING, +//// this.height - GuiUtil.PADDING - BUTTON_HEIGHT - (GuiUtil.PADDING / 2) +//// ).shiftForPadding().justifiedLeft().alignedBottom().build()); +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.face.toward"), +// (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.FACE_TOWARD) +// ) +// .size(BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING, this.height - GuiUtil.PADDING - BUTTON_HEIGHT) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.face.away"), +// (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.FACE_AWAY) +// ) +// .size(BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING + BUTTON_WIDTH + (GuiUtil.PADDING / 2), this.height - GuiUtil.PADDING - BUTTON_HEIGHT) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.rotate.face.with"), +// (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.FACE_WITH) +// ) +// .size(BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING + 2 * (BUTTON_WIDTH + (GuiUtil.PADDING / 2)), this.height - GuiUtil.PADDING - BUTTON_HEIGHT) +// .build()); +// } +// +// @Override +// protected void initRight() { +// super.initRight(); +// +// addRowOfButtons(RotateDirection.CLOCKWISE, 1); +// addRowOfButtons(RotateDirection.COUNTERCLOCKWISE, 0); +// +// this.rotateSlider = addDrawableChild(new RotateSliderWidget(this, this.width - GuiUtil.PADDING - SLIDER_WIDTH, +// this.height - GuiUtil.PADDING - SLIDER_HEIGHT, SLIDER_WIDTH, SLIDER_HEIGHT, this.armorStand +// )); +// } +// +// private void addRowOfButtons(RotateDirection direction, int index) { +// int refX = this.width - GuiUtil.PADDING - MINI_BUTTON_WIDTH; +// int refY = this.height - GuiUtil.PADDING - SLIDER_HEIGHT - 2 * (GuiUtil.PADDING / 2) - MINI_BUTTON_HEIGHT - +// index * (2 * (GuiUtil.PADDING / 2) + MINI_BUTTON_HEIGHT + LabelWidget.HEIGHT_WITH_PADDING); +// String modifier = direction.equals(RotateDirection.CLOCKWISE) ? "+" : "-"; +// +//// addLabel(LabelWidget.builder(direction.getLabel(), this.width - GuiUtil.PADDING, refY - (GuiUtil.PADDING / 2)) +//// .justifiedRight() +//// .alignedBottom() +//// .shiftForPadding() +//// .build()); +// addDrawableChild(ButtonWidget.builder(Text.literal(modifier + "1"), +// (button) -> ClientNetworking.sendAdjustYawPacket(direction.offset()) +// ) +// .size(MINI_BUTTON_WIDTH, MINI_BUTTON_HEIGHT) +// .position(refX - 3 * ((GuiUtil.PADDING / 2) + MINI_BUTTON_WIDTH), refY) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.literal(modifier + "5"), +// (button) -> ClientNetworking.sendAdjustYawPacket(direction.offset() * 5) +// ) +// .size(MINI_BUTTON_WIDTH, MINI_BUTTON_HEIGHT) +// .position(refX - 2 * ((GuiUtil.PADDING / 2) + MINI_BUTTON_WIDTH), refY) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.literal(modifier + "15"), +// (button) -> ClientNetworking.sendAdjustYawPacket(direction.offset() * 15) +// ) +// .size(MINI_BUTTON_WIDTH, MINI_BUTTON_HEIGHT) +// .position(refX - ((GuiUtil.PADDING / 2) + MINI_BUTTON_WIDTH), refY) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.literal(modifier + "45"), +// (button) -> ClientNetworking.sendAdjustYawPacket(direction.offset() * 45) +// ) +// .size(MINI_BUTTON_WIDTH, MINI_BUTTON_HEIGHT) +// .position(refX, refY) +// .build()); +// } +// +// @Override +// public void handledScreenTick() { +// super.handledScreenTick(); +// +//// this.playerFacingLabel.setText(getCurrentFacingText(this.client.player)); +//// this.playerRotationLabel.setText(getCurrentRotationText(this.client.player)); +//// this.standFacingLabel.setText(getCurrentFacingText(this.armorStand)); +//// this.standRotationLabel.setText(getCurrentRotationText(this.armorStand)); +// this.rotateSlider.tick(); +// } +// +// @Override +// public void updateYawOnClient(float yaw) { +// if (this.rotateSlider != null && this.rotateSlider.isPending(this)) { +// return; +// } +// +// super.updateYawOnClient(yaw); +// +// if (this.rotateSlider != null) { +// this.rotateSlider.setAngle(yaw); +// } +// } +// +// @Override +// public void onPong() { +// super.onPong(); +// +// if (this.rotateSlider != null) { +// this.rotateSlider.onPong(); +// } +// } +// +// private Text getCurrentFacingText(Entity entity) { +// float currentRotation = entity.getYaw(); +// Direction currentFacing = Direction.fromRotation(currentRotation); +// String towardsI18n = switch (currentFacing) { +// case NORTH -> "negZ"; +// case SOUTH -> "posZ"; +// case WEST -> "negX"; +// case EAST -> "posX"; +// default -> "posX"; +// }; +// Text towards = Text.translatable("armorstands.current.facing." + towardsI18n); +// return Text.translatable("armorstands.current.facing", currentFacing.toString(), towards.getString()); +// } +// +// private Text getCurrentRotationText(Entity entity) { +// float currentRotation = entity.getYaw(); +// return Text.translatable("armorstands.current.rotation", +// String.format(Locale.ROOT, "%.1f", MathHelper.wrapDegrees(currentRotation)) +// ); +// } public enum RotateDirection { CLOCKWISE(1, "armorstands.rotate.clockwise"), COUNTERCLOCKWISE(-1, "armorstands.rotate.counter"); diff --git a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandUtilitiesScreen.java b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandUtilitiesScreen.java index 93975b9..d058310 100644 --- a/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandUtilitiesScreen.java +++ b/src/main/java/me/roundaround/armorstands/client/gui/screen/ArmorStandUtilitiesScreen.java @@ -34,112 +34,112 @@ public ScreenType getScreenType() { return ScreenType.UTILITIES; } - @Override - protected void initStart() { - super.initStart(); - - listeners.clear(); - refreshFlags(); - } - - @Override - protected void initLeft() { - super.initLeft(); - - addLabel(LabelWidget.builder(Text.translatable("armorstands.utility.setup"), GuiUtil.PADDING, - this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 3 * (GuiUtil.PADDING / 2) - ).alignedBottom().justifiedLeft().shiftForPadding().build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.prepare"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.PREPARE) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING, this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 2 * (GuiUtil.PADDING / 2)) - .tooltip(Tooltip.of(Text.translatable("armorstands.utility.prepare.tooltip"))) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.toolRack"), - (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.TOOL_RACK) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING + BUTTON_WIDTH + (GuiUtil.PADDING / 2), - this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 2 * (GuiUtil.PADDING / 2) - ) - .tooltip(Tooltip.of(Text.translatable("armorstands.utility.toolRack.tooltip"))) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.uprightItem"), - (button) -> ClientNetworking.sendUtilityActionPacket( - UtilityAction.UPRIGHT_ITEM.forSmall(ArmorStandFlag.SMALL.getValue(armorStand))) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING, this.height - GuiUtil.PADDING - 2 * BUTTON_HEIGHT - (GuiUtil.PADDING / 2)) - .tooltip(Tooltip.of(Text.translatable("armorstands.utility.uprightItem.tooltip"))) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.flatItem"), - (button) -> ClientNetworking.sendUtilityActionPacket( - UtilityAction.FLAT_ITEM.forSmall(ArmorStandFlag.SMALL.getValue(armorStand))) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING + BUTTON_WIDTH + (GuiUtil.PADDING / 2), - this.height - GuiUtil.PADDING - 2 * BUTTON_HEIGHT - (GuiUtil.PADDING / 2) - ) - .tooltip(Tooltip.of(Text.translatable("armorstands.utility.flatItem.tooltip"))) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.block"), - (button) -> ClientNetworking.sendUtilityActionPacket( - UtilityAction.BLOCK.forSmall(ArmorStandFlag.SMALL.getValue(armorStand))) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING, this.height - GuiUtil.PADDING - BUTTON_HEIGHT) - .tooltip(Tooltip.of(Text.translatable("armorstands.utility.block.tooltip"))) - .build()); - addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.tool"), - (button) -> ClientNetworking.sendUtilityActionPacket( - UtilityAction.TOOL.forSmall(ArmorStandFlag.SMALL.getValue(armorStand))) - ) - .size(BUTTON_WIDTH, BUTTON_HEIGHT) - .position(GuiUtil.PADDING + BUTTON_WIDTH + (GuiUtil.PADDING / 2), this.height - GuiUtil.PADDING - BUTTON_HEIGHT) - .tooltip(Tooltip.of(Text.translatable("armorstands.utility.tool.tooltip"))) - .build()); - } - - @Override - protected void initRight() { - super.initRight(); - - List flags = ArmorStandFlag.getFlags(); - for (int i = flags.size() - 1; i >= 0; i--) { - addFlagToggleWidget(flags.get(flags.size() - i - 1), i); - } - } - - @Override - public void handledScreenTick() { - super.handledScreenTick(); - - refreshFlags(); - } - - private void refreshFlags() { - Arrays.stream(ArmorStandFlag.values()).forEach((flag) -> { - Consumer listener = listeners.getOrDefault(flag, (value) -> { - }); - - boolean curr = flag.getValue(this.armorStand); - boolean prev = currentValues.getOrDefault(flag, !curr); - - if (curr != prev) { - currentValues.put(flag, curr); - listener.accept(curr); - } - }); - } - - private void addFlagToggleWidget(ArmorStandFlag flag, int index) { - int xPos = this.width - GuiUtil.PADDING; - int yPos = this.height - (index + 1) * (GuiUtil.PADDING + FlagToggleWidget.WIDGET_HEIGHT); - - FlagToggleWidget widget = new FlagToggleWidget(this.textRenderer, flag, this.currentValues.get(flag), xPos, yPos); - - addDrawableChild(widget); - listeners.put(flag, widget::setValue); - } +// @Override +// protected void initStart() { +// super.initStart(); +// +// listeners.clear(); +// refreshFlags(); +// } +// +// @Override +// protected void initLeft() { +// super.initLeft(); +// +//// addLabel(LabelWidget.builder(Text.translatable("armorstands.utility.setup"), GuiUtil.PADDING, +//// this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 3 * (GuiUtil.PADDING / 2) +//// ).alignedBottom().justifiedLeft().shiftForPadding().build()); +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.prepare"), +// (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.PREPARE) +// ) +// .size(BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING, this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 2 * (GuiUtil.PADDING / 2)) +// .tooltip(Tooltip.of(Text.translatable("armorstands.utility.prepare.tooltip"))) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.toolRack"), +// (button) -> ClientNetworking.sendUtilityActionPacket(UtilityAction.TOOL_RACK) +// ) +// .size(BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING + BUTTON_WIDTH + (GuiUtil.PADDING / 2), +// this.height - GuiUtil.PADDING - 3 * BUTTON_HEIGHT - 2 * (GuiUtil.PADDING / 2) +// ) +// .tooltip(Tooltip.of(Text.translatable("armorstands.utility.toolRack.tooltip"))) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.uprightItem"), +// (button) -> ClientNetworking.sendUtilityActionPacket( +// UtilityAction.UPRIGHT_ITEM.forSmall(ArmorStandFlag.SMALL.getValue(armorStand))) +// ) +// .size(BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING, this.height - GuiUtil.PADDING - 2 * BUTTON_HEIGHT - (GuiUtil.PADDING / 2)) +// .tooltip(Tooltip.of(Text.translatable("armorstands.utility.uprightItem.tooltip"))) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.flatItem"), +// (button) -> ClientNetworking.sendUtilityActionPacket( +// UtilityAction.FLAT_ITEM.forSmall(ArmorStandFlag.SMALL.getValue(armorStand))) +// ) +// .size(BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING + BUTTON_WIDTH + (GuiUtil.PADDING / 2), +// this.height - GuiUtil.PADDING - 2 * BUTTON_HEIGHT - (GuiUtil.PADDING / 2) +// ) +// .tooltip(Tooltip.of(Text.translatable("armorstands.utility.flatItem.tooltip"))) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.block"), +// (button) -> ClientNetworking.sendUtilityActionPacket( +// UtilityAction.BLOCK.forSmall(ArmorStandFlag.SMALL.getValue(armorStand))) +// ) +// .size(BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING, this.height - GuiUtil.PADDING - BUTTON_HEIGHT) +// .tooltip(Tooltip.of(Text.translatable("armorstands.utility.block.tooltip"))) +// .build()); +// addDrawableChild(ButtonWidget.builder(Text.translatable("armorstands.utility.tool"), +// (button) -> ClientNetworking.sendUtilityActionPacket( +// UtilityAction.TOOL.forSmall(ArmorStandFlag.SMALL.getValue(armorStand))) +// ) +// .size(BUTTON_WIDTH, BUTTON_HEIGHT) +// .position(GuiUtil.PADDING + BUTTON_WIDTH + (GuiUtil.PADDING / 2), this.height - GuiUtil.PADDING - BUTTON_HEIGHT) +// .tooltip(Tooltip.of(Text.translatable("armorstands.utility.tool.tooltip"))) +// .build()); +// } +// +// @Override +// protected void initRight() { +// super.initRight(); +// +// List flags = ArmorStandFlag.getFlags(); +// for (int i = flags.size() - 1; i >= 0; i--) { +// addFlagToggleWidget(flags.get(flags.size() - i - 1), i); +// } +// } +// +// @Override +// public void handledScreenTick() { +// super.handledScreenTick(); +// +// refreshFlags(); +// } +// +// private void refreshFlags() { +// Arrays.stream(ArmorStandFlag.values()).forEach((flag) -> { +// Consumer listener = listeners.getOrDefault(flag, (value) -> { +// }); +// +// boolean curr = flag.getValue(this.armorStand); +// boolean prev = currentValues.getOrDefault(flag, !curr); +// +// if (curr != prev) { +// currentValues.put(flag, curr); +// listener.accept(curr); +// } +// }); +// } +// +// private void addFlagToggleWidget(ArmorStandFlag flag, int index) { +// int xPos = this.width - GuiUtil.PADDING; +// int yPos = this.height - (index + 1) * (GuiUtil.PADDING + FlagToggleWidget.WIDGET_HEIGHT); +// +// FlagToggleWidget widget = new FlagToggleWidget(this.textRenderer, flag, this.currentValues.get(flag), xPos, yPos); +// +// addDrawableChild(widget); +// listeners.put(flag, widget::setValue); +// } } diff --git a/src/main/java/me/roundaround/armorstands/client/gui/widget/AdjustPoseSliderWidget.java b/src/main/java/me/roundaround/armorstands/client/gui/widget/AdjustPoseSliderWidget.java index 02ab2b8..c9dbff6 100644 --- a/src/main/java/me/roundaround/armorstands/client/gui/widget/AdjustPoseSliderWidget.java +++ b/src/main/java/me/roundaround/armorstands/client/gui/widget/AdjustPoseSliderWidget.java @@ -25,9 +25,9 @@ public class AdjustPoseSliderWidget extends SliderWidget { private Optional lastScroll = Optional.empty(); public AdjustPoseSliderWidget( - int x, int y, int width, int height, PosePart part, EulerAngleParameter parameter, ArmorStandEntity armorStand + int width, int height, PosePart part, EulerAngleParameter parameter, ArmorStandEntity armorStand ) { - super(x, y, width, height, Text.empty(), 0); + super(0, 0, width, height, Text.empty(), 0); this.part = part; this.parameter = parameter; diff --git a/src/main/java/me/roundaround/armorstands/client/gui/widget/ArmorStandLayoutWidget.java b/src/main/java/me/roundaround/armorstands/client/gui/widget/ArmorStandLayoutWidget.java new file mode 100644 index 0000000..a566729 --- /dev/null +++ b/src/main/java/me/roundaround/armorstands/client/gui/widget/ArmorStandLayoutWidget.java @@ -0,0 +1,58 @@ +package me.roundaround.armorstands.client.gui.widget; + +import me.roundaround.roundalib.client.gui.GuiUtil; +import me.roundaround.roundalib.client.gui.widget.layout.LinearLayoutWidget; +import me.roundaround.roundalib.client.gui.widget.layout.SizableLayoutWidget; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.Widget; + +import java.util.function.Consumer; + +@Environment(EnvType.CLIENT) +public class ArmorStandLayoutWidget extends SizableLayoutWidget { + public final LinearLayoutWidget topLeft; + public final LinearLayoutWidget bottomLeft; + public final LinearLayoutWidget navRow; + public final LinearLayoutWidget topRight; + public final LinearLayoutWidget bottomRight; + + private final Screen screen; + + public ArmorStandLayoutWidget(Screen screen) { + super(0, 0, screen.width, screen.height); + + this.screen = screen; + + this.topLeft = LinearLayoutWidget.vertical().spacing(GuiUtil.PADDING / 2).alignLeft().alignTop(); + this.bottomLeft = LinearLayoutWidget.vertical().spacing(GuiUtil.PADDING / 2).alignLeft().alignBottom(); + this.navRow = LinearLayoutWidget.horizontal().alignCenterX().alignBottom(); + this.topRight = LinearLayoutWidget.vertical().spacing(GuiUtil.PADDING / 2).alignRight().alignTop(); + this.bottomRight = LinearLayoutWidget.vertical().spacing(GuiUtil.PADDING / 2).alignRight().alignBottom(); + } + + @Override + public void forEachElement(Consumer consumer) { + this.topLeft.forEachElement(consumer); + this.bottomLeft.forEachElement(consumer); + this.navRow.forEachElement(consumer); + this.topRight.forEachElement(consumer); + this.bottomRight.forEachElement(consumer); + } + + @Override + public void refreshPositions() { + this.topLeft.setPosition(GuiUtil.PADDING, GuiUtil.PADDING); + this.bottomLeft.setPosition(GuiUtil.PADDING, this.screen.height - GuiUtil.PADDING); + this.navRow.setPosition(this.screen.width / 2, this.screen.height - 1); + this.topRight.setPosition(this.screen.width - GuiUtil.PADDING, GuiUtil.PADDING); + this.bottomRight.setPosition(this.screen.width - GuiUtil.PADDING, this.screen.height - GuiUtil.PADDING); + + this.topLeft.refreshPositions(); + this.bottomLeft.refreshPositions(); + this.navRow.refreshPositions(); + this.topRight.refreshPositions(); + this.bottomRight.refreshPositions(); + } +} diff --git a/src/main/java/me/roundaround/armorstands/client/gui/widget/FlagToggleWidget.java b/src/main/java/me/roundaround/armorstands/client/gui/widget/FlagToggleWidget.java index 65a1e58..6e52a46 100644 --- a/src/main/java/me/roundaround/armorstands/client/gui/widget/FlagToggleWidget.java +++ b/src/main/java/me/roundaround/armorstands/client/gui/widget/FlagToggleWidget.java @@ -29,7 +29,7 @@ public class FlagToggleWidget extends PressableWidget { public FlagToggleWidget( TextRenderer textRenderer, ArmorStandFlag flag, boolean initialValue, int x, int y ) { - super(x, y, 100, WIDGET_HEIGHT, flag.getDisplayName()); + super(0, 0, 100, WIDGET_HEIGHT, flag.getDisplayName()); this.flag = flag; this.inverted = flag.invertControl(); diff --git a/src/main/java/me/roundaround/armorstands/client/gui/widget/MoveButtonWidget.java b/src/main/java/me/roundaround/armorstands/client/gui/widget/MoveButtonWidget.java deleted file mode 100644 index 06a35a0..0000000 --- a/src/main/java/me/roundaround/armorstands/client/gui/widget/MoveButtonWidget.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.roundaround.armorstands.client.gui.widget; - -import me.roundaround.armorstands.client.network.ClientNetworking; -import me.roundaround.armorstands.util.MoveMode; -import me.roundaround.armorstands.util.MoveUnits; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.text.Text; -import net.minecraft.util.math.Direction; - -public class MoveButtonWidget extends ButtonWidget { - public final Direction direction; - public final int amount; - - private MoveMode mode = MoveMode.RELATIVE; - private MoveUnits units = MoveUnits.PIXELS; - - public MoveButtonWidget( - int x, int y, int width, int height, Direction direction, int amount, MoveMode mode, MoveUnits units - ) { - super(x, y, width, height, getText(amount, units), (rawButton) -> { - MoveButtonWidget button = (MoveButtonWidget) rawButton; - ClientNetworking.sendAdjustPosPacket(button.direction, button.amount, button.mode, button.units); - }, ButtonWidget.DEFAULT_NARRATION_SUPPLIER); - - this.direction = direction; - this.amount = amount; - this.mode = mode; - this.units = units; - } - - public void setMode(MoveMode mode) { - this.mode = mode; - setUnits(this.mode.getDefaultUnits()); - } - - public void setUnits(MoveUnits units) { - this.units = units; - setMessage(getText(this.amount, this.units)); - } - - public static Text getText(int amount, MoveUnits units) { - return units.getButtonText(amount); - } - - public static Text getDirectionText(Direction direction, MoveMode mode) { - return mode.getDirectionText(direction); - } -} diff --git a/src/main/java/me/roundaround/armorstands/client/gui/widget/NavigationButtonWidget.java b/src/main/java/me/roundaround/armorstands/client/gui/widget/NavigationButtonWidget.java deleted file mode 100644 index d695303..0000000 --- a/src/main/java/me/roundaround/armorstands/client/gui/widget/NavigationButtonWidget.java +++ /dev/null @@ -1,40 +0,0 @@ -package me.roundaround.armorstands.client.gui.widget; - -import me.roundaround.armorstands.client.gui.screen.AbstractArmorStandScreen; -import me.roundaround.armorstands.client.network.ClientNetworking; -import me.roundaround.armorstands.network.ScreenType; - -public class NavigationButtonWidget extends IconButtonWidget { - private final ScreenType screenType; - private final boolean clickable; - - public NavigationButtonWidget( - AbstractArmorStandScreen parent, int x, int y, ScreenType screenType - ) { - super(x, y, screenType.getUIndex(), screenType.getDisplayName(), (button) -> { - if (parent.getScreenType() == screenType) { - return; - } - - ClientNetworking.sendRequestScreenPacket(parent.getArmorStand(), screenType); - }); - - this.screenType = screenType; - this.clickable = parent.getScreenType() != screenType; - this.active = clickable; - } - - public ScreenType getScreenType() { - return this.screenType; - } - - public boolean isMouseOverIgnoreState(double mouseX, double mouseY) { - return mouseX >= this.getX() && mouseY >= this.getY() && mouseX < (this.getX() + this.width) && - mouseY < (this.getY() + this.height); - } - - @Override - public boolean isHovered() { - return this.clickable && super.isHovered(); - } -} diff --git a/src/main/java/me/roundaround/armorstands/network/ScreenType.java b/src/main/java/me/roundaround/armorstands/network/ScreenType.java index 241229e..f109a94 100644 --- a/src/main/java/me/roundaround/armorstands/network/ScreenType.java +++ b/src/main/java/me/roundaround/armorstands/network/ScreenType.java @@ -1,6 +1,9 @@ package me.roundaround.armorstands.network; import io.netty.buffer.ByteBuf; +import me.roundaround.roundalib.asset.icon.BuiltinIcon; +import me.roundaround.roundalib.asset.icon.CustomIcon; +import me.roundaround.roundalib.asset.icon.Icon; import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.PacketCodecs; import net.minecraft.text.Text; @@ -10,12 +13,12 @@ import java.util.function.IntFunction; public enum ScreenType { - UTILITIES(0, "utilities"), - MOVE(1, "move"), - ROTATE(2, "rotate"), - POSE(3, "pose"), - PRESETS(4, "presets"), - INVENTORY(5, "inventory"); + UTILITIES(0, "utilities", new CustomIcon("flag", 20)), + MOVE(1, "move", BuiltinIcon.MOVE_18), + ROTATE(2, "rotate", BuiltinIcon.ROTATE_18), + POSE(3, "pose", BuiltinIcon.SLIDERS_18), + PRESETS(4, "presets", new CustomIcon("pose", 20)), + INVENTORY(5, "inventory", new CustomIcon("inventory", 20)); public static final IntFunction ID_TO_VALUE_FUNCTION = ValueLists.createIdToValueFunction( ScreenType::getId, values(), ValueLists.OutOfBoundsHandling.ZERO); @@ -24,10 +27,12 @@ public enum ScreenType { private final int id; private final String name; + private final Icon icon; - ScreenType(int id, String name) { + ScreenType(int id, String name, Icon icon) { this.id = id; this.name = name; + this.icon = icon; } public int getId() { @@ -38,8 +43,8 @@ public String getName() { return this.name; } - public int getUIndex() { - return this.id; + public Icon getIcon() { + return this.icon; } public Text getDisplayName() { diff --git a/src/main/resources/assets/armorstands/textures/gui/sprites/icon/body.png b/src/main/resources/assets/armorstands/textures/gui/sprites/icon/body.png new file mode 100644 index 0000000000000000000000000000000000000000..795cd0184f69196f9a9d257adced946796bd3c9e GIT binary patch literal 1237 zcmaJ>Z)n_P7(eNB>-4m;cCZUf11j_Np@Oz2r?VT=S>N zdtR=(F=b3D3}IAdevtLcCf!zH!eBZbiWa0p1szJ!FPlyTWqwf9eez9vSNEYTkoV7% z=l49n=U=8rhM$UVd}w1N5{YJZt2w;4hwp}a@Oo_ektp7}P`ZHjIR>f$4@OeDQ-Vas z0^=|TfnJ~d0`^5BEl13J0Tr@OE1F})K&TT7EEl6Ak-lAl3$zMEL`D}to6W8ow*5w~aMtJmxHKDMXv+#iTh{hb4*pMLO>IA4cOjjFzEkxy zToPkj6O7Y$XGftTW~1!!Ok5W*p*mXCf;P&iNfLjF>87smMybSsl1RaX2q;P78A<}2 zL1|E6jD#T@Y$@Kfvld>I*to=T{X8# zMnS*=3TnJa0UolH&WZ`c&~;H1N+gXb(qZ4+)<;bdZqD$yIvDt}I$F@i^W@>dIdlKH zIv%=TGHNOxEd4a|N$U}&E#0&D3~1^8tQfse?AUzc>gG%JHxIWx{KxhS%;H=77lhU` zLE-xcK2>|ZI`Qw`&#$1<-RS*8TmPB4_uOCL$yYk?fH4j zv)xBuzEMAL?R;;o++14MyU5X3TF=hCc6|GoxG;ICWoYEP>bHL% z?3A*bu2w%veZACE?kHB~XS{PTe3&>I)!MFaxcEc0>soc}gWq4AbzZ-9dFyXOhwq9MpO~L}e)Of*@JEwL L53BS2#aI3VM3kO7 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/armorstands/textures/gui/sprites/icon/copy.png b/src/main/resources/assets/armorstands/textures/gui/sprites/icon/copy.png new file mode 100644 index 0000000000000000000000000000000000000000..71b8e7ee91dadf9e5cbfbf17a763d7ff20a6622f GIT binary patch literal 1160 zcmaJ>UufM_7!NI#IX7@pCap5lRAI&C?@dnbiM<=!&As-z-LAX4w1vHRlAN@mO-@Ws zy=g&*QgIF(1E%(M2!MW{i78GB^hdr%>;=3p9z1<$l0?GOJ{eIu? z`_A{}gR#+9w{Pv=%5mKG+KAm?<1_iYxV3tgc8baq%4dXn&XD|WifJRFy$RQ6+|Ur<)>=`A9y8U z!l*0txQwTRk%a^wT^Mb;3o|bCgnfJY;ml$LA*P7W!r3UbvXZdIYq5F0Eergb37shk z>!K#>V|DmRqfs)GA0MnUYlqp{!`Krisi#Oy?ttGBHXAI}A2X-6V)4Pu?gVdqJ}{apyuD(VATn*oou?o~8Saqag=~*aS!{7Ij4|BFz_FY$(3z zLtk|Y9iGkbc2Pf2v0+8m0Z`RS6#^R+VYzAmqfn`WY6n}3Qi>uMcYFuTcN=Rz7HgFg zj3`N(gv@pdVQiXEl1`JD*9-~ryC;IkBdv5OzoYe#ZJY#eVy~KzkY7u(6>K5^0L|4+ z6R>CcH`f zKiu6DpFYw%etgTo>9@b{o4xek>g6*_%Olm>$yZ(9R{s60d+4QX<-6DH_m)rf?D)F> z$|sAzo;@Gm-2LqRa_{QNFYoj|_u(sj-weHV^Tc?6Yx!RN6*AZ>Uv9?aK#VfA@bzB7VsL literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/armorstands/textures/gui/sprites/icon/flag.png b/src/main/resources/assets/armorstands/textures/gui/sprites/icon/flag.png new file mode 100644 index 0000000000000000000000000000000000000000..a3966f3361b6677b12280a4bb7ff102691227f75 GIT binary patch literal 1235 zcmaJ>U2NM_6m}F*LbV83VPqh{a>i)2`8T#>TMbnfCv6xhQ5w-Agv7Od-CC`Guw9at zJxpCyu}ZL2{0N~+6HI74O)ESw-~q92Qp+ATK+`0q2^jEz(8L1|<6$CPw@KMUHA}wt z-0Sn5^PN8*tqu<+yC3bwFf3UfQfp{`D0&lJXnphO<4Lsb4vS;qh--!o;6p5LxEjRE zHW-IB2#lFm*I_?~#pkX1SU6UBPSIVP0+9~Yv^|8zu>OIj2lPo8;u;*coE-7jS6>sj zW#ouap~6(W0-UghW_>s^J6zXiCw18%2A;wDn+h^u!w}$2d&&uvW{%jfs~|bLrU`sQ zC7jF=o214nRlMN(5SJ;I)ES1uvoZxlAZBDy0{d}};dq+K(2Pj3tRipfj^;QLX^_E;6M`n`1nG_i6$ZL*d7Y|(;YBM-`yQWiinN!yl~jFO*>!3U6u}2Q-m{SrL$u#51G> zIFr<&z?fN6Hd!sxv9ldslvuWy6-zuXibyKSQsF=`ljnt^%5wr&>|o1I5CTVs9p4u6 z-NqL0id70e1flEKU3aR}2-OKUbb|@k!#RPH@!nC(G2BMb7u9GpWEJ|>YtSh9u8nUb zS+TYukQGe9U<8gtt4K;R&yf-5EvxFn=MTO!k`zO}{gl5;D4i!dxKeRJ#5PwNN8^Jm}cjpwPuU(6l<^UTME9TzUP z{+&-8`e*(49{li2PmF$QUH&1yuk=FV;7+`H`jhUf*vOIn$1>pLKDEpD{npBh3s*0m z-I3licTWB0r7@o4Vgkq%NEn5)ADUk@CxtzJ|%#d|WGn;m)8{>AN`_PA+nK_dklDTx| zq&vF`vQ`RF`=CwnMf+k3m4X%@MADX8>VvHhf)9d4AButxK8OfXK}^piyRi?U19L9_ z{NMk7|7}+0W)F?--M^P%n9F^zykCFvJG7Liyp#UME8X)b41Z5yh4-73>ICT;~CVmvMxkY40 z%cRUvvRhFEalO86I7|n*qFEC%6blkB3PF&EwyB+x2L7MMj@oIn8)Kn?(`Y$yXi2;S zLoiL>!yV;{l#TgH;?ugIB`b24100f?Rp#gy-t}Em@oXC+TLZYHA)xDu2y_HJ;9yns zN}l0Kwmh`66JFCLS%oU${Xy&F+X&pPWpUaqpgrFocJfPJCj5KyP0Iu-+@3$ z^;B0>A)u=UbVGqamsAnRSn(j#ks|8`H^93OByX!vse}d*54o6zQu0*YZ~#UU0@zVB zfD|kNSJFzJ=enAv+MGZs3VGi=&__cNZO;6-Js9+|Jz6-V^OVrR`R<>U+jQu@s996Z z?2i5K#zv)}?s~j%?#9LbYT>EZ-|zK$t+QWUIP$?*P21-4h|6CG%L94SoQeI$Ld#x(ED-&|i` w-xwbs-}v~QQ(s?RxhekA{!_j8=D`^^N1g8%>k literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/armorstands/textures/gui/sprites/icon/inventory.png b/src/main/resources/assets/armorstands/textures/gui/sprites/icon/inventory.png new file mode 100644 index 0000000000000000000000000000000000000000..1f21896fa68da992011fa5fb826271fae3c20824 GIT binary patch literal 1257 zcmaJ>eQ4Zd7{AeamfAyQW7@$mr2etd=90YmxFqy;w!Le6;@#@)VE0FLeUrRtvtB-y zq`UN{==o6?!&wT`iGytjq6}(L6q&<0I|lw^RTN>4IpLDmP3n8?UELpLfxI72 zp5OEQp06Ap$q&Wax3xzikyv&(UBLU6`r8)8>nn%1$MDt}WJPd31kYjT00Gcp|s~*}@%@?)mq$cZRY8TNPD%gO90!V~b+4hw%Nv_&e@VPFgNn%wc zm`svuq)NFFV!-hbA;(!tV;DdrK z0}JkoRR%l+1IH^mPPy3#BNI;G_!Evx03j|DJNBBk?o|Ap^%|{(oJO8`5b1-SV-c%K zR?H0uBm_gy839mu6)8#P0VS~lLve^V0FWThNix~M>vtq?txvH82jMokC^DZg1WDE? z1X)NSjTb4%BbL%xF<}_GE{cLm(wHJ$@0&aNs42qDSwF512EMG17P9d?d3bQ1x_aa- zJao6R>AqrkS-riol4=n)ZEiVs;aXz$o;Mbk$BsUD>XG|T=#OS&I|^gRm#+SvYU{cE z@AdQF|M2F@>1XD?9Sf(wKKXh_ck0>J4_>}}^U2Xx^~H;`-(C9~v=QB9o-^JV0$cRs zug$dQ7Zt z^Sy^+#sg>1JhuO{{k7`srml}peE#m+|2+5WhnpXs?~mTr)NU+f+P*9e9<@fdUjJrM`m4S4 ae556UZk}UrRCTTX^T}rN>G}S#7ybi}$*SuB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/armorstands/textures/gui/sprites/icon/leftarm.png b/src/main/resources/assets/armorstands/textures/gui/sprites/icon/leftarm.png new file mode 100644 index 0000000000000000000000000000000000000000..07c169a975b3a60c1c94107a0de21aca11da24dd GIT binary patch literal 1282 zcmaJ>ZD`zd7|(e)%dO`+SLL>@5YrE?U|uiDC0TE!y}Nc-c3rtvR>5NbN&abLd&xD) zd3RORO0Bj!=>%oykZ#EEi-n=!hkdYBCX|U#hC+4wu&xtV-w=GMGIsv2y{r3B7RdkQ z$@6=j-}9E~p6{bDttY1&gJ|3DCHlQy+wk(hfmoYvs}N6S zzz|GBpcluMU<-!%C(XWouRnE6(d-Nb$~sgblSOC@YiTWHfi?m?T!llX6(xSV_!)tl zdXzXJq?lAT28Yd~;|}Z{@9xvaM>JU{T94o@1qB(%Ko8)B%&6rmg($IUS3&2pm?rQ| z6>lU;Y?10u_24nvfw)Yuq{c8D9+4>^0x>L$5_lZv7>=izFwKZ0%PIn=FalnA2;|Vw z4J94#sJKJ7C^77LS%s$a`8<^mQ?@fiv$8DH3`cVui8M&JXnCMOT5eO-LL9o9V`e?m zw(zn=pxQYvN+7aZQDm~I)V5*Et>g-2jV^#J%~A}V$&^Fe)ONiz{GY~-+HPMl3+Xg; z?VO{bk{C@@FiPLO9hDUk8|AoTqPl?5xUJZ7U%HD~#_Js9Y+JzCI0^W>nx zY5VZ4A27^UpNzNl6~0q%mrAXE!MD%6u~)xJ#cx9Wi*M%#F3)|QdwucpQ$M$^fSLeZ z7ffx`9&oOf4qy4E^xV7C>SR;X+11@^%IQx}T@r2mi>1DP_}WiX%NymtQZmsUpKl+0`9Jo2 BwX*;K literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/armorstands/textures/gui/sprites/icon/leftleg.png b/src/main/resources/assets/armorstands/textures/gui/sprites/icon/leftleg.png new file mode 100644 index 0000000000000000000000000000000000000000..1e95429bd5b3e8ccff92e04b535d9d068d691513 GIT binary patch literal 1144 zcmaJ>-D@0G6rVJ-G{KZU_>c;g%Y>E&yz_B)W_D)C8k3!k+1gFRcA+a$=-rt+$*`HZ z6iX ze&_to*R0LXyg4-Z%Ag&{fy z9lw>tdB$Q}mOGt})G0_bnUht^vSbCx2tlp^)1`>v3`Xfl&w@izHwj`E&dp zlE}$!L=ncd+NR+s?dFPSP0nyEtCAvzVIJDLcFOAHe;QkAr;VkU$aRv^#l+<$@ke@K zp1$oJ<%*n*eKZMpUGRcK-NleZtm>3R{zdWv&({1_3*nXlNzuU2G&Kd982Qj8y5bjo z%U4^4o}I1mhN+rb8BJ=MVW?_l$}-E7mBNIkR~!xLsM5n$qm<#uB|YB(_ua)#Y>Tza z3Bime4N4b!jW9b;8BOPD43I8a;L!0P@@OX=&1pFzGz9BOwu3DQ6m?(s z6dggn8ql;f1Wi>}V1Z~pLMGM6d7$0@#2!6( z|L&E^!&UiC^Ru77{AI@%7j}F%{NLkGrmkN5;l`iC&o-<~>h?)={AH=ccUUBM4me}AX_>CU^qy?^DcGkrqe=WTrNuk2+0FQ`^#oU4;3 G&prn}iFNq^ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/armorstands/textures/gui/sprites/icon/paste.png b/src/main/resources/assets/armorstands/textures/gui/sprites/icon/paste.png new file mode 100644 index 0000000000000000000000000000000000000000..7758b5a5c496748d495d00c27d0fe6cca091a093 GIT binary patch literal 1322 zcmaJ>eM}o=7{9Gi;O@r2JA3_#I8q?$tDt;#JaVSE0i_L0a=Ri(Nrc=3~kNYvXk(C8CzOgokLkj zC81>um@>K&)ms9i^xfG}(GaN-pE5OcFQ7kS$O9Ru+wn-4Kqo#$Q^bHONi2|f5(ard zhC%_F3;|XpWysNLP!&{0@|SqF!bd`Zrf8&*4Fq_eVWKgCkMJR(ImYpvKN{m>C2U-` zY@o}q1Jb~#b#?k z9rcrm8s|oSTF0<$_3=n!r}Kk!Yjw53#bNikCb4^-yEJy8Z1FD&eltB$b*b;@;=a|@ ze^w}$XTLw6xn8;Rh-a)|RvIs=p^>i1#&^e#6_%#Ymv7tgNzLIiWhWQDzF1ejeMYF+ zyZ6kS;K2R^9@p8azmL^1zs$|8jNG_Zl=gSvPpH95@ddJV7KKprg_g(Yl zZdb|y-(i)vj#k!ocXuxoMx}etjxW|-0qNhDmZAlZ$Mg2C*xgQ`y4*XyJaOWR_s8go zYcv1useW?%PkS8hDpxi!wXb$`_O~4q^xWWu$v>70h5QG4%iz=M^1+zUGk^5g)RA=0 w_xY*gHM1=r*EiL?@!;%ymG?6@{}SfHPVPQ_`JBuBMDgzxkG4flHTAsmANE$vW&i*H literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/armorstands/textures/gui/sprites/icon/pose.png b/src/main/resources/assets/armorstands/textures/gui/sprites/icon/pose.png new file mode 100644 index 0000000000000000000000000000000000000000..ed78afada0a3fa92faaa1d540e20bbf7379a9caa GIT binary patch literal 1286 zcmaJ>Yi!$86m}bi&`3u$D#%tkj3=N-bNqH}t08?P-6EQ{$|5xg(Q<8HC#H?<+0NpW z*C;SlG1#QhiH8Ig{}2-Egv6gA#@bQ|G{M*yLVz?RMiCED_ydS-DmQIY_M@65-+S)$ z`Of*y%aeosyPGy|-;7~cQ+iJ_i}sepK6&6e@PAr`~Mc}3$ zCx(O!opE|#(cClc!oB1DIc~J+=#RIm(b4O|y7Rjsg*goGeOU7tYcwPthDjizLG+0;|vhzV;Bvp{pB8 zHrc!84xQpe(f1vNqAHb2w8BMgw?HwnEK@W~u`G!+NUv)7ARsMoXWc>)dYWrGzG+){ z%_30kvL7c9+0`gYPA0Q%*z(qLg|bEkz@eBZO_fTu&{niPKMVh-v7xq?t2&U%LeDO{ z8Y+pgvkpe-yS}5EB4VQqxF)I#7)#n(xdbggos1LcOH?;?g*Q}{1*%BGm ztU+o}ppBRz8;r`;?QDb>C5B1GVjRzlB9eM#si!-|b@4(f$+H5Rs$AlP zy@qA4i&c7D2z=Yk+4fky5eAF4Z+k`C!C4_Hw|#~>!SrNG*2!XoViOs zY{9UGNIKb-3%*gWEH5WQLc^`0snZ{A4}xK~_n$th{O`c~PgmYNWgIzr^qJNf(EasO zZJAUHb6Ymt^8Mn0_qfLL@(VZbM?$oxoTK8*_gXcS&JGb24{0F;Oz^Z@# zc=CAo+s~eye>5^2`l6w|v2%E#5b2Ff@E7iV=*r01U;e)H;X5u}D2{L+90cXN&b)(D z6SKGI&F#Co4jlP)=AKslV|woOb4`)oFFv+Oe`0<#a#|0a3(w+nXV15$9{hZ8=%wkQ zG~0Y^`t8N;{BK(~b)M)8ADf!GI&er?=o(Q&H$*UM>!%AJzR}WF`!l6e{mFN`ADQ?M DF>|sH literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/armorstands/textures/gui/sprites/icon/rightarm.png b/src/main/resources/assets/armorstands/textures/gui/sprites/icon/rightarm.png new file mode 100644 index 0000000000000000000000000000000000000000..5236a8e64fc2af1c34ab03938d05d7116b8ca850 GIT binary patch literal 1342 zcmaJ>ZA=?=7{9R>5$S>ni*a$wc^HJn>%H{u+PlyJYYUW723?`VsPW&s|G}m7uD!di zEm4PrsdF*7X=eDKj4bFfH?#RNNpxd~W?2-YQwgXaCZaJelVpCFADsFxP}~QyOYZ;j z-1B>$-}80{+gckPC0k1{408mV{9&}0=ilN@XnpD6HV4}7w*y`FUPHArz=T-6V#FXG zOn`0}hCs=sF2foOTR*5py6mn{izFKfC&=qKvxy`^V^~dXHVNc7wDB11)^sni_|XJ` zYl@eM@*z5u^uZpjsn3La`&uJ%UtAUyqIM@|irH!sm++ewL{GMS7s<8m5iH^qpeNYO0CvLw()xHP}Zm{NK%ZGrV@#KXiM6b9ftqYSX0}Im>Q}J==B?NIstV%==T!ni&N1QiBn@S7Q_S+x&=Ub zJRD7W0IQNR)1;#|Qiz%d>$3HmF-R z&}CTgts&nlSl=D7lFx*|Hq3}&^cEVSt;etptH(&-=2;T00_hPsmPFyuqziH?%X$Fk@`%I=Ub!uK%YBL@D2QZ% zizISxmG_7;2>}C0D02b{ILMF+Be+#nQ3QdH5fq|G<@@HgJ}QV%bLNk$gMluqqXl&| zPbL~1$XqMMuyt)ge|;qT{g1DPc2CunJ@@eB2CcODP}QNk?g>{lwQm2ocwk}SyZygk zuDu$pTBsTz9xQA5s_a_y*xQSub^)-(?@!JRP`P>7S$~Qdw_1!1x`p4s&1F7a%{9?r?>CWnr3+?K4ZSq&5 z_x$*1>fgieb?=_v-<TH{!!vqCTRpSAlziiOsOxFRsV(EhdeN-D?zA6d!0RCJ+=_G?pskq=HfJeB7Oxof)!CH#-xvp&Qe6At@;K?#!L+n9SU9 z=EmJbA4Du@saS0B&6h&4rL}^Xhmr>cscoQtKxv^+Uux+`o?5YjdMDXUeFzTB{Wx=e z=lsssT$mU?*xU13565x6j(h1`P@AGtmA5UIgd)mx#8wzHG{+4NwPNJXV9M9=bPyGUm8IJPA9w{} zQme?7xP%+Q=t6=IFO1jRg&EiMgrPV2!Is4ggqR|}70yPf)hY<9b}e?!#FD_Ts?eE& zutsXCGQpQff_YO^fGf+8&zmCBk)AVk10CR@3{^?aNwN+U#nPZ9Ykd0=n8U>Lt*SlJ zcE@f7p+RYENm8@f6q`AbB-4^&nx-T}2|~a$Ksp~$)B;i3-?3oh)J=kz1|;G$i>OZK zXhC3P*P;mHN@d+}l(uulvL>}qEGeQag<%%js&-1N_0lDWiXCGq<^ zV3xiYJIWLp8|zRKu)3gGo49i!j%e8~2<(gK1)in)^*Tg#9pJoCi#6HL z`=+nda~(Sy;dMjN97k1DRo4~888MC0u#+pQnq#X_gH8uqj#7#u7k7LI%y%0rzYuGc z5{xKGYJ|*o8eyVAC`lV6=AkB<{NBkR@<=ls$ZE6}vW=7AB=$xU67s7_wt@`^cB8n2v|5W$YIro&_HU=FoibWdoFoveaa*(h`7VWGS$4V8Kw&`QV_tdssp5A z1$c^{_kGXPb*(N)jG~nF&2xR!5wYgXj_ZTLF6*O(BQ{S78=Uy^^%*vFm&$gr*81ts zPk!w_!*3l~`E<|g!zYT9$+lwG(L2ZP_iW$hbj`i<^ZDYxOLv!UZu$0}nSXe%@5iAZ zT(lWoIez`!f&B+QJF|H5%UjDg-unCT@R6IRzuNcPhnLPhC3j)B%%y)#e|&3n??>4W Nq3n#?Uk|@`_8GTtczFN- literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/armorstands/textures/gui/sprites/selection.png b/src/main/resources/assets/armorstands/textures/gui/sprites/selection.png new file mode 100644 index 0000000000000000000000000000000000000000..457ce253458457303c6fb7cb13a8a82fc42d6b69 GIT binary patch literal 1924 zcmbVN4NTN#7_NsXFhz!DBQC~LaRc<{1Uu;hhBYGtr_LfULz$7~dOK$4GwDLcRwB^L zN^%@ziJLT0$h_K=O2`r`3~Oo&oeF_1ADke8xGM}Vi%Tw3J30!e2T12<>MYIrFUF2fp~$_OVeXIP5!iAm3Gpsj>Nn-Mu{O3b9x7#wO7t})^|wGz|e7&Zd6 za}?tWyZ|*i)EZoGz(JOthk}}+2#I(lm?Ci(CwK@TnDGz=G|ICD2pkF{p2-z)0x%4` z(++!Kx8vEYC=o14XIsq((5zw@3fJnj2CddfD^t`uN=X}aq|%8wDJ7*QoJQJ2lR87n z*nTTVdgaWH?Wg|d{>1_VT8k)pZ63MdNX>! zoK~7bMqe|p9f1*AUm*=h|0CTaFp+afK0=_=3qZ79SxzW$9+mrWL8bRP8G{k5YOfCV8s9!#^*FumYHQSo*ux)9n4zgD))8=zww;DxjH2s{VBLaKWyNbf`kpiWZKaWe&$^=L%$d{KR*}DQW!UD~J8!jibY!Dt z_wJDmw~mKfdXhVZ=)TTpfl3Sa=YVwby@axuyNen>bSzA&6YmGoChF`P#KUh}Dia_o z&oD8Lgbp-)%vgG#_VpD;58j@&Z`=DloAB<~oBJc;+m1b{Dlg7&J^g9t52Z87_DM}m zPQ3n+0&8#kCRefTJbCQekxMm8^Qsf~z4drC7Khd6lqM~$-G9X!OiA8bHEGkilCuxdF|DnU2fj2n7<