From 04e22991e2a7181d27678074324a1c846d783473 Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 26 Apr 2026 17:56:59 +0200 Subject: [PATCH 1/3] search bar --- .../editors/GuiOptionEditorDraggableList.java | 56 +++++++++++++++---- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java index 73a021541..c9ba80a06 100644 --- a/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java +++ b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java @@ -25,6 +25,7 @@ import io.github.notenoughupdates.moulconfig.common.text.StructuredText; import io.github.notenoughupdates.moulconfig.gui.GuiComponent; import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext; +import io.github.notenoughupdates.moulconfig.gui.KeyboardEvent; import io.github.notenoughupdates.moulconfig.gui.MouseEvent; import io.github.notenoughupdates.moulconfig.gui.component.*; import io.github.notenoughupdates.moulconfig.internal.*; @@ -332,6 +333,21 @@ private void reorderElements(int width, int mouseX, int mouseY) { GuiComponent makeDropDownOverlay() { return new GuiComponent() { + List remaining = new ArrayList<>(); + List filteredRemaining = new ArrayList<>(); + String searchText = ""; + + { + recalculateRemaining(); + } + + void recalculateRemaining() { + remaining = new ArrayList<>(exampleText.keySet()); + remaining.removeAll(activeText); + filteredRemaining = remaining.stream() + .filter(r -> getExampleText(r).getText().toLowerCase().contains(searchText.toLowerCase())) + .collect(Collectors.toList()); + } @Override public int getWidth() { @@ -340,9 +356,26 @@ public int getWidth() { @Override public int getHeight() { - List remaining = new ArrayList<>(exampleText.keySet()); - remaining.removeAll(activeText); - return -1 + 12 * remaining.size(); + return 11 + 12 * filteredRemaining.size(); + } + + @Override + public boolean keyboardEvent(@NotNull KeyboardEvent event, @NotNull GuiImmediateContext context) { + if (event instanceof KeyboardEvent.CharTyped) { + var typed = (KeyboardEvent.CharTyped) event; + searchText = searchText + typed.getChar(); + recalculateRemaining(); + } else if (event instanceof KeyboardEvent.KeyPressed) { + var pressed = (KeyboardEvent.KeyPressed) event; + if (pressed.getKeycode() == 259 && pressed.getPressed()) { + // if backspace, remove last character + if (!searchText.isEmpty()) { + searchText = searchText.substring(0, searchText.length() - 1); + recalculateRemaining(); + } + } + } + return super.keyboardEvent(event, context); } @Override @@ -350,12 +383,11 @@ public boolean mouseEvent(@NotNull MouseEvent mouseEvent, @NotNull GuiImmediateC if (mouseEvent instanceof MouseEvent.Click) { var click = (MouseEvent.Click) mouseEvent; if (click.getMouseState() && context.isHovered()) { - List remaining = new ArrayList<>(exampleText.keySet()); - remaining.removeAll(activeText); int dropdownY = -1; - for (Object indexObject : remaining) { + for (Object indexObject : filteredRemaining) { if (context.translated(0, dropdownY + 3, context.getWidth(), 10).isHovered()) { activeText.add(indexObject); + recalculateRemaining(); return true; } dropdownY += 12; @@ -369,9 +401,7 @@ public boolean mouseEvent(@NotNull MouseEvent mouseEvent, @NotNull GuiImmediateC @Override public void render(@NotNull GuiImmediateContext context) { - List remaining = new ArrayList<>(exampleText.keySet()); - remaining.removeAll(activeText); - if (remaining.isEmpty()) { + if (filteredRemaining.isEmpty()) { closeOverlay(); return; } @@ -395,8 +425,12 @@ public void render(@NotNull GuiImmediateContext context) { ); //Bottom renderContext.drawColoredRect(1, 1, dropdownWidth - 1, dropdownHeight - 1, main); //Middle - int dropdownY = -1; - for (Object indexObject : remaining) { + context.getRenderContext().drawStringScaledMaxWidth( + StructuredText.of(searchText), fr, 3, 3, false, + dropdownWidth - 16, 0xffa0a0a0 + ); + int dropdownY = 11; + for (Object indexObject : filteredRemaining) { StructuredText str = getExampleText(indexObject); if (str.getText().isEmpty()) { str = StructuredText.of(""); From f9e166f54c94f673eb20c87a7cbe406b14707863 Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 26 Apr 2026 19:30:45 +0200 Subject: [PATCH 2/3] search bar plead2 --- .../gui/editors/GuiOptionEditorDraggableList.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java index c9ba80a06..6ddb09e50 100644 --- a/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java +++ b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java @@ -333,12 +333,14 @@ private void reorderElements(int width, int mouseX, int mouseY) { GuiComponent makeDropDownOverlay() { return new GuiComponent() { + boolean hasRequestedFocus = false; List remaining = new ArrayList<>(); List filteredRemaining = new ArrayList<>(); String searchText = ""; { recalculateRemaining(); + requestFocus(); } void recalculateRemaining() { @@ -365,6 +367,7 @@ public boolean keyboardEvent(@NotNull KeyboardEvent event, @NotNull GuiImmediate var typed = (KeyboardEvent.CharTyped) event; searchText = searchText + typed.getChar(); recalculateRemaining(); + return true; } else if (event instanceof KeyboardEvent.KeyPressed) { var pressed = (KeyboardEvent.KeyPressed) event; if (pressed.getKeycode() == 259 && pressed.getPressed()) { @@ -372,6 +375,7 @@ public boolean keyboardEvent(@NotNull KeyboardEvent event, @NotNull GuiImmediate if (!searchText.isEmpty()) { searchText = searchText.substring(0, searchText.length() - 1); recalculateRemaining(); + return true; } } } @@ -383,7 +387,7 @@ public boolean mouseEvent(@NotNull MouseEvent mouseEvent, @NotNull GuiImmediateC if (mouseEvent instanceof MouseEvent.Click) { var click = (MouseEvent.Click) mouseEvent; if (click.getMouseState() && context.isHovered()) { - int dropdownY = -1; + int dropdownY = 11; for (Object indexObject : filteredRemaining) { if (context.translated(0, dropdownY + 3, context.getWidth(), 10).isHovered()) { activeText.add(indexObject); @@ -401,7 +405,11 @@ public boolean mouseEvent(@NotNull MouseEvent mouseEvent, @NotNull GuiImmediateC @Override public void render(@NotNull GuiImmediateContext context) { - if (filteredRemaining.isEmpty()) { + if (!hasRequestedFocus) { + hasRequestedFocus = true; + requestFocus(); + } + if (filteredRemaining.isEmpty() && searchText.isEmpty()) { closeOverlay(); return; } @@ -424,10 +432,11 @@ public void render(@NotNull GuiImmediateContext context) { outline ); //Bottom renderContext.drawColoredRect(1, 1, dropdownWidth - 1, dropdownHeight - 1, main); //Middle + renderContext.drawColoredRect(1, 13, dropdownWidth - 1, 14, 0xffd0d0d0); context.getRenderContext().drawStringScaledMaxWidth( StructuredText.of(searchText), fr, 3, 3, false, - dropdownWidth - 16, 0xffa0a0a0 + dropdownWidth - 16, 0xffd0d0d0 ); int dropdownY = 11; for (Object indexObject : filteredRemaining) { From 28abbbf48f30eaa1e2e31becd86b2b75be3f75ff Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 26 Apr 2026 19:42:49 +0200 Subject: [PATCH 3/3] search bar plead3 --- .../gui/editors/GuiOptionEditorDraggableList.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java index 6ddb09e50..d6278d8a7 100644 --- a/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java +++ b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorDraggableList.java @@ -387,7 +387,7 @@ public boolean mouseEvent(@NotNull MouseEvent mouseEvent, @NotNull GuiImmediateC if (mouseEvent instanceof MouseEvent.Click) { var click = (MouseEvent.Click) mouseEvent; if (click.getMouseState() && context.isHovered()) { - int dropdownY = 11; + int dropdownY = 13; for (Object indexObject : filteredRemaining) { if (context.translated(0, dropdownY + 3, context.getWidth(), 10).isHovered()) { activeText.add(indexObject); @@ -438,7 +438,11 @@ public void render(@NotNull GuiImmediateContext context) { StructuredText.of(searchText), fr, 3, 3, false, dropdownWidth - 16, 0xffd0d0d0 ); - int dropdownY = 11; + if (System.currentTimeMillis() % 1000 > 500) { + int cursorX = 3 + fr.getStringWidth(searchText); + renderContext.drawColoredRect(cursorX, 3, cursorX + 1, 11, 0xffffffff); + } + int dropdownY = 13; for (Object indexObject : filteredRemaining) { StructuredText str = getExampleText(indexObject); if (str.getText().isEmpty()) {