aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de
diff options
context:
space:
mode:
authorviciscat <51047087+viciscat@users.noreply.github.com>2024-11-26 04:49:02 +0100
committerGitHub <noreply@github.com>2024-11-25 22:49:02 -0500
commit8798d5f0643fd40715d82e0ec5bd9c9efbc83ec0 (patch)
treea807d85c7544fd767e5624739d128a6c0fe014a1 /src/main/java/de
parentbeeb590496dd92a4f6839da9a25c49562b9cb32e (diff)
downloadSkyblocker-8798d5f0643fd40715d82e0ec5bd9c9efbc83ec0.tar.gz
Skyblocker-8798d5f0643fd40715d82e0ec5bd9c9efbc83ec0.tar.bz2
Skyblocker-8798d5f0643fd40715d82e0ec5bd9c9efbc83ec0.zip
CTRL + F to search inventory (#933)
* CTRL + F to search inventory * remake the whole thing pretty much * comments yipee * aaron * extra translation trying array map
Diffstat (limited to 'src/main/java/de')
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java28
-rw-r--r--src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java33
-rw-r--r--src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java8
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/InventorySearch.java140
4 files changed, 208 insertions, 1 deletions
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java
index fa9bf376..4e890316 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java
@@ -119,6 +119,34 @@ public class UIAndVisualsCategory {
.build())
.build())
+ // Inventory Search
+ .group(OptionGroup.createBuilder()
+ .name(Text.translatable("skyblocker.config.uiAndVisuals.inventorySearch"))
+ .collapsed(true)
+ .option(Option.<UIAndVisualsConfig.InventorySearchConfig.EnableState>createBuilder()
+ .name(Text.translatable("skyblocker.config.uiAndVisuals.inventorySearch.enabled"))
+ .binding(defaults.uiAndVisuals.inventorySearch.enabled,
+ () -> config.uiAndVisuals.inventorySearch.enabled,
+ newValue -> config.uiAndVisuals.inventorySearch.enabled = newValue)
+ .controller(ConfigUtils::createEnumCyclingListController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(MinecraftClient.IS_SYSTEM_MAC ? Text.translatable("skyblocker.config.uiAndVisuals.inventorySearch.cmdK") : Text.translatable("skyblocker.config.uiAndVisuals.inventorySearch.ctrlK"))
+ .binding(defaults.uiAndVisuals.inventorySearch.ctrlK,
+ () -> config.uiAndVisuals.inventorySearch.ctrlK,
+ newValue -> config.uiAndVisuals.inventorySearch.ctrlK = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("skyblocker.config.uiAndVisuals.inventorySearch.showClickableText"))
+ .description(OptionDescription.of(Text.translatable("skyblocker.config.uiAndVisuals.inventorySearch.showClickableText.@Tooltip")))
+ .binding(defaults.uiAndVisuals.inventorySearch.clickableText,
+ () -> config.uiAndVisuals.inventorySearch.clickableText,
+ newValue -> config.uiAndVisuals.inventorySearch.clickableText = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .build())
+
//Title Container
.group(OptionGroup.createBuilder()
.name(Text.translatable("skyblocker.config.uiAndVisuals.titleContainer"))
diff --git a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java
index 598cbf54..755fb46e 100644
--- a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java
@@ -38,6 +38,9 @@ public class UIAndVisualsConfig {
public ItemCooldown itemCooldown = new ItemCooldown();
@SerialEntry
+ public InventorySearchConfig inventorySearch = new InventorySearchConfig();
+
+ @SerialEntry
public TitleContainer titleContainer = new TitleContainer();
@SerialEntry
@@ -83,6 +86,36 @@ public class UIAndVisualsConfig {
public boolean enableItemCooldowns = true;
}
+ public static class InventorySearchConfig {
+ @SerialEntry
+ public EnableState enabled = EnableState.SKYBLOCK;
+
+ @SerialEntry
+ public boolean ctrlK = false;
+
+ @SerialEntry
+ public boolean clickableText = false;
+
+ public enum EnableState {
+ OFF,
+ SKYBLOCK,
+ EVERYWHERE;
+
+ @Override
+ public String toString() {
+ return I18n.translate("skyblocker.config.uiAndVisuals.inventorySearch.state." + this.name());
+ }
+
+ public boolean isEnabled() {
+ return switch (this) {
+ case OFF -> false;
+ case SKYBLOCK -> de.hysky.skyblocker.utils.Utils.isOnSkyblock();
+ case EVERYWHERE -> true;
+ };
+ }
+ }
+ }
+
public static class TitleContainer {
@SerialEntry
public float titleContainerScale = 100;
diff --git a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java
index 579c8773..fc9381b9 100644
--- a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java
@@ -6,6 +6,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.skyblock.InventorySearch;
import de.hysky.skyblocker.skyblock.PetCache;
import de.hysky.skyblocker.skyblock.experiment.ExperimentSolver;
import de.hysky.skyblocker.skyblock.experiment.SuperpairsSolver;
@@ -311,7 +312,7 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen
}
@Inject(method = "drawSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawItem(Lnet/minecraft/item/ItemStack;III)V"))
- private void skyblocker$drawItemRarityBackground(DrawContext context, Slot slot, CallbackInfo ci) {
+ private void skyblocker$drawOnItem(DrawContext context, Slot slot, CallbackInfo ci) {
if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.itemInfoDisplay.itemRarityBackgrounds)
ItemRarityBackgrounds.tryDraw(slot.getStack(), context, slot.x, slot.y);
// Item protection
@@ -320,6 +321,11 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen
context.drawTexture(RenderLayer::getGuiTextured, ITEM_PROTECTION, slot.x, slot.y, 0, 0, 16, 16, 16, 16);
RenderSystem.disableBlend();
}
+ // Search
+ // Darken the slots
+ if (InventorySearch.isSearching() && !InventorySearch.slotMatches(slot)) {
+ context.fill(slot.x, slot.y, slot.x + 16, slot.y + 16, 100, 0x88_000000);
+ }
}
@Inject(method = "drawSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawStackOverlay(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V"))
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/InventorySearch.java b/src/main/java/de/hysky/skyblocker/skyblock/InventorySearch.java
new file mode 100644
index 00000000..6ca1f236
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/InventorySearch.java
@@ -0,0 +1,140 @@
+package de.hysky.skyblocker.skyblock;
+
+import de.hysky.skyblocker.annotations.Init;
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.config.configs.UIAndVisualsConfig;
+import de.hysky.skyblocker.utils.ItemUtils;
+import it.unimi.dsi.fastutil.ints.Int2BooleanArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2BooleanMap;
+import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
+import net.fabricmc.fabric.api.client.screen.v1.ScreenKeyboardEvents;
+import net.fabricmc.fabric.api.client.screen.v1.Screens;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
+import net.minecraft.client.gui.widget.TextFieldWidget;
+import net.minecraft.client.gui.widget.TextWidget;
+import net.minecraft.screen.slot.Slot;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+import org.jetbrains.annotations.NotNull;
+import org.lwjgl.glfw.GLFW;
+
+public class InventorySearch {
+ private static HandledScreen<?> openedHandledScreen = null;
+ private static final Int2BooleanMap slotToMatch = new Int2BooleanArrayMap(64);
+ private static String search = "";
+
+ @Init
+ public static void init() {
+ ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
+ UIAndVisualsConfig.InventorySearchConfig inventorySearchConfig = SkyblockerConfigManager.get().uiAndVisuals.inventorySearch;
+ if (!inventorySearchConfig.enabled.isEnabled() || !(screen instanceof HandledScreen<?> handledScreen)) return;
+
+ if (inventorySearchConfig.clickableText) Screens.getButtons(handledScreen).add(new SearchTextWidget(handledScreen));
+
+ ScreenKeyboardEvents.allowKeyPress(handledScreen).register((screen1, key, scancode, modifiers) -> {
+ if (key == (inventorySearchConfig.ctrlK ? GLFW.GLFW_KEY_K : GLFW.GLFW_KEY_F) && (modifiers & (GLFW.GLFW_MOD_CONTROL | GLFW.GLFW_MOD_SUPER)) != 0) {
+ InventorySearch.showSearchBar(handledScreen);
+ return false;
+ }
+ return true;
+ });
+ });
+ }
+
+ public static void showSearchBar(HandledScreen<?> handledScreen) {
+ if (handledScreen == openedHandledScreen) return;
+ openedHandledScreen = handledScreen;
+ TextFieldWidget textFieldWidget = getTextFieldWidget(handledScreen);
+ Screens.getButtons(handledScreen).add(new TextWidget(0, 5, handledScreen.width, 10, Text.literal("Search Inventory"), Screens.getTextRenderer(handledScreen)));
+ Screens.getButtons(handledScreen).addFirst(textFieldWidget);
+ Screens.getButtons(handledScreen).removeIf(button -> button instanceof SearchTextWidget); // remove search text
+ handledScreen.setFocused(textFieldWidget);
+
+ ScreenEvents.remove(handledScreen).register(InventorySearch::onScreenClosed);
+ }
+
+ private static @NotNull TextFieldWidget getTextFieldWidget(HandledScreen<?> handledScreen) {
+ // Slightly modified text field widget
+ TextFieldWidget textFieldWidget = new TextFieldWidget(Screens.getTextRenderer(handledScreen), 120, 20, Text.literal("Search Inventory")) {
+ @Override
+ public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ // Makes the widget catch all key presses (except escape) to fix closing the inventory when pressing E
+ // also check that the widget is focused and active
+ return super.keyPressed(keyCode, scanCode, modifiers) || (keyCode != GLFW.GLFW_KEY_ESCAPE && this.isNarratable() && this.isFocused());
+ }
+
+ // Unfocus when clicking outside
+ @Override
+ public boolean mouseClicked(double mouseX, double mouseY, int button) {
+ if (isFocused() && !clicked(mouseX, mouseY)) {
+ setFocused(false);
+ return false;
+ }
+ return super.mouseClicked(mouseX, mouseY, button);
+ }
+ };
+ textFieldWidget.setPosition((handledScreen.width - textFieldWidget.getWidth()) / 2, 15);
+ textFieldWidget.setPlaceholder(Text.translatable("gui.socialInteractions.search_hint"));
+ textFieldWidget.setText(search); // Restore previous search
+ textFieldWidget.setChangedListener(InventorySearch::onSearchTyped);
+ return textFieldWidget;
+ }
+
+ public static boolean isSearching() {
+ return openedHandledScreen != null;
+ }
+
+ public static boolean slotMatches(Slot slot) {
+ return slotToMatch.computeIfAbsent(slot.id, i -> slot.hasStack() &&
+ (slot.getStack().getName().getString().toLowerCase().contains(search) || ItemUtils.getLoreLineIf(slot.getStack(), s -> s.toLowerCase().contains(search)) != null));
+ }
+
+ private static void onSearchTyped(String text) {
+ slotToMatch.clear();
+ search = text.toLowerCase();
+ }
+
+ private static void onScreenClosed(Screen screen) {
+ openedHandledScreen = null;
+ slotToMatch.clear();
+
+ }
+
+ /**
+ * Button to open the search bar, for accessibility reasons (pojav and general preferences)
+ */
+ private static class SearchTextWidget extends TextWidget {
+
+ private final Text underlinedText;
+ private final Text normalText;
+ private final HandledScreen<?> screen;
+ private boolean hoveredState = false;
+
+ public SearchTextWidget(HandledScreen<?> handledScreen) {
+ super(Text.translatable("skyblocker.inventorySearch.clickHereToSearch"), Screens.getTextRenderer(handledScreen));
+ setPosition((handledScreen.width - this.getWidth()) / 2, 15);
+ underlinedText = getMessage().copy().formatted(Formatting.UNDERLINE);
+ normalText = getMessage().copy().formatted(Formatting.GRAY);
+ screen = handledScreen;
+ setMessage(normalText);
+ }
+
+ @Override
+ public void onClick(double mouseX, double mouseY) {
+ InventorySearch.showSearchBar(screen);
+ }
+
+ @Override
+ public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
+ if (isHovered() != hoveredState) {
+ hoveredState = active = isHovered();
+ if (hoveredState) setMessage(underlinedText);
+ else setMessage(normalText);
+ }
+
+ super.renderWidget(context, mouseX, mouseY, delta);
+ }
+ }
+}