From 6083a4c86cadb3def0eb599e49e3a2c6ebeebb62 Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sun, 8 Jun 2025 15:39:17 +0200 Subject: [PATCH 1/6] global search attempt --- .../isxander/yacl3/gui/SearchFieldWidget.java | 8 +++++ .../dev/isxander/yacl3/gui/YACLScreen.java | 36 +++++++++++++++++-- .../gui/tab/ScrollableNavigationBar.java | 6 ++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/main/java/dev/isxander/yacl3/gui/SearchFieldWidget.java b/src/main/java/dev/isxander/yacl3/gui/SearchFieldWidget.java index a6668865..756630b5 100644 --- a/src/main/java/dev/isxander/yacl3/gui/SearchFieldWidget.java +++ b/src/main/java/dev/isxander/yacl3/gui/SearchFieldWidget.java @@ -14,6 +14,7 @@ public class SearchFieldWidget extends EditBox { private final Consumer updateConsumer; private boolean isEmpty = true; + private boolean doNotUpdate = false; public SearchFieldWidget(YACLScreen yaclScreen, Font font, int x, int y, int width, int height, Component text, Component emptyText, Consumer updateConsumer) { super(font, x, y, width, height, text); @@ -33,7 +34,14 @@ public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float del } } + public void setValueDoNotUpdate(String value) { + doNotUpdate = true; + setValue(value); + doNotUpdate = false; + } + private void update(String query) { + if (doNotUpdate) return; boolean wasEmpty = isEmpty; isEmpty = query.isEmpty(); diff --git a/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java b/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java index 8a0f53f2..9a505b13 100644 --- a/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java +++ b/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java @@ -21,6 +21,7 @@ import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.MultiLineLabel; import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.components.tabs.Tab; import net.minecraft.client.gui.components.tabs.TabManager; import net.minecraft.client.gui.navigation.ScreenRectangle; import net.minecraft.client.gui.screens.Screen; @@ -28,6 +29,7 @@ import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.Nullable; @@ -313,6 +315,28 @@ public static void renderMultilineTooltip(GuiGraphics graphics, Font font, Multi } } + public void updateGlobalSearch(String search) { + int nextTabWithSearch = -1; + for (int i = 0; i < tabNavigationBar.getTabs().size(); i++) { + Tab tab = tabNavigationBar.getTabs().get(i); + if (tab instanceof CategoryTab categoryTab) { + categoryTab.optionList.getList().updateSearchQuery(search); + categoryTab.searchField.setValueDoNotUpdate(search); + if (nextTabWithSearch == -1 && categoryTab.hasSearch()) { + nextTabWithSearch = i; + } + } + } + Tab tab = tabNavigationBar.getTabManager().getCurrentTab(); + if (nextTabWithSearch != -1 && tab instanceof CategoryTab categoryTab && !categoryTab.hasSearch()) { + tabNavigationBar.selectTab(nextTabWithSearch, false); + if (tabNavigationBar.getTabManager().getCurrentTab() instanceof CategoryTab newTab) { + setFocused(newTab.searchField); + } + } + tabNavigationBar.updateTabNames(); + } + public static class CategoryTab implements TabExt { private static final ResourceLocation DARKER_BG = YACLPlatform.mcRl("textures/gui/menu_list_background.png"); @@ -367,7 +391,7 @@ public CategoryTab(YACLScreen screen, ConfigCategory category, ScreenRectangle t paddedWidth - 2, 18, Component.translatable("gui.recipebook.search_hint"), Component.translatable("gui.recipebook.search_hint"), - searchQuery -> optionList.getType().updateSearchQuery(searchQuery) + screen::updateGlobalSearch ); this.optionList = YACLSelectionList.asWidget( @@ -389,9 +413,17 @@ public CategoryTab(YACLScreen screen, ConfigCategory category, ScreenRectangle t updateButtons(); } + public boolean hasSearch() { + return !optionList.getList().children().isEmpty(); + } + @Override public Component getTabTitle() { - return category.name(); + MutableComponent copy = category.name().copy(); + if (!hasSearch()) { + copy.withStyle(ChatFormatting.DARK_GRAY, ChatFormatting.STRIKETHROUGH); + } + return copy; } @Override diff --git a/src/main/java/dev/isxander/yacl3/gui/tab/ScrollableNavigationBar.java b/src/main/java/dev/isxander/yacl3/gui/tab/ScrollableNavigationBar.java index 72210b82..3a257d1b 100644 --- a/src/main/java/dev/isxander/yacl3/gui/tab/ScrollableNavigationBar.java +++ b/src/main/java/dev/isxander/yacl3/gui/tab/ScrollableNavigationBar.java @@ -155,6 +155,12 @@ protected void ensureVisible(TabButton tabButton) { } } + public void updateTabNames() { + for (TabButton tabButton : accessor.yacl$getTabButtons()) { + tabButton.setMessage(tabButton.tab().getTabTitle()); + } + } + public ImmutableList getTabs() { return accessor.yacl$getTabs(); } From 847af8aa4b128685f158f602703704ad2cff0096 Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sun, 8 Jun 2025 15:47:02 +0200 Subject: [PATCH 2/6] fix graphical bug --- src/main/java/dev/isxander/yacl3/gui/SearchFieldWidget.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/dev/isxander/yacl3/gui/SearchFieldWidget.java b/src/main/java/dev/isxander/yacl3/gui/SearchFieldWidget.java index 756630b5..37adf997 100644 --- a/src/main/java/dev/isxander/yacl3/gui/SearchFieldWidget.java +++ b/src/main/java/dev/isxander/yacl3/gui/SearchFieldWidget.java @@ -41,13 +41,13 @@ public void setValueDoNotUpdate(String value) { } private void update(String query) { - if (doNotUpdate) return; boolean wasEmpty = isEmpty; isEmpty = query.isEmpty(); if (isEmpty && wasEmpty) return; + if (doNotUpdate) return; updateConsumer.accept(query); } From 5b621d2022a530454bd09a4db94e3f84d4f3f4d7 Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sun, 8 Jun 2025 16:39:33 +0200 Subject: [PATCH 3/6] keep track of cursor position --- src/main/java/dev/isxander/yacl3/gui/YACLScreen.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java b/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java index 9a505b13..80ed3433 100644 --- a/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java +++ b/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java @@ -317,18 +317,21 @@ public static void renderMultilineTooltip(GuiGraphics graphics, Font font, Multi public void updateGlobalSearch(String search) { int nextTabWithSearch = -1; + Tab currentTab = tabNavigationBar.getTabManager().getCurrentTab(); + int cursorPos = currentTab instanceof CategoryTab categoryTab ? categoryTab.searchField.getCursorPosition() : -1; + for (int i = 0; i < tabNavigationBar.getTabs().size(); i++) { Tab tab = tabNavigationBar.getTabs().get(i); if (tab instanceof CategoryTab categoryTab) { categoryTab.optionList.getList().updateSearchQuery(search); categoryTab.searchField.setValueDoNotUpdate(search); + if (cursorPos != -1) categoryTab.searchField.setCursorPosition(cursorPos); if (nextTabWithSearch == -1 && categoryTab.hasSearch()) { nextTabWithSearch = i; } } } - Tab tab = tabNavigationBar.getTabManager().getCurrentTab(); - if (nextTabWithSearch != -1 && tab instanceof CategoryTab categoryTab && !categoryTab.hasSearch()) { + if (nextTabWithSearch != -1 && currentTab instanceof CategoryTab categoryTab && !categoryTab.hasSearch()) { tabNavigationBar.selectTab(nextTabWithSearch, false); if (tabNavigationBar.getTabManager().getCurrentTab() instanceof CategoryTab newTab) { setFocused(newTab.searchField); From 482b927b1458ac1146e8bff38b35fce42b69603c Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sat, 13 Sep 2025 12:09:24 +0200 Subject: [PATCH 4/6] prefer tab where you started searching --- .../dev/isxander/yacl3/gui/YACLScreen.java | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java b/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java index 80ed3433..be1be2e7 100644 --- a/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java +++ b/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java @@ -58,6 +58,11 @@ public class YACLScreen extends Screen { public ControllerPopupWidget currentPopupController = null; public boolean popupControllerVisible = false; + /** + * The tab where the user started searching + */ + private @Nullable CategoryTab preferredTab = null; + public YACLScreen(YetAnotherConfigLib config, Screen parent) { super(config.title()); this.config = config; @@ -209,6 +214,7 @@ public boolean mouseClicked(MouseButtonEvent mouseButtonEvent, boolean bl) { //?} else { /*@Override public boolean mouseClicked(double mouseX, double mouseY, int button) { + preferredTab = null; if (super.mouseClicked(mouseX, mouseY, button)) { this.setDragging(true); return true; @@ -316,24 +322,31 @@ public static void renderMultilineTooltip(GuiGraphics graphics, Font font, Multi } public void updateGlobalSearch(String search) { - int nextTabWithSearch = -1; + Tab nextTabWithSearch = null; + if (preferredTab != null) { + System.out.println(preferredTab.getTabTitle().getString()); + preferredTab.optionList.getList().updateSearchQuery(search); + if (preferredTab.hasSearch()) nextTabWithSearch = preferredTab; + } else System.out.println("no preferred tab :("); Tab currentTab = tabNavigationBar.getTabManager().getCurrentTab(); int cursorPos = currentTab instanceof CategoryTab categoryTab ? categoryTab.searchField.getCursorPosition() : -1; for (int i = 0; i < tabNavigationBar.getTabs().size(); i++) { Tab tab = tabNavigationBar.getTabs().get(i); + if (tab == preferredTab) continue; if (tab instanceof CategoryTab categoryTab) { categoryTab.optionList.getList().updateSearchQuery(search); categoryTab.searchField.setValueDoNotUpdate(search); if (cursorPos != -1) categoryTab.searchField.setCursorPosition(cursorPos); - if (nextTabWithSearch == -1 && categoryTab.hasSearch()) { - nextTabWithSearch = i; + if (nextTabWithSearch == null && categoryTab.hasSearch()) { + nextTabWithSearch = categoryTab; } } } - if (nextTabWithSearch != -1 && currentTab instanceof CategoryTab categoryTab && !categoryTab.hasSearch()) { - tabNavigationBar.selectTab(nextTabWithSearch, false); - if (tabNavigationBar.getTabManager().getCurrentTab() instanceof CategoryTab newTab) { + // switch if the next tab is the preferred one or switch if the current tab does not have the search + if (nextTabWithSearch != null && nextTabWithSearch != currentTab && (nextTabWithSearch == preferredTab || !(currentTab instanceof CategoryTab categoryTab && categoryTab.hasSearch()))) { + tabManager.setCurrentTab(nextTabWithSearch, false); + if (nextTabWithSearch instanceof CategoryTab newTab) { setFocused(newTab.searchField); } } @@ -394,7 +407,11 @@ public CategoryTab(YACLScreen screen, ConfigCategory category, ScreenRectangle t paddedWidth - 2, 18, Component.translatable("gui.recipebook.search_hint"), Component.translatable("gui.recipebook.search_hint"), - screen::updateGlobalSearch + s -> { + if (screen.preferredTab == null) screen.preferredTab = this; + screen.updateGlobalSearch(s); + + } ); this.optionList = YACLSelectionList.asWidget( From d3c791b80cf4a21e9c3144f0d01b961ce213bec2 Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sat, 13 Sep 2025 12:10:59 +0200 Subject: [PATCH 5/6] oops left a print --- src/main/java/dev/isxander/yacl3/gui/YACLScreen.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java b/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java index be1be2e7..187e54c3 100644 --- a/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java +++ b/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java @@ -324,10 +324,9 @@ public static void renderMultilineTooltip(GuiGraphics graphics, Font font, Multi public void updateGlobalSearch(String search) { Tab nextTabWithSearch = null; if (preferredTab != null) { - System.out.println(preferredTab.getTabTitle().getString()); preferredTab.optionList.getList().updateSearchQuery(search); if (preferredTab.hasSearch()) nextTabWithSearch = preferredTab; - } else System.out.println("no preferred tab :("); + } Tab currentTab = tabNavigationBar.getTabManager().getCurrentTab(); int cursorPos = currentTab instanceof CategoryTab categoryTab ? categoryTab.searchField.getCursorPosition() : -1; From ce5afc43edc52dd24d6d9fd91c063b6e4eb9fab7 Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Fri, 17 Oct 2025 16:47:57 +0200 Subject: [PATCH 6/6] rebase and requested changes --- .../java/dev/isxander/yacl3/gui/YACLScreen.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java b/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java index 187e54c3..5661f624 100644 --- a/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java +++ b/src/main/java/dev/isxander/yacl3/gui/YACLScreen.java @@ -21,6 +21,7 @@ import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.MultiLineLabel; import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.components.tabs.Tab; import net.minecraft.client.gui.components.tabs.TabManager; import net.minecraft.client.gui.navigation.ScreenRectangle; @@ -214,7 +215,6 @@ public boolean mouseClicked(MouseButtonEvent mouseButtonEvent, boolean bl) { //?} else { /*@Override public boolean mouseClicked(double mouseX, double mouseY, int button) { - preferredTab = null; if (super.mouseClicked(mouseX, mouseY, button)) { this.setDragging(true); return true; @@ -324,7 +324,7 @@ public static void renderMultilineTooltip(GuiGraphics graphics, Font font, Multi public void updateGlobalSearch(String search) { Tab nextTabWithSearch = null; if (preferredTab != null) { - preferredTab.optionList.getList().updateSearchQuery(search); + preferredTab.optionList.getType().updateSearchQuery(search); if (preferredTab.hasSearch()) nextTabWithSearch = preferredTab; } Tab currentTab = tabNavigationBar.getTabManager().getCurrentTab(); @@ -334,7 +334,7 @@ public void updateGlobalSearch(String search) { Tab tab = tabNavigationBar.getTabs().get(i); if (tab == preferredTab) continue; if (tab instanceof CategoryTab categoryTab) { - categoryTab.optionList.getList().updateSearchQuery(search); + categoryTab.optionList.getType().updateSearchQuery(search); categoryTab.searchField.setValueDoNotUpdate(search); if (cursorPos != -1) categoryTab.searchField.setCursorPosition(cursorPos); if (nextTabWithSearch == null && categoryTab.hasSearch()) { @@ -352,6 +352,12 @@ public void updateGlobalSearch(String search) { tabNavigationBar.updateTabNames(); } + @Override + public void setFocused(@Nullable GuiEventListener focused) { + super.setFocused(focused); + if (focused != null && !(focused instanceof SearchFieldWidget)) preferredTab = null; + } + public static class CategoryTab implements TabExt { private static final ResourceLocation DARKER_BG = YACLPlatform.mcRl("textures/gui/menu_list_background.png"); @@ -433,7 +439,7 @@ public CategoryTab(YACLScreen screen, ConfigCategory category, ScreenRectangle t } public boolean hasSearch() { - return !optionList.getList().children().isEmpty(); + return optionList.getType().children().stream().anyMatch(o -> o.searchQueryMatches); } @Override