nageyqma·git
HTTPS https://git.nageyqma.icu/nageyqma/blade-addons-next.git SSH git@git.nageyqma.icu:nageyqma/blade-addons-next.git

HTTPS 链接可直接 git clone;推送代码请使用 SSH。

5.6 KB · 154 行raw
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
package blade.addon.features.other;

import blade.addon.utils.MathParser;
import blade.addon.utils.config.values.ExtraOptions;
import blade.addon.utils.data.ItemUtil;
import blade.addon.utils.rendering.DrawEvents;
import blade.addon.utils.rendering.RenderUtils;
import com.mojang.blaze3d.platform.InputConstants;
import com.mojang.blaze3d.platform.Window;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.input.CharacterEvent;
import net.minecraft.client.input.KeyEvent;
import net.minecraft.client.input.MouseButtonEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class SearchBar {

    private static final int SEARCH_Y = 20;
    private static final int SEARCH_WIDTH = 150;
    private static final int SEARCH_HEIGHT = 20;

    private static EditBox searchBar;
    private static boolean shouldDisplay = false;

    private static double parsedValue = Double.NaN;
    private static String writtenString = "";
    private static CopyOnWriteArrayList<String> searchTerms = new CopyOnWriteArrayList<>();

    private static final ConcurrentHashMap<ItemStack, Boolean> parsedData = new ConcurrentHashMap<>();

    public static void init() {
        DrawEvents.INVENTORY_SLOT_AFTER.register((context, item, x, y) -> {
            if (shouldDisplay() && !writtenString.isEmpty() && ExtraOptions.toggleableSearchBar && Double.isNaN(parsedValue)) {
                if (!matches(item)) {
                    context.fill(x, y, x + 16, y + 16, ExtraOptions.searchbarMissColor);
                }

            }
        });
    }

    private static boolean matches(ItemStack item) {
        if (parsedData.containsKey(item)) return parsedData.get(item);

        String name = item.getHoverName().getString().toLowerCase();
        if (name.equals("air")) return false;

        for (String term : searchTerms) {
            if (name.contains(term) || ItemUtil.containsIgnoreCaseLore(item, term)) {
                return true;
            }
        }

        return false;
    }

    public static void render(GuiGraphicsExtractor context, int mouseX, int mouseY, float deltaTicks) {
        if (!exists() || !shouldDisplay() || !ExtraOptions.toggleableSearchBar) return;
        searchBar.extractRenderState(context, mouseX, mouseY, deltaTicks);

        if (!Double.isNaN(parsedValue)) {
            String expression = "  §e= §2" + (ExtraOptions.formatMathResult ? RenderUtils.formatNumber((float) parsedValue) : (long) parsedValue);
            Font textRenderer = Minecraft.getInstance().font;
            if (textRenderer == null) return;

            int textX = searchBar.getX() + textRenderer.width(writtenString) + 4;
            int textY = searchBar.getY() + (searchBar.getHeight() - 8) / 2;
            context.text(textRenderer, expression, textX, textY, 0xffffffff, true);
        }
    }

    public static boolean keyPressed(KeyEvent input) {
        if (!exists() || !ExtraOptions.toggleableSearchBar) return false;

        boolean ctrlIsPressed = (input.modifiers() & InputConstants.MOD_CONTROL) != 0;

        if (ctrlIsPressed && input.key() == InputConstants.KEY_F) {
            shouldDisplay = !shouldDisplay;
            return true;
        } else if (shouldDisplay() && searchBar.isFocused()) {
            if (input.key() == InputConstants.KEY_RETURN) {
                if (!Double.isNaN(parsedValue)) {
                    searchBar.setValue(RenderUtils.formatNumber((float) parsedValue));
                }
            } else if (input.key() != InputConstants.KEY_ESCAPE) {
                searchBar.keyPressed(input);
                return true;
            }
        }
        return false;
    }

    public static void CharTyped(CharacterEvent input) {
        if (!exists() || !searchBar.isFocused() || !shouldDisplay() || !ExtraOptions.toggleableSearchBar) return;
        searchBar.charTyped(input);
    }

    public static void onMouseClick(MouseButtonEvent click) {
        if (!exists() || !shouldDisplay() || !ExtraOptions.toggleableSearchBar) return;
        searchBar.setFocused(inBounds(click.x(), click.y()));
    }


    public static boolean shouldDisplay() {
        return shouldDisplay;
    }

    private static boolean exists() {
        if (searchBar != null) return true;

        Minecraft mc = Minecraft.getInstance();
        Font textRenderer = mc.font;
        Window window = mc.getWindow();

        if (window == null || textRenderer == null) return false;

        searchBar = new EditBox(textRenderer, (window.getGuiScaledWidth() - SEARCH_WIDTH) / 2, SEARCH_Y, SEARCH_WIDTH, SEARCH_HEIGHT, Component.literal(""));
        searchBar.setMaxLength(100);
        searchBar.setResponder(string -> {


            writtenString = string.toLowerCase();
            parsedValue = MathParser.parseExpression(writtenString);
            if (Double.isNaN(parsedValue)) {
                parsedData.clear();
            }

            String[] terms = writtenString.split(",");
            searchTerms.clear();
            for (String term: terms) {
                searchTerms.add(term.strip());
            }
        });
        return true;
    }

    private static boolean inBounds(double x, double y) {
        int sx = searchBar.getX();
        int sy = searchBar.getY();
        int sw = searchBar.getWidth();
        int sh = searchBar.getHeight();

        return x >= sx && x <= sx + sw && y >= sy && y <= sy + sh;
    }

}