diff options
| author | vicisacat <victor.branchu@gmail.com> | 2024-04-14 17:36:21 +0200 |
|---|---|---|
| committer | vicisacat <victor.branchu@gmail.com> | 2024-04-20 16:09:49 +0200 |
| commit | b791e38cbd36360935164e337fa992bf514cbb36 (patch) | |
| tree | f245ad744288d6f62452c26161878d59f651971d /src/main | |
| parent | 3581365e654306cf08d0c4284ddfa454befd519d (diff) | |
| download | Skyblocker-b791e38cbd36360935164e337fa992bf514cbb36.tar.gz Skyblocker-b791e38cbd36360935164e337fa992bf514cbb36.tar.bz2 Skyblocker-b791e38cbd36360935164e337fa992bf514cbb36.zip | |
it works so cool
Diffstat (limited to 'src/main')
11 files changed, 1008 insertions, 113 deletions
diff --git a/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java b/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java new file mode 100644 index 00000000..92ca967d --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java @@ -0,0 +1,16 @@ +package de.hysky.skyblocker.mixin; + +import de.hysky.skyblocker.skyblock.FancyStatusBars; +import net.minecraft.client.util.Window; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Window.class) +public class WindowMixin { + @Inject(method = "setScaleFactor", at = @At("TAIL")) + public void onScaleFactorChange(double scaleFactor, CallbackInfo ci) { + FancyStatusBars.updatePositions(); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java index 1a582863..6bf012ff 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java @@ -1,5 +1,6 @@ package de.hysky.skyblocker.skyblock; +import com.google.gson.JsonObject; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.fancybars.BarGrid; @@ -8,25 +9,37 @@ import de.hysky.skyblocker.skyblock.fancybars.StatusBarsConfigScreen; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.render.RenderHelper; import de.hysky.skyblocker.utils.scheduler.Scheduler; -import jdk.jshell.EvalException; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; +import org.lwjgl.glfw.GLFW; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.awt.*; -import java.util.Collection; -import java.util.HashMap; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.util.*; import java.util.List; -import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; public class FancyStatusBars { private static final Identifier BARS = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/bars.png"); + private static final Path FILE = SkyblockerMod.CONFIG_DIR.resolve("status_bars.json"); + private static final Logger LOGGER = LoggerFactory.getLogger(FancyStatusBars.class); private final MinecraftClient client = MinecraftClient.getInstance(); private final StatusBarTracker statusBarTracker = SkyblockerMod.getInstance().statusBarTracker; @@ -48,26 +61,138 @@ public class FancyStatusBars { public static Map<String, StatusBar> statusBars = new HashMap<>(); public static void init() { - statusBars.put("health", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/health"), new Color[]{new Color(255, 0, 0), new Color(255, 220, 0)}, true, null, "health")); - statusBars.put("intelligence", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/intelligence"), new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}, true, null, "intelligence")); - statusBars.put("defense", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/defense"), new Color[]{new Color(255, 255, 255)}, false, null, "defense")); - statusBars.put("experience", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/experience"), new Color[]{new Color(100, 220, 70)}, false, null, "experience")); - - - barGrid.addRow(1, false); + statusBars.put("health", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/health"), + new Color[]{new Color(255, 0, 0), new Color(255, 220, 0)}, + true, new Color(255, 85, 85), Text.translatable("skyblocker.bars.config.health"))); + statusBars.put("intelligence", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/intelligence"), + new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}, + true, new Color(85, 255, 255), Text.translatable("skyblocker.bars.config.intelligence"))); + statusBars.put("defense", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/defense"), + new Color[]{new Color(255, 255, 255)}, + false, new Color(185, 185, 185), Text.translatable("skyblocker.bars.config.defense"))); + statusBars.put("experience", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/experience"), + new Color[]{new Color(100, 230, 70)}, + false, new Color(128, 255, 32), Text.translatable("skyblocker.bars.config.experience"))); + + // Default positions + StatusBar health = statusBars.get("health"); + health.gridX = 1; + health.gridY = 1; + StatusBar intelligence = statusBars.get("intelligence"); + intelligence.gridX = 2; + intelligence.gridY = 1; + StatusBar defense = statusBars.get("defense"); + defense.gridX = 1; + defense.gridY = -1; + StatusBar experience = statusBars.get("experience"); + experience.gridX = 1; + experience.gridY = 2; + + CompletableFuture.supplyAsync(FancyStatusBars::loadBarConfig).thenAccept(object -> { + if (object != null) { + for (String s : object.keySet()) { + if (statusBars.containsKey(s)) { + try { + statusBars.get(s).loadFromJson(object.get(s).getAsJsonObject()); + } catch (Exception e) { + LOGGER.error("[Skyblocker] Failed to load {} status bar", s, e); + } + } else { + LOGGER.warn("[Skyblocker] Unknown status bar: {}", s); + } + } + } + placeBarsInGrid(); + configLoaded = true; + }); + ClientLifecycleEvents.CLIENT_STOPPING.register((client) -> { + saveBarConfig(); + GLFW.glfwDestroyCursor(StatusBarsConfigScreen.RESIZE_CURSOR); + }); + /*barGrid.addRow(1, false); barGrid.add(1, 1, statusBars.get("health")); barGrid.add(2, 1, statusBars.get("intelligence")); barGrid.addRow(2, false); barGrid.add(1, 2, statusBars.get("experience")); barGrid.addRow(-1, true); - barGrid.add(1, -1, statusBars.get("defense")); + barGrid.add(1, -1, statusBars.get("defense"));*/ + //placeBarsInGrid(); ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register( ClientCommandManager.literal("skyblocker") .then(ClientCommandManager.literal("bar_test").executes(Scheduler.queueOpenScreenCommand(StatusBarsConfigScreen::new))))); } + private static boolean configLoaded = false; + + private static void placeBarsInGrid() { + List<StatusBar> original = statusBars.values().stream().toList(); + + // TOP + List<StatusBar> barList = new ArrayList<>(original.stream().filter(statusBar -> statusBar.gridY > 0).toList()); + barList.sort((a, b) -> a.gridY == b.gridY ? Integer.compare(a.gridX, b.gridX) : Integer.compare(a.gridY, b.gridY)); + + int y = 0; + int rowNum = 0; + for (StatusBar statusBar : barList) { + if (statusBar.gridY > y) { + barGrid.addRowToEnd(true, false); + rowNum++; + y = statusBar.gridY; + } + barGrid.addToEndOfRow(rowNum, false, statusBar); + } + + // BOTTOM LEFT + barList.clear(); + barList.addAll(original.stream().filter(statusBar -> statusBar.gridY < 0 && statusBar.gridX < 0).toList()); + barList.sort((a, b) -> a.gridY == b.gridY ? -Integer.compare(a.gridX, b.gridX) : -Integer.compare(a.gridY, b.gridY)); + doBottom(false, barList); + + // BOTTOM RIGHT + barList.clear(); + barList.addAll(original.stream().filter(statusBar -> statusBar.gridY < 0 && statusBar.gridX > 0).toList()); + barList.sort((a, b) -> a.gridY == b.gridY ? Integer.compare(a.gridX, b.gridX) : -Integer.compare(a.gridY, b.gridY)); + doBottom(true, barList); + } + + private static void doBottom(boolean right, List<StatusBar> barList) { + int y = 0; + int rowNum = 0; + for (StatusBar statusBar : barList) { + if (statusBar.gridY < y) { + barGrid.addRowToEnd(false, right); + rowNum--; + y = statusBar.gridY; + } + barGrid.addToEndOfRow(rowNum, right, statusBar); + } + } + + public static JsonObject loadBarConfig() { + try (BufferedReader reader = Files.newBufferedReader(FILE)) { + return SkyblockerMod.GSON.fromJson(reader, JsonObject.class); + } catch (NoSuchFileException e) { + LOGGER.warn("[Skyblocker] No status bar config file found, using defaults"); + } catch (Exception e) { + LOGGER.error("[Skyblocker] Failed to load status bars config", e); + } + return null; + } + + public static void saveBarConfig() { + JsonObject output = new JsonObject(); + statusBars.forEach((s, statusBar) -> output.add(s, statusBar.toJson())); + try (BufferedWriter writer = Files.newBufferedWriter(FILE)) { + SkyblockerMod.GSON.toJson(output, writer); + LOGGER.info("[Skyblocker] Saved status bars config"); + } catch (IOException e) { + LOGGER.error("[Skyblocker] Failed to save status bars config", e); + } + } + public static void updatePositions() { + if (!configLoaded) return; final float hotbarSize = 182; final int width = MinecraftClient.getInstance().getWindow().getScaledWidth(); final int height = MinecraftClient.getInstance().getWindow().getScaledHeight(); @@ -83,6 +208,7 @@ public class FancyStatusBars { // THE TOP for (int i = 0; i < barGrid.getTopSize(); i++) { List<StatusBar> row = barGrid.getRow(i + 1, false); + System.out.println(row); if (row.isEmpty()) continue; int totalSize = 0; for (StatusBar bar : row) { @@ -90,10 +216,11 @@ public class FancyStatusBars { } // Fix sizing - whileLoop: while (totalSize != 12) { + whileLoop: + while (totalSize != 12) { if (totalSize > 12) { for (StatusBar bar : row) { - if (bar.size > 2) { // TODO: this can cause infinite looping if we add more than 6 bars + if (bar.size > bar.getMinimumSize()) { // TODO: this can cause infinite looping if we add more than 6 bars bar.size--; totalSize--; } @@ -101,7 +228,7 @@ public class FancyStatusBars { } } else { for (StatusBar bar : row) { - if (bar.size < 12) { + if (bar.size < bar.getMaximumSize()) { bar.size++; totalSize++; } @@ -110,52 +237,52 @@ public class FancyStatusBars { } } - int x = width/2 - 91; - int y = height - 33 - 10*i; + int x = width / 2 - 91; + int y = height - 33 - 10 * i; + int size = 0; for (int j = 0; j < row.size(); j++) { StatusBar bar = row.get(j); - bar.setX(x); + bar.setX(x + (int) ((size / 12.d) * hotbarSize)); bar.setY(y); - bar.setWidth((int) ((bar.size / 12.f)*hotbarSize)); - x += bar.getWidth(); - bar.gridY = i+1; - bar.gridX = j+1; + bar.setWidth((int) ((bar.size / 12.d) * hotbarSize)); + size += bar.size; + bar.gridY = i + 1; + bar.gridX = j + 1; } } - final int maxSize = 3; // BOTTOM LEFT for (int i = 0; i < barGrid.getBottomLeftSize(); i++) { List<StatusBar> row = barGrid.getRow(-(i + 1), false); if (row.isEmpty()) continue; - int x = width/2 - 91 - 2; - int y = height - 15-10*i; + int x = width / 2 - 91 - 2; + int y = height - 15 - 10 * (barGrid.getBottomLeftSize() - i - 1); for (int j = 0; j < row.size(); j++) { StatusBar bar = row.get(j); - bar.size = Math.min(bar.size, maxSize); + bar.size = MathHelper.clamp(bar.size, bar.getMinimumSize(), bar.getMaximumSize()); bar.setY(y); - bar.setWidth(bar.size*25); + bar.setWidth(bar.size * 25); x -= bar.getWidth(); bar.setX(x); - bar.gridX = -j-1; - bar.gridY = -i-1; + bar.gridX = -j - 1; + bar.gridY = -i - 1; } } // BOTTOM RIGHT for (int i = 0; i < barGrid.getBottomRightSize(); i++) { List<StatusBar> row = barGrid.getRow(-(i + 1), true); if (row.isEmpty()) continue; - int x = width/2 + 91 + 2; - int y = height - 15-10*i; + int x = width / 2 + 91 + 2; + int y = height - 15 - 10 * (barGrid.getBottomRightSize() - i - 1); for (int j = 0; j < row.size(); j++) { StatusBar bar = row.get(j); - bar.size = Math.min(bar.size, maxSize); + bar.size = MathHelper.clamp(bar.size, bar.getMinimumSize(), bar.getMaximumSize()); bar.setX(x); bar.setY(y); - bar.setWidth(bar.size*25); + bar.setWidth(bar.size * 25); x += bar.getWidth(); - bar.gridX = j+1; - bar.gridY = -i-1; + bar.gridX = j + 1; + bar.gridY = -i - 1; } } } @@ -186,7 +313,7 @@ public class FancyStatusBars { value.render(context, -1, -1, client.getLastFrameDuration()); } for (StatusBar statusBar : barCollection) { - statusBar.renderText(context); + if (statusBar.showText()) statusBar.renderText(context); } StatusBarTracker.Resource health = statusBarTracker.getHealth(); statusBars.get("health").updateValues(health.value() / (float) health.max(), health.overflow() / (float) health.max(), health.value()); @@ -236,7 +363,7 @@ public class FancyStatusBars { MatrixStack matrices = context.getMatrices(); matrices.push(); matrices.translate(50, 50, 0); - matrices.scale(2,2,1); + matrices.scale(2, 2, 1); context.drawSprite(0, 0, 0, 60, 5, SUPPLIER.get(), 1, 0.25f, 0.25f, 1); matrices.pop(); return true; @@ -314,13 +441,13 @@ public class FancyStatusBars { context.drawTexture(BARS, anchorsX[anchorNum] + offsetX, anchorsY[anchorNum], 0, v, 9, 9); // Draw the background for the bar - context.drawGuiTexture(BAR_BACK, anchorsX[anchorNum]+ offsetX+10, anchorsY[anchorNum]+1, bar_width, 7); + context.drawGuiTexture(BAR_BACK, anchorsX[anchorNum] + offsetX + 10, anchorsY[anchorNum] + 1, bar_width, 7); // Draw the filled part of the bar for (int i = 0; i < fill.length; i++) { int fill_width = this.fill[i] * (bar_width - 2) / 100; if (fill_width >= 1) { - RenderHelper.renderNineSliceColored(context, BAR_FILL, anchorsX[anchorNum] + offsetX + 11, anchorsY[anchorNum]+2, fill_width, 5, colors[i]); + RenderHelper.renderNineSliceColored(context, BAR_FILL, anchorsX[anchorNum] + offsetX + 11, anchorsY[anchorNum] + 2, fill_width, 5, colors[i]); } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java index 6b90b86c..9d460803 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java @@ -34,18 +34,7 @@ public class EditBidPopup extends AbstractPopupScreen { super.init(); layout = DirectionalLayoutWidget.vertical(); layout.spacing(8).getMainPositioner().alignHorizontalCenter(); - textFieldWidget = new TextFieldWidget(textRenderer, 120, 15, Text.empty()) { - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (!super.keyPressed(keyCode, scanCode, modifiers)) { - if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { - done(null); - return true; - } - } else return true; - return false; - } - }; + textFieldWidget = new EnterConfirmTextFieldWidget(textRenderer, 120, 15, Text.empty(), () -> done(null)); textFieldWidget.setTextPredicate(this::isStringGood); layout.add(new TextWidget(Text.literal("- Set Bid -").fillStyle(Style.EMPTY.withBold(true)), textRenderer)); layout.add(textFieldWidget); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java index 93219240..384250f9 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java @@ -53,6 +53,28 @@ public class BarGrid { } } + public void addRowToEnd(boolean top, boolean right) { + if (top) { + this.top.add(new LinkedList<>()); + } else { + (right ? bottomRight: bottomLeft).add(new LinkedList<>()); + } + } + + public void addToEndOfRow(int row, boolean right, StatusBar bar) { + if (row>0) { + LinkedList<StatusBar> statusBars = top.get(row - 1); + statusBars.add(bar); + bar.gridY = row; + bar.gridX = statusBars.indexOf(bar)+1; + } else if (row<0) { + LinkedList<StatusBar> statusBars = (right? bottomRight: bottomLeft).get(Math.abs(row)-1); + statusBars.add(bar); + bar.gridY = row; + bar.gridX = (statusBars.indexOf(bar)+1) * (right ? 1: -1); + } + } + public void remove(int x, int y) { System.out.println("Removing x: " + x + " y: " + y); if (y > 0) { @@ -92,6 +114,21 @@ public class BarGrid { } } + public boolean coordinatesExist(int x, int y) { + if (x == 0 || y == 0) return false; + if (y > 0) { + if (y > getTopSize()) return false; + return x <= getRow(y, false).size(); + } else { + if (Math.abs(y) > (x < 0 ? getBottomLeftSize(): getBottomRightSize())) return false; + return Math.abs(x) <= getRow(y, x > 0).size(); + } + } + + public StatusBar getBar(int x, int y) { + return getRow(y, x>0).get(Math.abs(x)-1); + } + public int getTopSize() {return top.size();} public int getBottomLeftSize() {return bottomLeft.size();} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarColorPopup.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarColorPopup.java new file mode 100644 index 00000000..a3ce4e43 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarColorPopup.java @@ -0,0 +1,117 @@ +package de.hysky.skyblocker.skyblock.fancybars; + +import de.hysky.skyblocker.utils.render.gui.AbstractPopupScreen; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.widget.*; +import net.minecraft.text.Style; +import net.minecraft.text.Text; + +import java.awt.*; +import java.util.List; +import java.util.function.Consumer; + +public class EditBarColorPopup extends AbstractPopupScreen { + + private final Consumer<Color> setColor; + + private DirectionalLayoutWidget layout = DirectionalLayoutWidget.vertical(); + private BasicColorSelector colorSelector; + + protected EditBarColorPopup(Text title, Screen backgroundScreen, Consumer<Color> setColor) { + super(title, backgroundScreen); + this.setColor = setColor; + } + + @Override + protected void init() { + super.init(); + layout = DirectionalLayoutWidget.vertical(); + layout.spacing(8).getMainPositioner().alignHorizontalCenter(); + layout.add(new TextWidget(title.copy().fillStyle(Style.EMPTY.withBold(true)), MinecraftClient.getInstance().textRenderer)); + colorSelector = new BasicColorSelector(0, 0, 150, () -> done(null)); + layout.add(colorSelector); + + DirectionalLayoutWidget horizontal = DirectionalLayoutWidget.horizontal(); + ButtonWidget buttonWidget = ButtonWidget.builder(Text.literal("Cancel"), button -> close()).width(80).build(); + horizontal.add(buttonWidget); + horizontal.add(ButtonWidget.builder(Text.literal("Done"), this::done).width(80).build()); + + layout.add(horizontal); + layout.forEachChild(this::addDrawableChild); + this.layout.refreshPositions(); + SimplePositioningWidget.setPos(layout, this.getNavigationFocus()); + } + + private void done(Object object) { + if (colorSelector.validColor) setColor.accept(new Color(colorSelector.getColor())); + close(); + } + + @Override + public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { + super.renderBackground(context, mouseX, mouseY, delta); + drawPopupBackground(context, layout.getX(), layout.getY(), layout.getWidth(), layout.getHeight()); + } + + private static class BasicColorSelector extends ContainerWidget { + + private final EnterConfirmTextFieldWidget textFieldWidget; + + public BasicColorSelector(int x, int y, int width, Runnable onEnter) { + super(x, y, width, 15, Text.literal("edit color")); + textFieldWidget = new EnterConfirmTextFieldWidget(MinecraftClient.getInstance().textRenderer, getX() + 16, getY(), width - 16, 15, Text.empty(), onEnter); + textFieldWidget.setChangedListener(this::onTextChange); + textFieldWidget.setTextPredicate(s -> s.length() <= 6); + } + + @Override + public List<? extends Element> children() { + return List.of(textFieldWidget); + } + + public int getColor() { + return color; + } + + private int color = 0xFF000000; + private boolean validColor = false; + + private void onTextChange(String text) { + try { + color = Integer.parseInt(text, 16) | 0xFF000000; + validColor = true; + } catch (NumberFormatException e) { + color = 0; + validColor = false; + } + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + context.drawBorder(getX(), getY(), 15, 15, validColor ? -1 : 0xFFDD0000); + context.fill(getX() + 1, getY() + 1, getX() + 14, getY() + 14, color); + textFieldWidget.renderWidget(context, mouseX, mouseY, delta); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + + } + + @Override + public void setX(int x) { + super.setX(x); + textFieldWidget.setX(getX()+16); + } + + @Override + public void setY(int y) { + super.setY(y); + textFieldWidget.setY(getY()); + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java new file mode 100644 index 00000000..54af7a03 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java @@ -0,0 +1,274 @@ +package de.hysky.skyblocker.skyblock.fancybars; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.tooltip.TooltipBackgroundRenderer; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.client.gui.widget.ContainerWidget; +import net.minecraft.client.gui.widget.TextWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Colors; +import net.minecraft.util.Formatting; + +import java.awt.*; +import java.util.List; +import java.util.function.Consumer; + +public class EditBarWidget extends ContainerWidget { + + private final EnumCyclingOption<StatusBar.IconPosition> iconOption; + private final BooleanOption booleanOption; + + private final ColorOption color1; + private final ColorOption color2; + private final ColorOption textColor; + private final TextWidget nameWidget; + + private int contentsWidth = 0; + + public EditBarWidget(int x, int y, Screen parent) { + super(x, y, 100, 66, Text.literal("Edit bar")); + + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + + nameWidget = new TextWidget(Text.empty(), textRenderer); + + MutableText translatable = Text.translatable("skyblocker.bars.config.icon"); + contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + textRenderer.getWidth("RIGHT") + 10); + iconOption = new EnumCyclingOption<>(0, 11, getWidth(), translatable, StatusBar.IconPosition.class); + + translatable = Text.translatable("skyblocker.bars.config.showValue"); + contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); + booleanOption = new BooleanOption(0, 22, getWidth(), translatable); + + // COLO(u)RS + translatable = Text.translatable("skyblocker.bars.config.mainColor"); + contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); + color1 = new ColorOption(0, 33, getWidth(), translatable, parent); + + translatable = Text.translatable("skyblocker.bars.config.overflowColor"); + contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); + color2 = new ColorOption(0, 44, getWidth(), translatable, parent); + + translatable = Text.translatable("skyblocker.bars.config.textColor"); + contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); + textColor = new ColorOption(0, 55, getWidth(), translatable, parent); + + setWidth(contentsWidth); + } + + @Override + public List<? extends Element> children() { + return List.of(iconOption, booleanOption, color1, color2, textColor); + } + + public int insideMouseX = 0; + public int insideMouseY = 0; + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + if (isHovered()) { + insideMouseX = mouseX; + insideMouseY = mouseY; + } else { + int i = mouseX - insideMouseX; + int j = mouseY - insideMouseY; + if (i * i + j * j > 30 * 30) visible = false; + } + TooltipBackgroundRenderer.render(context, getX(), getY(), getWidth(), getHeight(), 0); + MatrixStack matrices = context.getMatrices(); + matrices.push(); + matrices.translate(getX(), getY(), 0); + nameWidget.render(context, mouseX, mouseY, delta); + iconOption.renderWidget(context, mouseX - getX(), mouseY - getY(), delta); + booleanOption.renderWidget(context, mouseX - getX(), mouseY - getY(), delta); + color1.renderWidget(context, mouseX - getX(), mouseY - getY(), delta); + color2.renderWidget(context, mouseX - getX(), mouseY - getY(), delta); + textColor.renderWidget(context, mouseX - getX(), mouseY - getY(), delta); + matrices.pop(); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (!visible) return false; + if (!isHovered()) visible = false; + return super.mouseClicked(mouseX - getX(), mouseY - getY(), button); + } + + public void setStatusBar(StatusBar statusBar) { + iconOption.setCurrent(statusBar.getIconPosition()); + iconOption.setOnChange(statusBar::setIconPosition); + booleanOption.setCurrent(statusBar.showText()); + booleanOption.setOnChange(statusBar::setShowText); + + color1.setCurrent(statusBar.getColors()[0].getRGB()); + color1.setOnChange(color -> statusBar.getColors()[0] = color); + + color2.active = statusBar.hasOverflow(); + if (color2.active) { + color2.setCurrent(statusBar.getColors()[1].getRGB()); + color2.setOnChange(color -> statusBar.getColors()[1] = color); + } + + if (statusBar.getTextColor() != null) { + textColor.setCurrent(statusBar.getTextColor().getRGB()); + } + textColor.setOnChange(statusBar::setTextColor); + + MutableText formatted = statusBar.getName().copy().formatted(Formatting.BOLD); + nameWidget.setMessage(formatted); + setWidth(Math.max(MinecraftClient.getInstance().textRenderer.getWidth(formatted), contentsWidth)); + } + + @Override + public void setWidth(int width) { + super.setWidth(width); + iconOption.setWidth(width); + booleanOption.setWidth(width); + color1.setWidth(width); + color2.setWidth(width); + textColor.setWidth(width); + nameWidget.setWidth(width); + + } + + public static class EnumCyclingOption<T extends Enum<T>> extends ClickableWidget { + + private T current; + private final T[] values; + private Consumer<T> onChange = null; + + public EnumCyclingOption(int x, int y, int width, Text message, Class<T> enumClass) { + super(x, y, width, 11, message); + values = enumClass.getEnumConstants(); + current = values[0]; + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + if (isMouseOver(mouseX, mouseY)) { + context.fill(getX(), getY(), getRight(), getBottom(), 0x20FFFFFF); + } + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + context.drawText(textRenderer, getMessage(), getX() + 1, getY() + 1, -1, true); + String string = current.toString(); + context.drawText(textRenderer, string, getRight() - textRenderer.getWidth(string) - 1, getY() + 1, -1, true); + } + + public void setCurrent(T current) { + this.current = current; + } + + @Override + public void onClick(double mouseX, double mouseY) { + current = values[(current.ordinal() + 1) % values.length]; + if (onChange != null) onChange.accept(current); + super.onClick(mouseX, mouseY); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + } + + public void setOnChange(Consumer<T> onChange) { + this.onChange = onChange; + } + } + + public static class BooleanOption extends ClickableWidget { + + private boolean current = false; + private Consumer<Boolean> onChange = null; + + public BooleanOption(int x, int y, int width, Text message) { + super(x, y, width, 11, message); + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + if (isMouseOver(mouseX, mouseY)) { + context.fill(getX(), getY(), getRight(), getBottom(), 0x20FFFFFF); + } + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + context.drawText(textRenderer, getMessage(), getX() + 1, getY() + 1, -1, true); + context.drawBorder(getRight() - 10, getY() + 1, 9, 9, -1); + if (current) context.fill(getRight() - 8, getY() + 3, getRight() - 3, getY() + 8, -1); + } + + @Override + public void onClick(double mouseX, double mouseY) { + current = !current; + if (onChange != null) onChange.accept(current); + super.onClick(mouseX, mouseY); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + } + + public void setCurrent(boolean current) { + this.current = current; + } + + public void se |
