Skip to content

Commit cdd8cc6

Browse files
authored
Global Search (#278)
* global search attempt * fix graphical bug * keep track of cursor position * prefer tab where you started searching * oops left a print * rebase and requested changes
1 parent 938f8be commit cdd8cc6

3 files changed

Lines changed: 73 additions & 2 deletions

File tree

src/main/java/dev/isxander/yacl3/gui/SearchFieldWidget.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class SearchFieldWidget extends EditBox {
1515
private final Consumer<String> updateConsumer;
1616

1717
private boolean isEmpty = true;
18+
private boolean doNotUpdate = false;
1819

1920
public SearchFieldWidget(YACLScreen yaclScreen, Font font, int x, int y, int width, int height, Component text, Component emptyText, Consumer<String> updateConsumer) {
2021
super(font, x, y, width, height, text);
@@ -33,13 +34,20 @@ public void extractWidgetRenderState(@NonNull GuiGraphicsExtractor graphics, int
3334
}
3435
}
3536

37+
public void setValueDoNotUpdate(String value) {
38+
doNotUpdate = true;
39+
setValue(value);
40+
doNotUpdate = false;
41+
}
42+
3643
private void update(String query) {
3744
boolean wasEmpty = isEmpty;
3845
isEmpty = query.isEmpty();
3946

4047
if (isEmpty && wasEmpty)
4148
return;
4249

50+
if (doNotUpdate) return;
4351
updateConsumer.accept(query);
4452
}
4553

src/main/java/dev/isxander/yacl3/gui/YACLScreen.java

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import net.minecraft.client.gui.components.Button;
2020
import net.minecraft.client.gui.components.MultiLineLabel;
2121
import net.minecraft.client.gui.components.Tooltip;
22+
import net.minecraft.client.gui.components.events.GuiEventListener;
23+
import net.minecraft.client.gui.components.tabs.Tab;
2224
import net.minecraft.client.gui.components.tabs.TabManager;
2325
import net.minecraft.client.gui.navigation.ScreenRectangle;
2426
import net.minecraft.client.gui.screens.Screen;
@@ -27,6 +29,7 @@
2729
import net.minecraft.client.renderer.RenderPipelines;
2830
import net.minecraft.network.chat.CommonComponents;
2931
import net.minecraft.network.chat.Component;
32+
import net.minecraft.network.chat.MutableComponent;
3033
import net.minecraft.resources.Identifier;
3134
import org.jetbrains.annotations.Nullable;
3235

@@ -54,6 +57,11 @@ public class YACLScreen extends Screen {
5457
public ControllerPopupWidget<?> currentPopupController = null;
5558
public boolean popupControllerVisible = false;
5659

60+
/**
61+
* The tab where the user started searching
62+
*/
63+
private @Nullable CategoryTab preferredTab = null;
64+
5765
public YACLScreen(YetAnotherConfigLib config, Screen parent) {
5866
super(config.title());
5967
this.config = config;
@@ -284,6 +292,43 @@ public static void renderMultilineTooltip(GuiGraphicsExtractor graphics, Font fo
284292
}
285293
}
286294

295+
public void updateGlobalSearch(String search) {
296+
Tab nextTabWithSearch = null;
297+
if (preferredTab != null) {
298+
preferredTab.optionList.getType().updateSearchQuery(search);
299+
if (preferredTab.hasSearch()) nextTabWithSearch = preferredTab;
300+
}
301+
Tab currentTab = tabNavigationBar.getTabManager().getCurrentTab();
302+
int cursorPos = currentTab instanceof CategoryTab categoryTab ? categoryTab.searchField.getCursorPosition() : -1;
303+
304+
for (int i = 0; i < tabNavigationBar.getTabs().size(); i++) {
305+
Tab tab = tabNavigationBar.getTabs().get(i);
306+
if (tab == preferredTab) continue;
307+
if (tab instanceof CategoryTab categoryTab) {
308+
categoryTab.optionList.getType().updateSearchQuery(search);
309+
categoryTab.searchField.setValueDoNotUpdate(search);
310+
if (cursorPos != -1) categoryTab.searchField.setCursorPosition(cursorPos);
311+
if (nextTabWithSearch == null && categoryTab.hasSearch()) {
312+
nextTabWithSearch = categoryTab;
313+
}
314+
}
315+
}
316+
// switch if the next tab is the preferred one or switch if the current tab does not have the search
317+
if (nextTabWithSearch != null && nextTabWithSearch != currentTab && (nextTabWithSearch == preferredTab || !(currentTab instanceof CategoryTab categoryTab && categoryTab.hasSearch()))) {
318+
tabManager.setCurrentTab(nextTabWithSearch, false);
319+
if (nextTabWithSearch instanceof CategoryTab newTab) {
320+
setFocused(newTab.searchField);
321+
}
322+
}
323+
tabNavigationBar.updateTabNames();
324+
}
325+
326+
@Override
327+
public void setFocused(@Nullable GuiEventListener focused) {
328+
super.setFocused(focused);
329+
if (focused != null && !(focused instanceof SearchFieldWidget)) preferredTab = null;
330+
}
331+
287332
public static class CategoryTab implements TabExt {
288333
private static final Identifier DARKER_BG = YACLPlatform.mcRl("textures/gui/menu_list_background.png");
289334

@@ -338,7 +383,11 @@ public CategoryTab(YACLScreen screen, ConfigCategory category, ScreenRectangle t
338383
paddedWidth - 2, 18,
339384
Component.translatable("gui.recipebook.search_hint"),
340385
Component.translatable("gui.recipebook.search_hint"),
341-
searchQuery -> optionList.getType().updateSearchQuery(searchQuery)
386+
s -> {
387+
if (screen.preferredTab == null) screen.preferredTab = this;
388+
screen.updateGlobalSearch(s);
389+
390+
}
342391
);
343392

344393
this.optionList = YACLSelectionList.asWidget(
@@ -360,9 +409,17 @@ public CategoryTab(YACLScreen screen, ConfigCategory category, ScreenRectangle t
360409
updateButtons();
361410
}
362411

412+
public boolean hasSearch() {
413+
return optionList.getType().children().stream().anyMatch(o -> o.searchQueryMatches);
414+
}
415+
363416
@Override
364417
public Component getTabTitle() {
365-
return category.name();
418+
MutableComponent copy = category.name().copy();
419+
if (!hasSearch()) {
420+
copy.withStyle(ChatFormatting.DARK_GRAY, ChatFormatting.STRIKETHROUGH);
421+
}
422+
return copy;
366423
}
367424

368425
@Override

src/main/java/dev/isxander/yacl3/gui/tab/ScrollableNavigationBar.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ protected void ensureVisible(TabButton tabButton) {
153153
}
154154
}
155155

156+
public void updateTabNames() {
157+
for (TabButton tabButton : accessor.yacl$getTabButtons()) {
158+
tabButton.setMessage(tabButton.tab().getTabTitle());
159+
}
160+
}
161+
156162
public ImmutableList<Tab> getTabs() {
157163
return accessor.yacl$getTabs();
158164
}

0 commit comments

Comments
 (0)