diff --git a/CHANGELOG.md b/CHANGELOG.md index 365fdbd3..3b2702f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [26.1.2.7] + +### Added +* Added `Vec2d` utility class +* Added `EditableConfigValue#setCanEdit` variant taking a `BooleanSupplier` + * Allows for more dynamic control of can-edit visual appearance for entries in config editor screen +* Added "undo" and "redo" icons +* Added `DocsMod` abstraction layer +* `ImageComponent` now has a "click_action" field + +### Changed +* Default width of string editor overlays is a bit wider now +* Update panel scrolling to handle both X and Y axes, since this is well-supported by vanilla + * `Panel#scrollPanel` signature has changed + * Soft-breaking change; mods need to update to new API. They won't crash if not but panel scrolling may not function well + +### Fixed +* Fixed execClientCommand() incorrectly stripping all forward slashes from commands (thanks @FalAut) +* Fixed pose stack leak which could happen under some circumstances in sidebar rendering + ## [26.1.2.6-beta] ### Fixed diff --git a/build.gradle b/build.gradle index 6649d1cd..60e23be5 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'java-library' id 'net.fabricmc.fabric-loom' version '1.15.2' apply(false) id 'net.neoforged.moddev' version '2.0.140' apply(false) - id "me.modmuss50.mod-publish-plugin" version "1.1.0" + id "me.modmuss50.mod-publish-plugin" version "2.1.1" } tasks.named('wrapper', Wrapper).configure { @@ -124,6 +124,8 @@ publishMods { minecraftVersions.add(it.trim()) } javaVersions.add(JavaVersion.VERSION_25) + client = true + server = true } curseforge("curseforgeFabric") { diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/FTBLibraryCommands.java b/common/src/main/java/dev/ftb/mods/ftblibrary/FTBLibraryCommands.java index 3cea43f5..c7b6344e 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/FTBLibraryCommands.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/FTBLibraryCommands.java @@ -9,7 +9,6 @@ import dev.ftb.mods.ftblibrary.config.FTBLibraryServerConfig; import dev.ftb.mods.ftblibrary.nbtedit.NBTEditResponseHandlers; import dev.ftb.mods.ftblibrary.net.EditConfigPacket; -import dev.ftb.mods.ftblibrary.net.EditNBTPacket; import dev.ftb.mods.ftblibrary.net.OpenTestScreenPacket; import dev.ftb.mods.ftblibrary.platform.Mod; import dev.ftb.mods.ftblibrary.platform.Platform; @@ -32,6 +31,7 @@ import net.minecraft.nbt.StringTag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.resources.Identifier; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.permissions.Permissions; import net.minecraft.util.ProblemReporter; @@ -43,15 +43,9 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.storage.TagValueOutput; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - import static net.minecraft.commands.Commands.literal; public class FTBLibraryCommands { - public static final Map EDITING_NBT = new HashMap<>(); - public static void registerCommands(CommandDispatcher dispatcher, CommandBuildContext ignoredCtx, Commands.CommandSelection ignoredType) { var command = literal(FTBLibrary.MOD_ID) .then(literal("gamemode") @@ -128,39 +122,32 @@ private static int editNBT(CommandContext context, NBTEditCa var tag = new CompoundTag(); data.accept(info, tag); - if (!info.isEmpty()) { - EDITING_NBT.put(player.getUUID(), info); - Server2PlayNetworking.send(player, new EditNBTPacket(info, tag)); - return Command.SINGLE_SUCCESS; - } - - return 0; + return NBTEditResponseHandlers.INSTANCE.sendRequestPacket(player, info, tag); } private static void editItemNBT(CommandContext context, CompoundTag info, CompoundTag tag) throws CommandSyntaxException { var player = context.getSource().getPlayerOrException(); ItemStack stack = player.getMainHandItem(); - if (stack.isEmpty()) { - return; + if (!stack.isEmpty()) { + info.store("type", Identifier.CODEC, NBTEditResponseHandlers.ITEM); + ItemStack.CODEC.encodeStart(player.level().registryAccess().createSerializationContext(NbtOps.INSTANCE), stack) + .ifSuccess(res -> { + if (res instanceof CompoundTag t) tag.merge(t); + }); + var key = RegistryHelper.getIdentifier(stack.getItem(), Registries.ITEM); + info.put("text", InfoBuilder.create(context) + .add("Class", Component.literal(stack.getItem().getClass().getName())) + .add("ID", Component.literal(key == null ? "null" : key.toString())) + .add("Mod", Component.literal(key == null ? "null" : Platform.get().getMod(key.getNamespace()).map(Mod::name).orElse("Unknown"))) + .build()); } - info.putString("type", "item"); - ItemStack.CODEC.encodeStart(player.level().registryAccess().createSerializationContext(NbtOps.INSTANCE), stack) - .ifSuccess(res -> { - if (res instanceof CompoundTag t) tag.merge(t); - }); - var key = RegistryHelper.getIdentifier(stack.getItem(), Registries.ITEM); - info.put("text", InfoBuilder.create(context) - .add("Class", Component.literal(stack.getItem().getClass().getName())) - .add("ID", Component.literal(key == null ? "null" : key.toString())) - .add("Mod", Component.literal(key == null ? "null" : Platform.get().getMod(key.getNamespace()).map(Mod::name).orElse("Unknown"))) - .build()); } private static void editPlayerNBT(CommandContext context, CompoundTag info, CompoundTag tag) throws CommandSyntaxException { var player = EntityArgument.getPlayer(context, "player"); - info.putString("type", NBTEditResponseHandlers.PLAYER.toString()); + info.store("type", Identifier.CODEC, NBTEditResponseHandlers.PLAYER); info.store("id", UUIDUtil.CODEC, player.getUUID()); TagValueOutput output = TagValueOutput.createWithContext(ProblemReporter.DISCARDING, player.level().registryAccess()); @@ -183,7 +170,7 @@ private static void editEntityNBT(CommandContext context, Co return; } - info.putString("type", NBTEditResponseHandlers.ENTITY.toString()); + info.store("type", Identifier.CODEC, NBTEditResponseHandlers.ENTITY); info.putInt("id", entity.getId()); TagValueOutput output = TagValueOutput.createWithContext(ProblemReporter.DISCARDING, entity.registryAccess()); @@ -197,8 +184,7 @@ private static void editEntityNBT(CommandContext context, Co .add("Mod", Component.literal(key == null ? "null" : Platform.get().getMod(key.getNamespace()).map(Mod::name).orElse("Unknown"))) .build()); - String name = entity.getDisplayName() == null ? "?" : entity.getDisplayName().getString(); - info.putString("title", name); + info.putString("title", entity.getDisplayName().getString()); } private static void editBlockNBT(CommandContext context, CompoundTag info, CompoundTag tag) throws CommandSyntaxException { @@ -211,7 +197,7 @@ private static void editBlockNBT(CommandContext context, Com return; } - info.putString("type", NBTEditResponseHandlers.BLOCK.toString()); + info.store("type", Identifier.CODEC, NBTEditResponseHandlers.BLOCK); BlockPos.CODEC.encodeStart(NbtOps.INSTANCE, pos).ifSuccess(nbt -> info.put("pos", nbt)); tag.merge(blockEntity.saveWithFullMetadata(context.getSource().getLevel().registryAccess())); tag.remove("x"); @@ -228,7 +214,7 @@ private static void editBlockNBT(CommandContext context, Com .add("Block Class", Component.literal(blockEntity.getBlockState().getBlock().getClass().getName())) .add("Position", Component.literal("[" + pos.getX() + ", " + pos.getY() + ", " + pos.getZ() + "]")) .add("Mod", Component.literal(key == null ? "null" : Platform.get().getMod(key.getNamespace()).map(Mod::name).orElse("Unknown"))) - .add("Ticking", Component.literal(isTicking(blockEntity) ? "true" : "false")) + .add("Ticking", Component.literal(Boolean.toString(isTicking(blockEntity)))) .build()); var title = blockEntity instanceof Nameable n ? n.getDisplayName() : null; @@ -239,7 +225,9 @@ private static void editBlockNBT(CommandContext context, Com } private static boolean isTicking(BlockEntity be) { - return be.getBlockState().getBlock() instanceof EntityBlock eb && eb.getTicker(be.getLevel(), be.getBlockState(), be.getType()) != null; + return be.getLevel() != null + && be.getBlockState().getBlock() instanceof EntityBlock eb + && eb.getTicker(be.getLevel(), be.getBlockState(), be.getType()) != null; } private interface NBTEditCallback { diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableConfigValue.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableConfigValue.java index 20eb48bb..5c8e8016 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableConfigValue.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableConfigValue.java @@ -16,6 +16,7 @@ import org.jspecify.annotations.Nullable; import java.util.Objects; +import java.util.function.BooleanSupplier; import java.util.function.Consumer; /** @@ -40,7 +41,7 @@ public abstract class EditableConfigValue implements Comparable icon = Icons.SETTINGS; - private boolean canEdit = true; + private BooleanSupplier canEdit = () -> true; protected static Component info(String key) { return Component.literal(key + ":").withStyle(ChatFormatting.AQUA); @@ -225,10 +226,15 @@ public EditableConfigValue setOrder(int o) { } public boolean getCanEdit() { - return canEdit; + return canEdit.getAsBoolean(); } public EditableConfigValue setCanEdit(boolean e) { + canEdit = () -> e; + return this; + } + + public EditableConfigValue setCanEdit(BooleanSupplier e) { canEdit = e; return this; } diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableFluid.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableFluid.java index 0955e2cb..c51303f9 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableFluid.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableFluid.java @@ -50,9 +50,7 @@ public Component getStringForGUI(FluidStack value) { @Override public void onClicked(Widget clickedWidget, MouseButton button, ConfigCallback callback) { - if (getCanEdit()) { - new SelectFluidScreen(this, callback).openGui(); - } + new SelectFluidScreen(this, callback).openGui(); } @Override diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableItemStack.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableItemStack.java index fb72c336..783f4932 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableItemStack.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableItemStack.java @@ -52,9 +52,7 @@ public Component getStringForGUI(@Nullable ItemStack value) { @Override public void onClicked(Widget clickedWidget, MouseButton button, ConfigCallback callback) { - if (getCanEdit()) { - new SelectItemStackScreen(this, callback).openGui(); - } + new SelectItemStackScreen(this, callback).openGui(); } @Override diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableVariantConfig.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableVariantConfig.java index 1bb6b3c3..a8f305a8 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableVariantConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/editable/EditableVariantConfig.java @@ -18,9 +18,7 @@ public abstract class EditableVariantConfig extends EditableConfigValue { @Override public void onClicked(Widget clickedWidget, MouseButton button, ConfigCallback callback) { - if (getCanEdit()) { - boolean changed = updateValue(getIteration(value, button.isLeft())); - callback.save(changed); - } + boolean changed = updateValue(getIteration(value, button.isLeft())); + callback.save(changed); } } \ No newline at end of file diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditConfigListScreen.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditConfigListScreen.java index e1934f91..ed2b3d0d 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditConfigListScreen.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditConfigListScreen.java @@ -159,17 +159,19 @@ public void addMouseOverText(TooltipList list) { @Override public void onClicked(MouseButton button) { - playClickSound(); - CV listType = listConfig.getType(); - listType.setValue(listType.copy(listType.getDefaultValue())); - listType.onClicked(this, button, accepted -> { - if (accepted) { - localValues.add(listType.getValue()); - changed = true; - } + if (listConfig.getCanEdit()) { + playClickSound(); + CV listType = listConfig.getType(); + listType.setValue(listType.copy(listType.getDefaultValue())); + listType.onClicked(this, button, accepted -> { + if (accepted) { + localValues.add(listType.getValue()); + changed = true; + } - openGui(); - }); + openGui(); + }); + } } @Override diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditConfigScreen.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditConfigScreen.java index 5dea4259..745472dc 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditConfigScreen.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditConfigScreen.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.Supplier; import static dev.ftb.mods.ftblibrary.util.TextComponentUtils.hotkeyTooltip; @@ -81,9 +82,9 @@ public EditConfigScreen(EditableConfigGroup configGroup, boolean readOnly) { } buttonExpandAll = new SimpleButton(topPanel, List.of(Component.translatable("gui.expand_all"), hotkeyTooltip("="), hotkeyTooltip("+")), Icons.EXPAND, - (widget, button) -> toggleAll(false)); + (_, _) -> toggleAll(false)); buttonCollapseAll = new SimpleButton(topPanel, List.of(Component.translatable("gui.collapse_all"), hotkeyTooltip("-")), Icons.COLLAPSE, - (widget, button) -> toggleAll(true)); + (_, _) -> toggleAll(true)); } private void toggleAll(boolean collapsed) { @@ -113,7 +114,7 @@ public boolean onInit() { allConfigButtons.forEach(w -> { if (w instanceof ConfigEntryButton eb) { - widestKey = Math.max(widestKey, getTheme().getFont().width(eb.keyText)); + widestKey = Math.max(widestKey, getTheme().getFont().width(eb.keyText.get())); widestValue = Math.max(widestValue, getTheme().getFont().width(eb.getValueStr())); } else if (w instanceof ConfigGroupButton gb) { widestGroup.setValue(Math.max(widestGroup.intValue(), getTheme().getStringWidth(gb.title))); @@ -269,7 +270,7 @@ public void onClicked(MouseButton button) { private class ConfigEntryButton extends Button implements EditStringConfigOverlay.PosProvider { private final ConfigGroupButton groupButton; private final EditableConfigValue configValue; - private final Component keyText; + private final Supplier keyText; public ConfigEntryButton(Panel panel, ConfigGroupButton groupButton, EditableConfigValue configValue) { super(panel); @@ -277,9 +278,9 @@ public ConfigEntryButton(Panel panel, ConfigGroupButton groupButton, EditableCon this.groupButton = groupButton; this.configValue = configValue; - keyText = this.configValue.getCanEdit() ? + keyText = () -> this.configValue.getCanEdit() ? Component.literal(this.configValue.getName()) : - Component.literal(this.configValue.getName()).withStyle(ChatFormatting.GRAY); + Component.literal(this.configValue.getName()).withStyle(getTheme().hasDarkBackground() ? ChatFormatting.DARK_GRAY : ChatFormatting.GRAY); } @Override @@ -287,7 +288,7 @@ public void draw(GuiGraphicsExtractor graphics, Theme theme, int x, int y, int w IconHelper.renderIcon(Icons.COLOR_BLANK.withColor(Color4I.GRAY), graphics, x, y + 1, 10, 10); IconHelper.renderIcon(Icons.INFO, graphics, x + 1, y + 2, 8, 8); - theme.drawStringOnBackground(graphics, keyText, x + 13, y + 2);//Bits.setFlag(0, Theme.SHADOW, isMouseOver())); + theme.drawStringOnBackground(graphics, keyText.get(), x + 13, y + 2); Component valueText = configValue.getStringForGUI(configValue.getValue()); @@ -297,7 +298,7 @@ public void draw(GuiGraphicsExtractor graphics, Theme theme, int x, int y, int w } var textCol = configValue.getColor(theme).mutable(); - textCol.setAlpha(255); + textCol.setAlpha(configValue.getCanEdit() ? 255 : 128); if (isMouseOver()) { textCol.addBrightness(60); @@ -311,7 +312,7 @@ public void draw(GuiGraphicsExtractor graphics, Theme theme, int x, int y, int w @Override public void onClicked(MouseButton button) { - if (!readOnly && getMouseY() >= 20) { + if (configValue.getCanEdit() && !readOnly && getMouseY() >= 20) { playClickSound(); configValue.onClicked(this, button, accepted -> { if (accepted) changed = true; @@ -325,7 +326,7 @@ public void addMouseOverText(TooltipList list) { if (getMouseY() > 18) { int x = getMouseX() - getX(); if (x < 16) { - list.add(keyText.copy().withStyle(ChatFormatting.UNDERLINE)); + list.add(keyText.get().copy().withStyle(ChatFormatting.UNDERLINE)); var tooltip = configValue.getTooltip(); if (!tooltip.isEmpty()) { diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditStringConfigOverlay.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditStringConfigOverlay.java index 0b824848..fb0f836f 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditStringConfigOverlay.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/EditStringConfigOverlay.java @@ -36,8 +36,8 @@ public EditStringConfigOverlay(Panel panel, EditableStringifiedConfig config, this.currentValue = config.copy(config.getValue()); this.title = title; - int stringWidth = getGui().getTheme().getStringWidth(config.getStringFromValue(currentValue)); - width = Math.min(getWindow().getGuiScaledWidth() / 2, stringWidth + config.getExtraEditorWidth()); + width = Math.clamp(currentValue == null ? 0 : getGui().getTheme().getStringWidth(config.getStringFromValue(currentValue)) + 86, + 150, getWindow().getGuiScaledWidth() * 3 / 4); titleField = new TextField(this).addFlags(Theme.SHADOW).setText(Objects.requireNonNullElse(title, Component.empty())); titleField.setSize(0, 0); @@ -165,12 +165,13 @@ public void onEnterPressed() { } @Override - public boolean mouseScrolled(double scroll) { - return config.scrollValue(currentValue, scroll > 0).map(v -> { + public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) { + var directionlessDelta = scrollX != 0 ? scrollX : scrollY; + return config.scrollValue(currentValue, directionlessDelta > 0).map(v -> { textBox.setText(config.getStringFromValue(v)); textBox.setSelectionPos(textBox.getCursorPos()); return true; - }).orElse(super.mouseScrolled(scroll)); + }).orElse(super.mouseScrolled(mouseX, mouseY, scrollX, scrollY)); } } } diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/resource/ResourceSelectorScreen.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/resource/ResourceSelectorScreen.java index dc72ae04..71410749 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/resource/ResourceSelectorScreen.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/config/gui/resource/ResourceSelectorScreen.java @@ -345,13 +345,15 @@ public CountTextBox() { } @Override - public boolean mouseScrolled(double scroll) { + public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) { if (!isMouseOver) return false; + + var directionlessDelta = scrollX != 0 ? scrollX : scrollY; if (isShiftKeyDown()) { - int adj = scroll > 0 ? getCount() : -getCount() / 2; + int adj = directionlessDelta > 0 ? getCount() : -getCount() / 2; adjust(adj); } else { - adjust((int) Math.signum(scroll)); + adjust((int) Math.signum(directionlessDelta)); } return true; } diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/MenuScreenWrapper.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/MenuScreenWrapper.java index 5f307a38..48e0f507 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/MenuScreenWrapper.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/MenuScreenWrapper.java @@ -69,7 +69,7 @@ public boolean mouseReleased(MouseButtonEvent event) { @Override public boolean mouseScrolled(double x, double y, double dirX, double dirY) { - return wrappedGui.mouseScrolled(dirY) || super.mouseScrolled(x, y, dirX, dirY); + return wrappedGui.mouseScrolled(x, y, dirX, dirY) || super.mouseScrolled(x, y, dirX, dirY); } @Override diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/theme/Theme.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/theme/Theme.java index b4f7a153..d777d0d0 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/theme/Theme.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/theme/Theme.java @@ -64,8 +64,8 @@ public class Theme { private static final Icon SCROLL_BAR_BG_DISABLED = SCROLL_BAR_BG.withTint(Color4I.BLACK.withAlpha(100)); private static final Icon TEXT_BOX = PartIcon.wholeTexture("textures/gui/sprites/container/enchanting_table/enchantment_slot_disabled.png", 108, 19, 4); - private static final Icon TAB_H_UNSELECTED = TEXTURE_RECIPE_BOOK.withUV(150, 2, 35, 26, 256, 256); - private static final Icon TAB_H_SELECTED = TEXTURE_RECIPE_BOOK.withUV(188, 2, 35, 26, 256, 256); + private static final Icon TAB_H_UNSELECTED = PartIcon.wholeTexture("textures/gui/sprites/widget/tab.png", 130, 24, 2); + private static final Icon TAB_H_SELECTED = PartIcon.wholeTexture("textures/gui/sprites/widget/tab_selected.png", 130, 24, 2); public static boolean renderDebugBoxes = false; private final BooleanStack fontUnicode = new BooleanArrayList(); diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/BaseScreen.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/BaseScreen.java index 423e8a2b..9b8a3088 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/BaseScreen.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/BaseScreen.java @@ -460,11 +460,11 @@ public void mouseReleased(MouseButton button) { } @Override - public boolean mouseScrolled(double scroll) { - if (focusedWidget != null && focusedWidget.mouseScrolled(scroll)) { + public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) { + if (focusedWidget != null && focusedWidget.mouseScrolled(mouseX, mouseY, scrollX, scrollY)) { return true; } - return modalPanels.isEmpty() ? super.mouseScrolled(scroll) : modalPanels.peekFirst().mouseScrolled(scroll); + return modalPanels.isEmpty() ? super.mouseScrolled(mouseX, mouseY, scrollX, scrollY) : modalPanels.peekFirst().mouseScrolled(mouseX, mouseY, scrollX, scrollY); } @Override diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/DropDownMenu.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/DropDownMenu.java index 84cfa74e..ea64c380 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/DropDownMenu.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/DropDownMenu.java @@ -33,11 +33,6 @@ public void onTextChanged() { this.scrollBar = new PanelScrollBar(this, ScrollBar.Plane.VERTICAL, mainPanel); } - @Override - public boolean scrollPanel(double scroll) { - return super.scrollPanel(scroll); - } - @Override public void addWidgets() { add(textBox); diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/IntTextBox.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/IntTextBox.java index b22cbc7a..70ca4ced 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/IntTextBox.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/IntTextBox.java @@ -43,9 +43,10 @@ public void setMinMax(int min, int max) { } @Override - public boolean mouseScrolled(double scroll) { + public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) { if (allowInput()) { - setAmount(getIntValue() + (int) scroll); + var directionlessDelta = scrollX != 0 ? scrollX : scrollY; + setAmount(getIntValue() + (int) directionlessDelta); return true; } return false; diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/MultilineTextBox.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/MultilineTextBox.java index 8c774d27..991ea129 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/MultilineTextBox.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/MultilineTextBox.java @@ -311,6 +311,8 @@ private void scrollToCursor() { } } + d0 = Mth.clamp(d0, 0, Math.max(0, parent.getContentHeight() - parent.height)); + parent.setScrollY(d0); } diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/Panel.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/Panel.java index 5a7eec5d..c5be9719 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/Panel.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/Panel.java @@ -342,16 +342,16 @@ public void mouseReleased(MouseButton button) { } @Override - public boolean mouseScrolled(double scroll) { + public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) { return getWithScrollOffset(() -> { for (var i = widgets.size() - 1; i >= 0; i--) { var widget = widgets.get(i); - if (widget.isEnabled() && widget.mouseScrolled(scroll)) { + if (widget.isEnabled() && widget.mouseScrolled(mouseX, mouseY, scrollX, scrollY)) { return true; } } - return scrollPanel(scroll); + return scrollPanel(scrollX, scrollY); }); } @@ -370,15 +370,23 @@ public boolean mouseDragged(int button, double dragX, double dragY) { } - public boolean scrollPanel(double scroll) { + public boolean scrollPanel(double xDelta, double yDelta) { if (attachedScrollbar != null || !isMouseOver()) { return false; } - if (isDefaultScrollVertical() != isShiftKeyDown()) { - return movePanelScroll(0, -getScrollStep() * scroll); + // No scroll direction was given? + var directionlessDelta = yDelta != 0 ? yDelta : xDelta; + if (directionlessDelta == 0) { + return false; + } + + // If the user is pressing shift, we'll always attempt to scroll horizontally, otherwise we'll just blindly apply both directions + if (isShiftKeyDown()) { + var scrollAmount = -getScrollStep() * directionlessDelta; + return movePanelScroll(scrollAmount, 0); } else { - return movePanelScroll(-getScrollStep() * scroll, 0); + return movePanelScroll(-getScrollStep() * xDelta, -getScrollStep() * yDelta); } } diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/ScreenWrapper.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/ScreenWrapper.java index 7aa15170..20f3e343 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/ScreenWrapper.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/ScreenWrapper.java @@ -57,8 +57,8 @@ public boolean mouseReleased(MouseButtonEvent event) { } @Override - public boolean mouseScrolled(double x, double y, double dirX, double dirY) { - return wrappedGui.mouseScrolled(dirY) || super.mouseScrolled(x, y, dirX, dirY); + public boolean mouseScrolled(double x, double y, double scrollX, double scrollY) { + return wrappedGui.mouseScrolled(x, y, scrollX, scrollY) || super.mouseScrolled(x, y, scrollX, scrollY); } @Override diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/ScrollBar.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/ScrollBar.java index 02c69db2..d8a52f2b 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/ScrollBar.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/ScrollBar.java @@ -73,9 +73,10 @@ public boolean mousePressed(MouseButton button) { } @Override - public boolean mouseScrolled(double scroll) { - if (scroll != 0 && canMouseScrollPlane() && canMouseScroll()) { - setValue(getValue() - getScrollStep() * scroll); + public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) { + var scrollDelta = scrollY == 0 ? scrollX : scrollY; + if (scrollDelta != 0 && canMouseScrollPlane() && canMouseScroll()) { + setValue(getValue() - getScrollStep() * scrollDelta); return true; } diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/TextField.java b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/TextField.java index ac962fdc..cf9182e9 100644 --- a/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/TextField.java +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/client/gui/widget/TextField.java @@ -7,13 +7,20 @@ import dev.ftb.mods.ftblibrary.math.Bits; import dev.ftb.mods.ftblibrary.util.TooltipList; import net.minecraft.client.gui.ActiveTextCollector; +import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.gui.TextAlignment; +import net.minecraft.client.renderer.state.gui.GuiTextRenderState; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Style; +import net.minecraft.util.ARGB; import net.minecraft.util.FormattedCharSequence; import net.minecraft.util.Mth; +import org.joml.Matrix3x2f; +import org.jspecify.annotations.Nullable; import java.util.Optional; +import java.util.function.Consumer; public class TextField extends Widget { @@ -161,11 +168,64 @@ public Optional