Skip to content

Instantly share code, notes, and snippets.

@Ensamisten
Created November 4, 2024 09:28
Show Gist options
  • Select an option

  • Save Ensamisten/50b638e954b47a6cbfb336f3024fb434 to your computer and use it in GitHub Desktop.

Select an option

Save Ensamisten/50b638e954b47a6cbfb336f3024fb434 to your computer and use it in GitHub Desktop.
package io.github.ensamisten.mixin.client;
import io.github.ensamisten.command.custom.CommandManager;
import io.github.ensamisten.gui.DeveloperScreen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.ArrayList;
import java.util.List;
@Mixin(DeveloperScreen.class)
public class DeveloperScreenMixin {
@Shadow
protected TextFieldWidget chatField;
private List<String> currentSuggestions = new ArrayList<>();
private int selectedSuggestionIndex = 0;
private int boxX = 4; // Position of the suggestion box
private int boxY;
private int boxWidth = 150;
private int lineHeight;
@Inject(method = "keyPressed", at = @At("HEAD"), cancellable = true)
public void onKeyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable<Boolean> info) {
if (!currentSuggestions.isEmpty()) {
if (keyCode == GLFW.GLFW_KEY_TAB) {
applySuggestion();
info.setReturnValue(true);
} else if (keyCode == GLFW.GLFW_KEY_UP) {
selectedSuggestionIndex = (selectedSuggestionIndex - 1 + currentSuggestions.size()) % currentSuggestions.size();
info.setReturnValue(true);
} else if (keyCode == GLFW.GLFW_KEY_DOWN) {
selectedSuggestionIndex = (selectedSuggestionIndex + 1) % currentSuggestions.size();
info.setReturnValue(true);
}
} else if (keyCode == GLFW.GLFW_KEY_TAB) {
String currentText = this.chatField.getText();
updateCurrentSuggestions(currentText);
info.setReturnValue(true);
}
}
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/TextFieldWidget;render(Lnet/minecraft/client/gui/DrawContext;IIF)V", shift = At.Shift.AFTER))
private void renderDeveloperSuggestions(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (!currentSuggestions.isEmpty()) {
drawSuggestionBox(context, currentSuggestions);
}
}
@Inject(method = "mouseClicked", at = @At("HEAD"), cancellable = true)
public void onMouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> ci) {
if (!currentSuggestions.isEmpty()) {
lineHeight = MinecraftClient.getInstance().textRenderer.fontHeight + 4;
boxY = MinecraftClient.getInstance().getWindow().getScaledHeight() - 30 - lineHeight * currentSuggestions.size();
for (int i = 0; i < currentSuggestions.size(); i++) {
int suggestionY = boxY + i * lineHeight;
// Check if the mouse is within the bounds of this suggestion
if (mouseX >= boxX && mouseX <= boxX + boxWidth &&
mouseY >= suggestionY && mouseY <= suggestionY + lineHeight) {
// Set the clicked suggestion as the selected text
applySuggestion(i);
ci.setReturnValue(true); // Cancel further processing of the click
return;
}
}
}
}
private void drawSuggestionBox(DrawContext context, List<String> suggestions) {
MinecraftClient client = MinecraftClient.getInstance();
lineHeight = client.textRenderer.fontHeight + 4;
boxY = client.getWindow().getScaledHeight() - 30 - lineHeight * suggestions.size();
context.getMatrices().push();
context.getMatrices().translate(0.0F, 0.0F, 200.0F); // Render in front
// Draw background box and borders
context.fill(boxX, boxY, boxX + boxWidth, boxY + lineHeight * suggestions.size(), 0x80000000);
context.fill(boxX, boxY, boxX + boxWidth, boxY + 1, 0xFF000000);
context.fill(boxX, boxY, boxX + 1, boxY + lineHeight * suggestions.size(), 0xFF000000);
context.fill(boxX + boxWidth - 1, boxY, boxX + boxWidth, boxY + lineHeight * suggestions.size(), 0xFF000000);
context.fill(boxX, boxY + lineHeight * suggestions.size() - 1, boxX + boxWidth, boxY + lineHeight * suggestions.size(), 0xFF000000);
// Draw each suggestion with highlighting
for (int i = 0; i < suggestions.size(); i++) {
int suggestionY = boxY + i * lineHeight;
int textColor = (i == selectedSuggestionIndex) ? 0xFFFFA500 : 0xFFFFFF;
if (i == selectedSuggestionIndex) {
context.fill(boxX + 1, suggestionY, boxX + boxWidth - 1, suggestionY + lineHeight, 0x40FFFFFF);
}
context.drawTextWithShadow(client.textRenderer, Text.of(suggestions.get(i)), boxX + 4, suggestionY + 2, textColor);
}
context.getMatrices().pop();
}
private void updateCurrentSuggestions(String input) {
currentSuggestions.clear();
CommandManager.getInstance().getAllCommands().forEach((name, node) -> {
if (name.startsWith(input)) {
currentSuggestions.add(name);
}
});
selectedSuggestionIndex = 0; // Reset index when updating suggestions
}
private void applySuggestion() {
if (!currentSuggestions.isEmpty() && selectedSuggestionIndex < currentSuggestions.size()) {
String selectedSuggestion = currentSuggestions.get(selectedSuggestionIndex);
chatField.setText(selectedSuggestion);
chatField.setCursor(selectedSuggestion.length(), false);
currentSuggestions.clear();
}
}
private void applySuggestion(int index) {
if (index >= 0 && index < currentSuggestions.size()) {
String selectedSuggestion = currentSuggestions.get(index);
chatField.setText(selectedSuggestion);
chatField.setCursor(selectedSuggestion.length(), false);
currentSuggestions.clear();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment