From f8cdb369181d5021d67d3157be992bb010b55433 Mon Sep 17 00:00:00 2001 From: olim88 Date: Sat, 10 Jan 2026 23:24:31 +0000 Subject: [PATCH 1/4] works --- .../skyblock/chat/ChatRuleConfigScreen.java | 46 +++- .../utils/render/gui/SoundSelectionPopup.java | 220 ++++++++++++++++++ .../assets/skyblocker/lang/en_us.json | 1 + 3 files changed, 265 insertions(+), 2 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRuleConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRuleConfigScreen.java index 5c3fb1cc8e2..e73b9c4be19 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRuleConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRuleConfigScreen.java @@ -4,6 +4,7 @@ import de.hysky.skyblocker.utils.datafixer.ItemStackComponentizationFixer; import de.hysky.skyblocker.utils.render.gui.ItemSelectionPopup; import de.hysky.skyblocker.utils.render.gui.RangedSliderWidget; +import de.hysky.skyblocker.utils.render.gui.SoundSelectionPopup; import de.hysky.skyblocker.utils.render.gui.ToggleableLayoutWidget; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.ChatFormatting; @@ -28,11 +29,13 @@ import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Style; +import net.minecraft.resources.Identifier; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.util.Util; @@ -52,6 +55,7 @@ public class ChatRuleConfigScreen extends Screen { private static final int COLUMN_WIDTH = 105; private static final int GRID_SPACING = 2; + protected static final Identifier SEARCH_ICON_TEXTURE = Identifier.withDefaultNamespace("icon/search"); private static final ItemStack INVALID_ITEM = new ItemStack(Items.BARRIER); private static final Component YES_TEXT = CommonComponents.GUI_YES.copy().withStyle(ChatFormatting.GREEN); private static final Component NO_TEXT = CommonComponents.GUI_NO.copy().withStyle(ChatFormatting.RED); @@ -78,6 +82,7 @@ public class ChatRuleConfigScreen extends Screen { private final HeaderAndFooterLayout layout = new HeaderAndFooterLayout(this); private final GridLayout content = new GridLayout().columnSpacing(GRID_SPACING); + private CycleButton soundButton; public ChatRuleConfigScreen(Screen parent, int chatRuleIndex) { super(Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen")); @@ -156,13 +161,17 @@ protected void init() { displayedValues.add(Optional.ofNullable(chatRule.getCustomSound())); } // using an optional since it doesn't allow null values. - buttons.addChild(CycleButton.builder(opt -> soundNames.get(opt.orElse(null)), Optional.ofNullable(chatRule.getCustomSound())) + soundButton = CycleButton.builder(opt -> soundNames.get(opt.orElse(null)), Optional.ofNullable(chatRule.getCustomSound())) .withValues(() -> true, displayedValues, availableValues) - .create(0, 0, getWidth(1.5f), 20, Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.sounds"), (button, value) -> { + .create(0, 0, getWidth(1.3f), 20, Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.sounds"), (button, value) -> { chatRule.setCustomSound(value.orElse(null)); value.ifPresent(soundEvent -> minecraft.getSoundManager().play(SimpleSoundInstance.forUI(soundEvent, 1.0F))); }) ).setTooltip(Tooltip.create(Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.@Tooltip"))); + }); + buttons.addChild(soundButton); + //search button + buttons.addChild(new SoundSearchMenu(), LayoutSettings::alignHorizontallyRight); // Chat message EditBox chatMessageInput = new EditBox(font, getWidth(2), 20, Component.empty()); @@ -371,6 +380,39 @@ public void onClick(MouseButtonEvent click, boolean doubled) { protected void updateWidgetNarration(NarrationElementOutput builder) {} } + private class SoundSearchMenu extends AbstractWidget { + + private SoundSearchMenu() { + super(0, 0, 16, 16, Component.empty()); + setTooltip(Tooltip.create(Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.search.@Tooltip"))); + } + + @Override + protected void renderWidget(GuiGraphics context, int mouseX, int mouseY, float deltaTicks) { + context.blitSprite(RenderPipelines.GUI_TEXTURED, SEARCH_ICON_TEXTURE, this.getX(), this.getY(), this.getWidth(), this.getHeight()); + } + + @Override + public void setX(int x) { + super.setX(x); + } + + @Override + public void onClick(MouseButtonEvent click, boolean doubled) { + super.onClick(click, doubled); + Objects.requireNonNull(minecraft); + minecraft.setScreen(new SoundSelectionPopup(ChatRuleConfigScreen.this, sound -> { + if (sound != null) { + chatRule.setCustomSound(sound); + soundButton.setMessage(Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.custom").withStyle(ChatFormatting.YELLOW)); + } + })); + } + + @Override + protected void updateWidgetNarration(NarrationElementOutput builder) {} + } + private class ContentContainer extends AbstractContainerWidget implements Layout { private static final int SIDE_PADDING = 10; private final List children = new ArrayList<>(); diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java new file mode 100644 index 00000000000..f00c1d731a8 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java @@ -0,0 +1,220 @@ +package de.hysky.skyblocker.utils.render.gui; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractContainerWidget; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.StringWidget; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.layouts.GridLayout; +import net.minecraft.client.gui.layouts.LinearLayout; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.client.resources.sounds.SimpleSoundInstance; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.function.Consumer; + +public class SoundSelectionPopup extends AbstractPopupScreen { + + private final List filteredWidgets = new ObjectArrayList<>(); + private final Consumer<@Nullable SoundEvent> onDone; + private @Nullable SoundEvent selectedSound = null; + + private final GridLayout gridWidget = new GridLayout(); + private LinearLayout listLayout = new LinearLayout(0, 0, LinearLayout.Orientation.VERTICAL); + private @Nullable Button doneButton; + private EditBox searchField; + private ListContainer widgetsContainer; + + public SoundSelectionPopup(Screen backgroundScreen, Consumer<@Nullable SoundEvent> onDone) { + super(Component.literal("Select Sound"), backgroundScreen); + this.onDone = onDone; + + } + + @Override + protected void init() { + GridLayout.RowHelper adder = gridWidget.createRowHelper(2); + searchField = new EditBox(Minecraft.getInstance().font, 400, 20, Component.translatable("gui.recipebook.search_hint")); + searchField.setHint(Component.translatable("gui.recipebook.search_hint").withStyle(ChatFormatting.ITALIC).withStyle(ChatFormatting.GRAY)); + searchField.setResponder(this::filterSounds); + addRenderableWidget(adder.addChild(searchField, 2)); + + widgetsContainer = new ListContainer(0, 0, 400, this.height / 2); + + addRenderableWidget(adder.addChild(widgetsContainer, 2)); + + addRenderableWidget(adder.addChild(Button.builder(CommonComponents.GUI_CANCEL, b -> { + onClose(); + onDone.accept(null); + }).build())); + doneButton = Button.builder(CommonComponents.GUI_DONE, b -> { + onClose(); + onDone.accept(selectedSound); + }).build(); + doneButton.active = false; + addRenderableWidget(adder.addChild(doneButton)); + gridWidget.arrangeElements(); + repositionElements(); + filterSounds(""); + } + @Nullable + private Component getSoundName (SoundEvent sound){ + String key = BuiltInRegistries.SOUND_EVENT.getKey(sound).toShortLanguageKey(); + //first check for translation + Component translation = Component.translatableWithFallback("subtitles." + key, "null"); + if (!translation.getString().equals("null")){ + return translation; + } + //convert note block sounds + if (key.contains("note_block")){ + String[] split = key.split("\\."); + return Component.literal("note block " + split[split.length -1].replace("_", " ")); + } + return null; + + + } + + private void filterSounds(String input) { + filteredWidgets.clear(); + for (SoundEvent soundEvent : BuiltInRegistries.SOUND_EVENT) { + Component translation = getSoundName(soundEvent); + //filter sounds + if (translation != null && translation.getString().toLowerCase().contains(input.toLowerCase())) { + AbstractWidget widget = new SoundWidget(translation, soundEvent); + filteredWidgets.add(widget); + } + + + } + int listX = listLayout.getX(); + int listY = listLayout.getY(); + listLayout = new LinearLayout(0, 0, LinearLayout.Orientation.VERTICAL); + filteredWidgets.forEach(listLayout::addChild); + listLayout.arrangeElements(); + listLayout.setPosition(listX, listY); + widgetsContainer.refreshScrollAmount(); + } + + @Override + protected void repositionElements() { + gridWidget.setPosition((width - gridWidget.getWidth()) / 2, (height - gridWidget.getHeight()) / 2); + } + + @Override + public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float delta) { + super.renderBackground(context, mouseX, mouseY, delta); + drawPopupBackground(context, gridWidget.getX(), gridWidget.getY(), gridWidget.getWidth(), gridWidget.getHeight()); + } + + private class ListContainer extends AbstractContainerWidget { + + public ListContainer(int i, int j, int k, int l) { + super(i, j, k, l, Component.literal("List")); + } + + @Override + protected int contentHeight() { + return listLayout.getHeight(); + } + + @Override + protected double scrollRate() { + return 15; + } + + @Override + public void setScrollAmount(double scrollY) { + super.setScrollAmount(scrollY); + listLayout.setY(getY() - (int) scrollAmount()); + } + + private boolean isVisible(AbstractWidget widget) { + return widget.getBottom() >= getY() && widget.getY() < getBottom(); + } + + @Override + protected void renderWidget(GuiGraphics context, int mouseX, int mouseY, float deltaTicks) { + context.enableScissor(getX(), getY(), getRight(), getBottom()); + for (AbstractWidget widget : filteredWidgets) { + if (isVisible(widget)) widget.render(context, mouseX, mouseY, deltaTicks); + } + renderScrollbar(context, mouseX, mouseY); + context.disableScissor(); + } + + @Override + public void setX(int x) { + super.setX(x); + listLayout.setX(x); + } + + @Override + public void setY(int y) { + super.setY(y); + listLayout.setY(y); + } + + @Override + protected void updateWidgetNarration(NarrationElementOutput narrationElementOutput) { + + } + + @Override + public List children() { + return filteredWidgets; + } + } + + private class SoundWidget extends StringWidget { + SoundEvent sound; + Component name; + + public SoundWidget(Component name, SoundEvent sound) { + super(name, font); + this.name = name; + this.sound = sound; + this.active = true; + } + + @Override + public int getHeight() { + return super.getHeight() + 10; + } + + @Override + public void renderWidget(GuiGraphics context, int mouseX, int mouseY, float delta) { + super.renderWidget(context, mouseX, mouseY, delta); + if (selectedSound == sound) { + context.fill(RenderPipelines.GUI,this.getX(),this.getY(),this.getRight(),this.getBottom(),0x3000FF00); + } else if (this.isHovered){ + context.fill(RenderPipelines.GUI,this.getX(),this.getY(),this.getRight(),this.getBottom(),0x20FFFFFF); + } + } + + @Override + public void onClick(MouseButtonEvent click, boolean doubled) { + selectedSound = sound; + if (doneButton != null) doneButton.active = true; + minecraft.getSoundManager().stop(); + minecraft.getSoundManager().play(SimpleSoundInstance.forUI(sound, 1.0F)); + super.onClick(click, doubled); + } + } + +} diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 2b736ff249f..b05f08aea7c 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -105,6 +105,7 @@ "skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.none": "None", "skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.pling": "Pling", "skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.zombie": "Zombie", + "skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.search.@Tooltip": "Search more sounds", "skyblocker.config.chat.chatRules.screen.ruleScreen.toast": "Toast:", "skyblocker.config.chat.chatRules.screen.ruleScreen.toast.duration": "Toast Duration", "skyblocker.config.chat.chatRules.screen.ruleScreen.toast.duration.@Tooltip": "How long the toast stays on screen.", From b78d1ac672d4bf300e3068a6eebbb39da060236a Mon Sep 17 00:00:00 2001 From: olim88 Date: Thu, 29 Jan 2026 19:29:49 +0000 Subject: [PATCH 2/4] small bugs I can't remember but i think this is just fixing some small bugs --- .../utils/render/gui/SoundSelectionPopup.java | 48 +++++++++++-------- .../assets/skyblocker/lang/en_us.json | 2 +- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java index f00c1d731a8..f4a1799c065 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java @@ -7,8 +7,10 @@ import net.minecraft.client.gui.components.AbstractContainerWidget; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.CycleButton; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.components.StringWidget; +import net.minecraft.client.gui.components.Tooltip; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.layouts.GridLayout; import net.minecraft.client.gui.layouts.LinearLayout; @@ -20,25 +22,25 @@ import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; import net.minecraft.sounds.SoundEvent; -import net.minecraft.sounds.SoundEvents; import org.jspecify.annotations.Nullable; import java.util.List; import java.util.function.Consumer; public class SoundSelectionPopup extends AbstractPopupScreen { + private static final Component YES_TEXT = CommonComponents.GUI_YES.copy().withStyle(ChatFormatting.GREEN); + private static final Component NO_TEXT = CommonComponents.GUI_NO.copy().withStyle(ChatFormatting.RED); private final List filteredWidgets = new ObjectArrayList<>(); private final Consumer<@Nullable SoundEvent> onDone; private @Nullable SoundEvent selectedSound = null; + private boolean advanced = false; private final GridLayout gridWidget = new GridLayout(); private LinearLayout listLayout = new LinearLayout(0, 0, LinearLayout.Orientation.VERTICAL); private @Nullable Button doneButton; - private EditBox searchField; - private ListContainer widgetsContainer; + private @Nullable ListContainer widgetsContainer; public SoundSelectionPopup(Screen backgroundScreen, Consumer<@Nullable SoundEvent> onDone) { super(Component.literal("Select Sound"), backgroundScreen); @@ -49,10 +51,13 @@ public SoundSelectionPopup(Screen backgroundScreen, Consumer<@Nullable SoundEven @Override protected void init() { GridLayout.RowHelper adder = gridWidget.createRowHelper(2); - searchField = new EditBox(Minecraft.getInstance().font, 400, 20, Component.translatable("gui.recipebook.search_hint")); + EditBox searchField = new EditBox(Minecraft.getInstance().font, 300, 20, Component.translatable("gui.recipebook.search_hint")); searchField.setHint(Component.translatable("gui.recipebook.search_hint").withStyle(ChatFormatting.ITALIC).withStyle(ChatFormatting.GRAY)); searchField.setResponder(this::filterSounds); - addRenderableWidget(adder.addChild(searchField, 2)); + addRenderableWidget(adder.addChild(searchField, 1)); + addRenderableWidget((adder.addChild(CycleButton.booleanBuilder(YES_TEXT, NO_TEXT, advanced) + .withTooltip(b -> Tooltip.create(Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.regex.@Tooltip"))) + .create(0, 0, 100, 20, Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.regex"), (button, value) -> advanced = !advanced),1))); widgetsContainer = new ListContainer(0, 0, 400, this.height / 2); @@ -72,20 +77,20 @@ protected void init() { repositionElements(); filterSounds(""); } - @Nullable - private Component getSoundName (SoundEvent sound){ + + private Component getSoundName(SoundEvent sound) { String key = BuiltInRegistries.SOUND_EVENT.getKey(sound).toShortLanguageKey(); //first check for translation Component translation = Component.translatableWithFallback("subtitles." + key, "null"); - if (!translation.getString().equals("null")){ + if (!translation.getString().equals("null")) { return translation; } //convert note block sounds - if (key.contains("note_block")){ + if (key.contains("note_block")) { String[] split = key.split("\\."); - return Component.literal("note block " + split[split.length -1].replace("_", " ")); + return Component.literal("note block " + split[split.length - 1].replace("_", " ")); } - return null; + return Component.literal(key); } @@ -95,20 +100,24 @@ private void filterSounds(String input) { for (SoundEvent soundEvent : BuiltInRegistries.SOUND_EVENT) { Component translation = getSoundName(soundEvent); //filter sounds - if (translation != null && translation.getString().toLowerCase().contains(input.toLowerCase())) { + if (translation.getString().toLowerCase().contains(input.toLowerCase())) { AbstractWidget widget = new SoundWidget(translation, soundEvent); filteredWidgets.add(widget); } - - } + recreateList(); + } + + private void recreateList() { int listX = listLayout.getX(); int listY = listLayout.getY(); listLayout = new LinearLayout(0, 0, LinearLayout.Orientation.VERTICAL); filteredWidgets.forEach(listLayout::addChild); listLayout.arrangeElements(); listLayout.setPosition(listX, listY); - widgetsContainer.refreshScrollAmount(); + if (widgetsContainer != null) { + widgetsContainer.refreshScrollAmount(); + } } @Override @@ -201,9 +210,9 @@ public int getHeight() { public void renderWidget(GuiGraphics context, int mouseX, int mouseY, float delta) { super.renderWidget(context, mouseX, mouseY, delta); if (selectedSound == sound) { - context.fill(RenderPipelines.GUI,this.getX(),this.getY(),this.getRight(),this.getBottom(),0x3000FF00); - } else if (this.isHovered){ - context.fill(RenderPipelines.GUI,this.getX(),this.getY(),this.getRight(),this.getBottom(),0x20FFFFFF); + context.fill(RenderPipelines.GUI, this.getX(), this.getY(), this.getRight(), this.getBottom(), 0x3000FF00); + } else if (this.isHovered) { + context.fill(RenderPipelines.GUI, this.getX(), this.getY(), this.getRight(), this.getBottom(), 0x20FFFFFF); } } @@ -216,5 +225,4 @@ public void onClick(MouseButtonEvent click, boolean doubled) { super.onClick(click, doubled); } } - } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index b05f08aea7c..cf11042b251 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -104,8 +104,8 @@ "skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.custom": "Custom", "skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.none": "None", "skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.pling": "Pling", - "skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.zombie": "Zombie", "skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.search.@Tooltip": "Search more sounds", + "skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.zombie": "Zombie", "skyblocker.config.chat.chatRules.screen.ruleScreen.toast": "Toast:", "skyblocker.config.chat.chatRules.screen.ruleScreen.toast.duration": "Toast Duration", "skyblocker.config.chat.chatRules.screen.ruleScreen.toast.duration.@Tooltip": "How long the toast stays on screen.", From dd548a07ba34f935b11a5e7c5385768e94ba96a8 Mon Sep 17 00:00:00 2001 From: olim88 Date: Thu, 5 Feb 2026 17:32:25 +0000 Subject: [PATCH 3/4] add advanced button to toggle the availability of untranslated sounds --- .../skyblock/chat/ChatRuleConfigScreen.java | 4 +-- .../utils/render/gui/SoundSelectionPopup.java | 28 +++++++++++++------ .../assets/skyblocker/lang/en_us.json | 3 ++ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRuleConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRuleConfigScreen.java index e73b9c4be19..2e973bd9f10 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRuleConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRuleConfigScreen.java @@ -163,12 +163,12 @@ protected void init() { // using an optional since it doesn't allow null values. soundButton = CycleButton.builder(opt -> soundNames.get(opt.orElse(null)), Optional.ofNullable(chatRule.getCustomSound())) .withValues(() -> true, displayedValues, availableValues) + .create(0, 0, getWidth(1.3f), 20, Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.sounds"), (button, value) -> { chatRule.setCustomSound(value.orElse(null)); value.ifPresent(soundEvent -> minecraft.getSoundManager().play(SimpleSoundInstance.forUI(soundEvent, 1.0F))); - }) - ).setTooltip(Tooltip.create(Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.@Tooltip"))); }); + soundButton.setTooltip(Tooltip.create(Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.sounds.@Tooltip"))); buttons.addChild(soundButton); //search button buttons.addChild(new SoundSearchMenu(), LayoutSettings::alignHorizontallyRight); diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java index f4a1799c065..637d08e0129 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java @@ -35,7 +35,7 @@ public class SoundSelectionPopup extends AbstractPopupScreen { private final List filteredWidgets = new ObjectArrayList<>(); private final Consumer<@Nullable SoundEvent> onDone; private @Nullable SoundEvent selectedSound = null; - private boolean advanced = false; + private boolean advanced = false; private final GridLayout gridWidget = new GridLayout(); private LinearLayout listLayout = new LinearLayout(0, 0, LinearLayout.Orientation.VERTICAL); @@ -51,13 +51,19 @@ public SoundSelectionPopup(Screen backgroundScreen, Consumer<@Nullable SoundEven @Override protected void init() { GridLayout.RowHelper adder = gridWidget.createRowHelper(2); - EditBox searchField = new EditBox(Minecraft.getInstance().font, 300, 20, Component.translatable("gui.recipebook.search_hint")); + EditBox searchField = new EditBox(Minecraft.getInstance().font, 200, 20, Component.empty()); searchField.setHint(Component.translatable("gui.recipebook.search_hint").withStyle(ChatFormatting.ITALIC).withStyle(ChatFormatting.GRAY)); searchField.setResponder(this::filterSounds); - addRenderableWidget(adder.addChild(searchField, 1)); - addRenderableWidget((adder.addChild(CycleButton.booleanBuilder(YES_TEXT, NO_TEXT, advanced) - .withTooltip(b -> Tooltip.create(Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.regex.@Tooltip"))) - .create(0, 0, 100, 20, Component.translatable("skyblocker.config.chat.chatRules.screen.ruleScreen.regex"), (button, value) -> advanced = !advanced),1))); + addRenderableWidget(adder.addChild(searchField)); + + CycleButton toggleAdvanced = CycleButton.booleanBuilder(YES_TEXT, NO_TEXT, advanced) + .withTooltip(b -> Tooltip.create(Component.translatable("skyblocker.utils.render.gui.soundSelectionPopup.advanced.@Tooltip"))) + .create(0, 0, 100, 20, Component.translatable("skyblocker.utils.render.gui.soundSelectionPopup.advanced"), (button, value) -> { + advanced = !advanced; + filterSounds(searchField.getValue()); + }); + + addRenderableWidget(adder.addChild(toggleAdvanced)); widgetsContainer = new ListContainer(0, 0, 400, this.height / 2); @@ -78,7 +84,7 @@ protected void init() { filterSounds(""); } - private Component getSoundName(SoundEvent sound) { + private @Nullable Component getSoundName(SoundEvent sound) { String key = BuiltInRegistries.SOUND_EVENT.getKey(sound).toShortLanguageKey(); //first check for translation Component translation = Component.translatableWithFallback("subtitles." + key, "null"); @@ -90,7 +96,11 @@ private Component getSoundName(SoundEvent sound) { String[] split = key.split("\\."); return Component.literal("note block " + split[split.length - 1].replace("_", " ")); } - return Component.literal(key); + if (advanced) { + return Component.literal(key); + } else { + return null; + } } @@ -100,7 +110,7 @@ private void filterSounds(String input) { for (SoundEvent soundEvent : BuiltInRegistries.SOUND_EVENT) { Component translation = getSoundName(soundEvent); //filter sounds - if (translation.getString().toLowerCase().contains(input.toLowerCase())) { + if (translation != null && translation.getString().toLowerCase().contains(input.toLowerCase())) { AbstractWidget widget = new SoundWidget(translation, soundEvent); filteredWidgets.add(widget); } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index cf11042b251..be9aa27259b 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -1813,6 +1813,9 @@ "skyblocker.utils.locationUpdateError": "Failed to update your location! Some features of the mod may not work properly :(", + "skyblocker.utils.render.gui.soundSelectionPopup.advanced": "Advanced", + "skyblocker.utils.render.gui.soundSelectionPopup.advanced.@Tooltip": "Show sounds without a propper name", + "skyblocker.valueBreakdownPopup": "Skyblocker Estimated Value Breakdown", "skyblocker.valueBreakdownPopup.baseItemPrice": "Base item price: %s", "skyblocker.valueBreakdownPopup.coins": "%s coins", From 1085486985025849091f2bbe4c9a27b4e723afd6 Mon Sep 17 00:00:00 2001 From: olim88 Date: Thu, 5 Feb 2026 17:37:09 +0000 Subject: [PATCH 4/4] spotless and checkstyle --- .../skyblocker/utils/render/gui/SoundSelectionPopup.java | 7 ++++--- src/main/resources/assets/skyblocker/lang/en_us.json | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java index 637d08e0129..bdd9376b0ab 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/SoundSelectionPopup.java @@ -26,6 +26,7 @@ import org.jspecify.annotations.Nullable; import java.util.List; +import java.util.Locale; import java.util.function.Consumer; public class SoundSelectionPopup extends AbstractPopupScreen { @@ -110,7 +111,7 @@ private void filterSounds(String input) { for (SoundEvent soundEvent : BuiltInRegistries.SOUND_EVENT) { Component translation = getSoundName(soundEvent); //filter sounds - if (translation != null && translation.getString().toLowerCase().contains(input.toLowerCase())) { + if (translation != null && translation.getString().toLowerCase(Locale.ENGLISH).contains(input.toLowerCase(Locale.ENGLISH))) { AbstractWidget widget = new SoundWidget(translation, soundEvent); filteredWidgets.add(widget); } @@ -143,7 +144,7 @@ public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float private class ListContainer extends AbstractContainerWidget { - public ListContainer(int i, int j, int k, int l) { + ListContainer(int i, int j, int k, int l) { super(i, j, k, l, Component.literal("List")); } @@ -204,7 +205,7 @@ private class SoundWidget extends StringWidget { SoundEvent sound; Component name; - public SoundWidget(Component name, SoundEvent sound) { + SoundWidget(Component name, SoundEvent sound) { super(name, font); this.name = name; this.sound = sound; diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index be9aa27259b..21e0370d9ca 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -1812,7 +1812,6 @@ "skyblocker.updateRepository.success": "§aUpdated the local repository successfully.", "skyblocker.utils.locationUpdateError": "Failed to update your location! Some features of the mod may not work properly :(", - "skyblocker.utils.render.gui.soundSelectionPopup.advanced": "Advanced", "skyblocker.utils.render.gui.soundSelectionPopup.advanced.@Tooltip": "Show sounds without a propper name",