From 9590d69e89c2d966fe80501ce4f754da85bc1ac5 Mon Sep 17 00:00:00 2001 From: inyourwalls Date: Fri, 26 Jan 2024 23:31:48 -0500 Subject: reformat, initial config test --- build.gradle.kts | 2 +- src/main/java/net/inyourwalls/frank/Frank.java | 128 +++++++++++---------- .../net/inyourwalls/frank/config/FrankConfig.java | 86 ++++++++++++++ 3 files changed, 157 insertions(+), 59 deletions(-) create mode 100644 src/main/java/net/inyourwalls/frank/config/FrankConfig.java diff --git a/build.gradle.kts b/build.gradle.kts index b97f98a..de9662c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } val minecraftVersion = "1.20.2" -version = "0.1.1+$minecraftVersion" +version = "1.0.0+$minecraftVersion" group = "net.inyourwalls" repositories { diff --git a/src/main/java/net/inyourwalls/frank/Frank.java b/src/main/java/net/inyourwalls/frank/Frank.java index 4b8fc08..7583978 100644 --- a/src/main/java/net/inyourwalls/frank/Frank.java +++ b/src/main/java/net/inyourwalls/frank/Frank.java @@ -4,6 +4,7 @@ package net.inyourwalls.frank; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.fabricmc.fabric.api.registry.FuelRegistry; +import net.inyourwalls.frank.config.FrankConfig; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.ingame.AbstractFurnaceScreen; @@ -16,69 +17,80 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Frank implements ClientModInitializer { - public static final Logger LOGGER = LoggerFactory.getLogger(Frank.class); + public static final Logger LOGGER = LoggerFactory.getLogger(Frank.class); - private static final int CRAFTING_SLOT_INDEX = 0; - private static final int FUEL_SLOT_INDEX = 1; - private static final int WHITE = 0xffffff; + private static final int CRAFTING_SLOT_INDEX = 0; + private static final int FUEL_SLOT_INDEX = 1; - @Override - public void onInitializeClient() { - ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> { - if (screen instanceof AbstractFurnaceScreen furnace) { - ScreenEvents.afterRender(screen).register((_s, drawContext, mouseX, mouseY, tickDelta) -> { - AbstractFurnaceScreenHandler handler = (AbstractFurnaceScreenHandler) furnace.getScreenHandler(); - int speedMultiplier = (handler instanceof BlastFurnaceScreenHandler || handler instanceof SmokerScreenHandler) ? 2 : 1; - renderInfoLines( - furnace, - drawContext, - client.textRenderer, - handler.getSlot(CRAFTING_SLOT_INDEX).getStack().getCount(), - handler.getCookProgress(), - handler.getSlot(FUEL_SLOT_INDEX).getStack(), - handler.getFuelProgress(), - speedMultiplier - ); - }); - } - }); - LOGGER.info("Screen events registered."); - } + @Override + public void onInitializeClient() { + FrankConfig config = new FrankConfig(); + + ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> { + if (screen instanceof AbstractFurnaceScreen furnace) { + AbstractFurnaceScreenHandler handler = (AbstractFurnaceScreenHandler) furnace.getScreenHandler(); + + // Add our text lines. + for (FrankConfig.InfoLine infoLine : config.getActiveInfoLines()) { + + } + + int speedMultiplier = (handler instanceof BlastFurnaceScreenHandler || handler instanceof SmokerScreenHandler) ? 2 : 1; + ScreenEvents.afterRender(screen).register((_s, drawContext, mouseX, mouseY, tickDelta) -> { + renderInfoLines( + furnace, + drawContext, + client.textRenderer, + handler.getSlot(CRAFTING_SLOT_INDEX).getStack().getCount(), + handler.getCookProgress(), + handler.getSlot(FUEL_SLOT_INDEX).getStack(), + handler.getFuelProgress(), + speedMultiplier, + config.getTextColour() + ); + }); - /** - * Renders the info lines on the given screen. - */ - private void renderInfoLines( - AbstractFurnaceScreen screen, - DrawContext context, - TextRenderer renderer, - int itemsInProgress, - float cookProgress, - ItemStack fuel, - float fuelProgress, - int speedMultiplier - ) { - // Determine where to start drawing the information. - int infoX = screen.width / 2 + 90; - int infoY = screen.height / 2 - 80; - if (screen.recipeBook.isOpen()) { - infoX += 77; + ScreenEvents.afterTick(screen).register(_s -> {}); + } + }); + LOGGER.info("Screen events registered."); } - - int smeltingSpeed = 10 / speedMultiplier; // this code sucks, but i don't care. - int secondsLeft = itemsInProgress * smeltingSpeed - (int)(cookProgress * smeltingSpeed); - int minutesLeft = secondsLeft / 60; - secondsLeft = secondsLeft % 60; - int fuelCount = fuel.getCount(); - Integer fuelTicks = FuelRegistry.INSTANCE.get(fuel.getItem()); - // Avoid null pointer exception because Java is terrible. - if (fuelTicks == null) fuelTicks = 0; - int burningFuel = (int)((float)(fuelTicks / 10) * fuelProgress); - int itemsSmeltable = (((fuelTicks / 10) * fuelCount) / 20) + (burningFuel / 20); + /** + * Renders the info lines on the given screen. + */ + private void renderInfoLines( + AbstractFurnaceScreen screen, + DrawContext context, + TextRenderer renderer, + int itemsInProgress, + float cookProgress, + ItemStack fuel, + float fuelProgress, + int speedMultiplier, + int textColour + ) { + // Determine where to start drawing the information. + int infoX = screen.width / 2 + 90; + int infoY = screen.height / 2 - 80; + if (screen.recipeBook.isOpen()) { + infoX += 77; + } + + int smeltingSpeed = 10 / speedMultiplier; // this code sucks, but i don't care. + int secondsLeft = itemsInProgress * smeltingSpeed - (int)(cookProgress * smeltingSpeed); + int minutesLeft = secondsLeft / 60; + secondsLeft = secondsLeft % 60; - context.drawTextWithShadow(renderer, Text.translatable("ui.frank.time_left", minutesLeft, secondsLeft), infoX, infoY, WHITE); - context.drawTextWithShadow(renderer, Text.translatable("ui.frank.smeltable", itemsSmeltable), infoX, infoY + 10, WHITE); - } + int fuelCount = fuel.getCount(); + Integer fuelTicks = FuelRegistry.INSTANCE.get(fuel.getItem()); + // Avoid null pointer exception because Java is terrible. + if (fuelTicks == null) fuelTicks = 0; + int burningFuel = (int)((float)(fuelTicks / 10) * fuelProgress); + int itemsSmeltable = (((fuelTicks / 10) * fuelCount) / 20) + (burningFuel / 20); + + context.drawTextWithShadow(renderer, Text.translatable("ui.frank.time_left", minutesLeft, secondsLeft), infoX, infoY, textColour); + context.drawTextWithShadow(renderer, Text.translatable("ui.frank.smeltable", itemsSmeltable), infoX, infoY + 10, textColour); + } } diff --git a/src/main/java/net/inyourwalls/frank/config/FrankConfig.java b/src/main/java/net/inyourwalls/frank/config/FrankConfig.java new file mode 100644 index 0000000..b17af67 --- /dev/null +++ b/src/main/java/net/inyourwalls/frank/config/FrankConfig.java @@ -0,0 +1,86 @@ +// FrankConfig: Config class for Frank. +package net.inyourwalls.frank.config; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Path; + +public class FrankConfig { + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + private InfoLine[] linesToDisplay = {InfoLine.TIME_LEFT, InfoLine.SMELTABLE}; + private int textColour = 0xffffff; + + /** + * Gets which info lines should be displayed. The order should be treated as + * the order in which they are displayed. + */ + public InfoLine[] getActiveInfoLines() { + return this.linesToDisplay; + } + + /** + * Sets which info lines should be displayed. The order should be treated as + * the order in which they are displayed. + */ + public void setActiveInfoLines(InfoLine... infoLines) { + this.linesToDisplay = infoLines; + } + + /** + * Gets the current text colour. + */ + public int getTextColour() { + return this.textColour; + } + + /** + * Sets a new text colour. + */ + public void setTextColour(int textColour) { + this.textColour = textColour; + } + + /** + * An enum that lists the information lines available in Frank. + */ + public static enum InfoLine { + /** + * A variant representing the "time left" line. + */ + TIME_LEFT, + /** + * A variant representing the "items smeltable" line. + */ + SMELTABLE; + + public String translationKey() { + return "ui.frank." + this.toString().toLowerCase(); + } + } + + /** + * Attempts to load the configuration from the given path. + * @param configPath The path to try loading the configuration from. + * @throws IOException If any errors occur while loading the config. + */ + public static FrankConfig load(Path configPath) throws IOException { + FileReader reader = new FileReader(configPath.toFile()); + return GSON.fromJson(reader, FrankConfig.class); + } + + /** + * Attempts to save the given configuration to the given path. + * @param config The configuration to save. + * @param configPath The path to try saving the configuration to. + * @throws IOException If any errors occur while saving the config. + */ + public static void save(FrankConfig config, Path configPath) throws IOException { + FileWriter writer = new FileWriter(configPath.toFile()); + GSON.toJson(config, writer); + } +} -- cgit v1.3.1 From d61bebc891726fec527deda01e26f784057cb383 Mon Sep 17 00:00:00 2001 From: inyourwalls Date: Sat, 27 Jan 2024 00:16:16 -0500 Subject: rewrite rendering stuff to support line ordering --- src/main/java/net/inyourwalls/frank/Frank.java | 104 +++++++++++++++---------- 1 file changed, 61 insertions(+), 43 deletions(-) diff --git a/src/main/java/net/inyourwalls/frank/Frank.java b/src/main/java/net/inyourwalls/frank/Frank.java index 7583978..45554f3 100644 --- a/src/main/java/net/inyourwalls/frank/Frank.java +++ b/src/main/java/net/inyourwalls/frank/Frank.java @@ -25,72 +25,90 @@ public class Frank implements ClientModInitializer { @Override public void onInitializeClient() { FrankConfig config = new FrankConfig(); + config.setTextColour(0xff7aff); + config.setActiveInfoLines(FrankConfig.InfoLine.SMELTABLE, FrankConfig.InfoLine.TIME_LEFT); ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> { if (screen instanceof AbstractFurnaceScreen furnace) { AbstractFurnaceScreenHandler handler = (AbstractFurnaceScreenHandler) furnace.getScreenHandler(); - // Add our text lines. - for (FrankConfig.InfoLine infoLine : config.getActiveInfoLines()) { - - } - int speedMultiplier = (handler instanceof BlastFurnaceScreenHandler || handler instanceof SmokerScreenHandler) ? 2 : 1; ScreenEvents.afterRender(screen).register((_s, drawContext, mouseX, mouseY, tickDelta) -> { - renderInfoLines( - furnace, - drawContext, - client.textRenderer, - handler.getSlot(CRAFTING_SLOT_INDEX).getStack().getCount(), - handler.getCookProgress(), - handler.getSlot(FUEL_SLOT_INDEX).getStack(), - handler.getFuelProgress(), - speedMultiplier, - config.getTextColour() - ); - }); + int x = screen.width / 2 + 90; // just after the right edge. + int y = screen.height / 2 - 80; // more or less in line with the top edge. + if (furnace.recipeBook.isOpen()) x += 77; + for (FrankConfig.InfoLine infoLine : config.getActiveInfoLines()) { + switch (infoLine) { + case TIME_LEFT -> { + renderTimeLeft( + drawContext, + client.textRenderer, + x, + y, + config.getTextColour(), + handler.getSlot(CRAFTING_SLOT_INDEX).getStack().getCount(), + speedMultiplier, + handler.getCookProgress() + ); + break; + } + + case SMELTABLE -> { + renderItemsSmeltable( + drawContext, + client.textRenderer, + x, + y, + config.getTextColour(), + handler.getSlot(FUEL_SLOT_INDEX).getStack(), + handler.getFuelProgress() + ); + break; + } + } - ScreenEvents.afterTick(screen).register(_s -> {}); + y += 10; + } + }); } }); LOGGER.info("Screen events registered."); } - /** - * Renders the info lines on the given screen. - */ - private void renderInfoLines( - AbstractFurnaceScreen screen, - DrawContext context, - TextRenderer renderer, - int itemsInProgress, - float cookProgress, - ItemStack fuel, - float fuelProgress, + private void renderTimeLeft( + DrawContext context, + TextRenderer renderer, + int x, + int y, + int textColour, + int itemsInProgress, int speedMultiplier, - int textColour + float cookProgress ) { - // Determine where to start drawing the information. - int infoX = screen.width / 2 + 90; - int infoY = screen.height / 2 - 80; - if (screen.recipeBook.isOpen()) { - infoX += 77; - } + int smeltingSpeed = 10 / speedMultiplier; // still kinda lame, but it works! + int secondsLeft = itemsInProgress * smeltingSpeed - (int)(cookProgress * smeltingSpeed); + int minutesLeft = secondsLeft / 60; + secondsLeft = secondsLeft % 60; - int smeltingSpeed = 10 / speedMultiplier; // this code sucks, but i don't care. - int secondsLeft = itemsInProgress * smeltingSpeed - (int)(cookProgress * smeltingSpeed); - int minutesLeft = secondsLeft / 60; - secondsLeft = secondsLeft % 60; + context.drawTextWithShadow(renderer, Text.translatable("ui.frank.time_left", minutesLeft, secondsLeft), x, y, textColour); + } + private void renderItemsSmeltable( + DrawContext context, + TextRenderer renderer, + int x, + int y, + int textColour, + ItemStack fuel, + float fuelProgress + ) { int fuelCount = fuel.getCount(); Integer fuelTicks = FuelRegistry.INSTANCE.get(fuel.getItem()); - // Avoid null pointer exception because Java is terrible. if (fuelTicks == null) fuelTicks = 0; int burningFuel = (int)((float)(fuelTicks / 10) * fuelProgress); int itemsSmeltable = (((fuelTicks / 10) * fuelCount) / 20) + (burningFuel / 20); - context.drawTextWithShadow(renderer, Text.translatable("ui.frank.time_left", minutesLeft, secondsLeft), infoX, infoY, textColour); - context.drawTextWithShadow(renderer, Text.translatable("ui.frank.smeltable", itemsSmeltable), infoX, infoY + 10, textColour); + context.drawTextWithShadow(renderer, Text.translatable("ui.frank.smeltable", itemsSmeltable), x, y, textColour); } } -- cgit v1.3.1 From f25401cdcecfe67e484173d68653a90eff446ba6 Mon Sep 17 00:00:00 2001 From: inyourwalls Date: Sun, 28 Jan 2024 19:39:06 -0500 Subject: modify rendering again, no longer using array in config --- build.gradle.kts | 3 + src/main/java/net/inyourwalls/frank/Frank.java | 133 ++++++++++++++++----- .../net/inyourwalls/frank/ModMenuIntegration.java | 15 +++ .../net/inyourwalls/frank/config/ConfigScreen.java | 110 +++++++++++++++++ .../net/inyourwalls/frank/config/FrankConfig.java | 58 +++++---- src/main/resources/assets/frank/lang/en_us.json | 4 + src/main/resources/fabric.mod.json | 7 +- 7 files changed, 265 insertions(+), 65 deletions(-) create mode 100644 src/main/java/net/inyourwalls/frank/ModMenuIntegration.java create mode 100644 src/main/java/net/inyourwalls/frank/config/ConfigScreen.java diff --git a/build.gradle.kts b/build.gradle.kts index de9662c..032649f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,6 +9,7 @@ group = "net.inyourwalls" repositories { // Repositories to fetch additional dependencies from. + maven("https://maven.terraformersmc.com/") } dependencies { @@ -18,6 +19,8 @@ dependencies { mappings("net.fabricmc:yarn:$minecraftVersion+build.$yarnBuild:v2") modImplementation("net.fabricmc:fabric-loader:0.14.23") modImplementation("net.fabricmc.fabric-api:fabric-api:0.90.4+$minecraftVersion") + + modImplementation("com.terraformersmc:modmenu:9.0.0") } tasks { diff --git a/src/main/java/net/inyourwalls/frank/Frank.java b/src/main/java/net/inyourwalls/frank/Frank.java index 45554f3..e402076 100644 --- a/src/main/java/net/inyourwalls/frank/Frank.java +++ b/src/main/java/net/inyourwalls/frank/Frank.java @@ -2,6 +2,7 @@ package net.inyourwalls.frank; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.fabricmc.fabric.api.registry.FuelRegistry; import net.inyourwalls.frank.config.FrankConfig; @@ -16,17 +17,24 @@ import net.minecraft.text.Text; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.nio.file.Path; + public class Frank implements ClientModInitializer { public static final Logger LOGGER = LoggerFactory.getLogger(Frank.class); - private static final int CRAFTING_SLOT_INDEX = 0; private static final int FUEL_SLOT_INDEX = 1; + private static final Path CONFIG_PATH = FabricLoader.getInstance().getConfigDir().resolve("frank.json"); + private static FrankConfig config; @Override public void onInitializeClient() { - FrankConfig config = new FrankConfig(); - config.setTextColour(0xff7aff); - config.setActiveInfoLines(FrankConfig.InfoLine.SMELTABLE, FrankConfig.InfoLine.TIME_LEFT); + try { + config = FrankConfig.load(CONFIG_PATH); + } catch (IOException ex) { + LOGGER.warn("Failed to load configuration file, falling back on default values."); + config = new FrankConfig(); + } ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> { if (screen instanceof AbstractFurnaceScreen furnace) { @@ -37,37 +45,81 @@ public class Frank implements ClientModInitializer { int x = screen.width / 2 + 90; // just after the right edge. int y = screen.height / 2 - 80; // more or less in line with the top edge. if (furnace.recipeBook.isOpen()) x += 77; - for (FrankConfig.InfoLine infoLine : config.getActiveInfoLines()) { - switch (infoLine) { - case TIME_LEFT -> { - renderTimeLeft( - drawContext, - client.textRenderer, - x, - y, - config.getTextColour(), - handler.getSlot(CRAFTING_SLOT_INDEX).getStack().getCount(), - speedMultiplier, - handler.getCookProgress() - ); - break; - } - - case SMELTABLE -> { - renderItemsSmeltable( - drawContext, - client.textRenderer, - x, - y, - config.getTextColour(), - handler.getSlot(FUEL_SLOT_INDEX).getStack(), - handler.getFuelProgress() - ); - break; - } + switch (config.getDisplayMode()) { + case TIME_LEFT_FIRST -> { + renderTimeLeft( + drawContext, + client.textRenderer, + x, + y, + config.getTextColour(), + handler.getSlot(CRAFTING_SLOT_INDEX).getStack().getCount(), + speedMultiplier, + handler.getCookProgress() + ); + renderItemsSmeltable( + drawContext, + client.textRenderer, + x, + y + 10, + config.getTextColour(), + handler.getSlot(FUEL_SLOT_INDEX).getStack(), + handler.getFuelProgress() + ); + break; + } + + case TIME_LEFT_ONLY -> { + renderTimeLeft( + drawContext, + client.textRenderer, + x, + y, + config.getTextColour(), + handler.getSlot(CRAFTING_SLOT_INDEX).getStack().getCount(), + speedMultiplier, + handler.getCookProgress() + ); + break; + } + + case ITEMS_SMELTABLE_FIRST -> { + renderItemsSmeltable( + drawContext, + client.textRenderer, + x, + y + 10, + config.getTextColour(), + handler.getSlot(FUEL_SLOT_INDEX).getStack(), + handler.getFuelProgress() + ); + renderTimeLeft( + drawContext, + client.textRenderer, + x, + y + 10, + config.getTextColour(), + handler.getSlot(CRAFTING_SLOT_INDEX).getStack().getCount(), + speedMultiplier, + handler.getCookProgress() + ); + break; } - y += 10; + case ITEMS_SMELTABLE_ONLY -> { + renderItemsSmeltable( + drawContext, + client.textRenderer, + x, + y, + config.getTextColour(), + handler.getSlot(FUEL_SLOT_INDEX).getStack(), + handler.getFuelProgress() + ); + break; + } + + case DISABLED -> {} } }); } @@ -110,5 +162,20 @@ public class Frank implements ClientModInitializer { context.drawTextWithShadow(renderer, Text.translatable("ui.frank.smeltable", itemsSmeltable), x, y, textColour); } + + /** + * Gets the current active configuration. + */ + public static FrankConfig getConfig() { + return config; + } + + /** + * Attempts to save the provided configuration. + */ + public static void saveConfig(FrankConfig configToSave) throws IOException { + config = configToSave; + FrankConfig.save(config, CONFIG_PATH); + } } diff --git a/src/main/java/net/inyourwalls/frank/ModMenuIntegration.java b/src/main/java/net/inyourwalls/frank/ModMenuIntegration.java new file mode 100644 index 0000000..e28fd5f --- /dev/null +++ b/src/main/java/net/inyourwalls/frank/ModMenuIntegration.java @@ -0,0 +1,15 @@ +// ModMenuIntegration: Entrypoint for integrating with Mod Menu. +package net.inyourwalls.frank; + +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; +import net.inyourwalls.frank.config.ConfigScreen; + +public class ModMenuIntegration implements ModMenuApi { + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + return parent -> { + return new ConfigScreen(parent); + }; + } +} diff --git a/src/main/java/net/inyourwalls/frank/config/ConfigScreen.java b/src/main/java/net/inyourwalls/frank/config/ConfigScreen.java new file mode 100644 index 0000000..3217f6e --- /dev/null +++ b/src/main/java/net/inyourwalls/frank/config/ConfigScreen.java @@ -0,0 +1,110 @@ +// ConfigScreen: Frank's configuration screen. +package net.inyourwalls.frank.config; + +import net.inyourwalls.frank.Frank; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +import java.io.IOException; + +import static net.minecraft.client.gui.widget.ButtonWidget.DEFAULT_WIDTH_SMALL; +import static net.minecraft.client.gui.widget.ButtonWidget.DEFAULT_HEIGHT; + +public class ConfigScreen extends Screen { + private static final Identifier FURNACE_UI_TEXTURE = new Identifier("textures/gui/container/furnace.png"); + private static final int FURNACE_TEXTURE_WIDTH = 176; + private static final int FURNACE_TEXTURE_HEIGHT = 166; + private final FrankConfig modifiedConfig; + private final Screen previousScreen; + + public ConfigScreen(Screen previous) { + super(Text.translatable("ui.frank.config")); + this.previousScreen = previous; + this.modifiedConfig = Frank.getConfig(); + } + + @Override + public void init() { + int exitButtonY = this.height / 2 + FURNACE_TEXTURE_HEIGHT + 10; + ButtonWidget backButton = ButtonWidget.builder(Text.translatable("gui.back"), thisButton -> { + this.close(); + }) + .size(DEFAULT_WIDTH_SMALL, DEFAULT_HEIGHT) + .position(this.width / 2 - DEFAULT_WIDTH_SMALL, exitButtonY) + .build(); + + ButtonWidget saveButton = ButtonWidget.builder(Text.translatable("selectWorld.edit.save"), thisButton -> { + try { + Frank.saveConfig(modifiedConfig); + Frank.LOGGER.info("Configuration file was successfully saved."); + } catch (IOException ex) { + Frank.LOGGER.error("Failed to save configuration file", ex); + } + }) + .size(DEFAULT_WIDTH_SMALL, DEFAULT_HEIGHT) + .position(this.width / 2, exitButtonY) + .build(); + + this.addDrawableChild(backButton); + this.addDrawableChild(saveButton); + } + + @Override + public void close() { + this.client.setScreen(this.previousScreen); + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + context.drawCenteredTextWithShadow(this.textRenderer, Text.translatable("ui.frank.config"), this.width / 2, 5, 0xffffff); + + int x = (this.width / 2) - (FURNACE_TEXTURE_WIDTH / 2); + int y = this.height / 2; + renderPreview(context, x, y); + } + + private void renderPreview(DrawContext context, int x, int y) { + context.drawCenteredTextWithShadow( + this.textRenderer, + Text.translatable("ui.frank.config.preview"), + x + (FURNACE_TEXTURE_WIDTH / 2), + y - 10, + 0xffffff + ); + context.drawTexture(FURNACE_UI_TEXTURE, x, y, 0, 0, FURNACE_TEXTURE_WIDTH, FURNACE_TEXTURE_HEIGHT); + + int infoX = x + FURNACE_TEXTURE_WIDTH + 2; + int infoY = y + 3; + for (FrankConfig.InfoLine infoLine : modifiedConfig.getActiveInfoLines()) { + switch (infoLine) { + case TIME_LEFT -> { + context.drawTextWithShadow( + this.textRenderer, + Text.translatable("ui.frank.time_left", 0, 0), + infoX, + infoY, + modifiedConfig.getTextColour() + ); + break; + } + + case SMELTABLE -> { + context.drawTextWithShadow( + this.textRenderer, + Text.translatable("ui.frank.smeltable", 0), + infoX, + infoY, + modifiedConfig.getTextColour() + ); + break; + } + } + + infoY += 10; + } + } +} diff --git a/src/main/java/net/inyourwalls/frank/config/FrankConfig.java b/src/main/java/net/inyourwalls/frank/config/FrankConfig.java index b17af67..4619bb7 100644 --- a/src/main/java/net/inyourwalls/frank/config/FrankConfig.java +++ b/src/main/java/net/inyourwalls/frank/config/FrankConfig.java @@ -12,23 +12,21 @@ import java.nio.file.Path; public class FrankConfig { private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); - private InfoLine[] linesToDisplay = {InfoLine.TIME_LEFT, InfoLine.SMELTABLE}; + private InfoDisplayMode infoDisplayMode = InfoDisplayMode.TIME_LEFT_FIRST; private int textColour = 0xffffff; /** - * Gets which info lines should be displayed. The order should be treated as - * the order in which they are displayed. + * Gets the "mode" Frank should display its information in. */ - public InfoLine[] getActiveInfoLines() { - return this.linesToDisplay; + public InfoDisplayMode getDisplayMode() { + return this.infoDisplayMode; } /** - * Sets which info lines should be displayed. The order should be treated as - * the order in which they are displayed. + * Sets the "mode" Frank should display its information in. */ - public void setActiveInfoLines(InfoLine... infoLines) { - this.linesToDisplay = infoLines; + public void setDisplayMode(InfoDisplayMode infoDisplayMode) { + this.infoDisplayMode = infoDisplayMode; } /** @@ -46,31 +44,15 @@ public class FrankConfig { } /** - * An enum that lists the information lines available in Frank. - */ - public static enum InfoLine { - /** - * A variant representing the "time left" line. - */ - TIME_LEFT, - /** - * A variant representing the "items smeltable" line. - */ - SMELTABLE; - - public String translationKey() { - return "ui.frank." + this.toString().toLowerCase(); - } - } - - /** - * Attempts to load the configuration from the given path. + * Attempts to load the configuration from the given path. If the file is + * empty, all values will be set to default. * @param configPath The path to try loading the configuration from. - * @throws IOException If any errors occur while loading the config. + * @throws IOException If any I/O errors occur while loading the config. */ public static FrankConfig load(Path configPath) throws IOException { FileReader reader = new FileReader(configPath.toFile()); - return GSON.fromJson(reader, FrankConfig.class); + FrankConfig loadedConfig = GSON.fromJson(reader, FrankConfig.class); + return loadedConfig == null ? new FrankConfig() : loadedConfig; } /** @@ -82,5 +64,21 @@ public class FrankConfig { public static void save(FrankConfig config, Path configPath) throws IOException { FileWriter writer = new FileWriter(configPath.toFile()); GSON.toJson(config, writer); + writer.close(); + } + + /** + * An enum representing the five ways Frank can display its information. + */ + public static enum InfoDisplayMode { + TIME_LEFT_FIRST, + TIME_LEFT_ONLY, + ITEMS_SMELTABLE_FIRST, + ITEMS_SMELTABLE_ONLY, + DISABLED; + + public String translationKey() { + return "ui.frank.config." + this.toString().toLowerCase(); + } } } diff --git a/src/main/resources/assets/frank/lang/en_us.json b/src/main/resources/assets/frank/lang/en_us.json index ca2862d..bdb1422 100644 --- a/src/main/resources/assets/frank/lang/en_us.json +++ b/src/main/resources/assets/frank/lang/en_us.json @@ -1,5 +1,9 @@ { "ui.frank.time_left": "Time remaining: %sm %ss", "ui.frank.smeltable": "Items smeltable: %s", + + "ui.frank.config": "Configuration - Frank", + "ui.frank.config.preview": "Preview", + "frank.matrix": "Matrix" } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 5c676c5..e02b2b5 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -3,7 +3,7 @@ "id": "frank", "version": "${version}", "name": "Frank", - "description": "Mod that displays additional info about furnaces and fuels.", + "description": "Mod that displays additional info in furnaces.", "authors": [ "InYourWalls" ], @@ -16,11 +16,14 @@ "entrypoints": { "client": [ "net.inyourwalls.frank.Frank" + ], + "modmenu": [ + "net.inyourwalls.frank.ModMenuIntegration" ] }, "depends": { "fabricloader": ">=0.14.22", - "fabric-api": ">=0.90.4+1.20.2", + "fabric-screen-api-v1": ">=0.90.4+1.20.2", "minecraft": "~1.20.2", "java": ">=17" }, -- cgit v1.3.1 From 037db74c048b66e20d62bde7a35e85f579661552 Mon Sep 17 00:00:00 2001 From: inyourwalls Date: Sun, 28 Jan 2024 20:47:36 -0500 Subject: make all the fancy dials works --- .../net/inyourwalls/frank/ModMenuIntegration.java | 2 +- .../net/inyourwalls/frank/config/ConfigScreen.java | 144 ++++++++++++++++----- src/main/resources/assets/frank/lang/en_us.json | 5 + 3 files changed, 119 insertions(+), 32 deletions(-) diff --git a/src/main/java/net/inyourwalls/frank/ModMenuIntegration.java b/src/main/java/net/inyourwalls/frank/ModMenuIntegration.java index e28fd5f..053e871 100644 --- a/src/main/java/net/inyourwalls/frank/ModMenuIntegration.java +++ b/src/main/java/net/inyourwalls/frank/ModMenuIntegration.java @@ -9,7 +9,7 @@ public class ModMenuIntegration implements ModMenuApi { @Override public ConfigScreenFactory getModConfigScreenFactory() { return parent -> { - return new ConfigScreen(parent); + return new ConfigScreen(parent, Frank.getConfig()); }; } } diff --git a/src/main/java/net/inyourwalls/frank/config/ConfigScreen.java b/src/main/java/net/inyourwalls/frank/config/ConfigScreen.java index 3217f6e..f074f9a 100644 --- a/src/main/java/net/inyourwalls/frank/config/ConfigScreen.java +++ b/src/main/java/net/inyourwalls/frank/config/ConfigScreen.java @@ -2,13 +2,16 @@ package net.inyourwalls.frank.config; import net.inyourwalls.frank.Frank; +import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import java.io.IOException; +import java.util.stream.IntStream; import static net.minecraft.client.gui.widget.ButtonWidget.DEFAULT_WIDTH_SMALL; import static net.minecraft.client.gui.widget.ButtonWidget.DEFAULT_HEIGHT; @@ -17,13 +20,14 @@ public class ConfigScreen extends Screen { private static final Identifier FURNACE_UI_TEXTURE = new Identifier("textures/gui/container/furnace.png"); private static final int FURNACE_TEXTURE_WIDTH = 176; private static final int FURNACE_TEXTURE_HEIGHT = 166; - private final FrankConfig modifiedConfig; + private final FrankConfig modifiedConfig = new FrankConfig(); private final Screen previousScreen; - public ConfigScreen(Screen previous) { + public ConfigScreen(Screen previous, FrankConfig currentConfig) { super(Text.translatable("ui.frank.config")); this.previousScreen = previous; - this.modifiedConfig = Frank.getConfig(); + modifiedConfig.setDisplayMode(currentConfig.getDisplayMode()); + modifiedConfig.setTextColour(currentConfig.getTextColour()); } @Override @@ -48,8 +52,47 @@ public class ConfigScreen extends Screen { .position(this.width / 2, exitButtonY) .build(); + ButtonWidget modeToggleButton = ButtonWidget.builder( + Text.translatable(modifiedConfig.getDisplayMode().translationKey()), + thisButton -> { + int ordinal = modifiedConfig.getDisplayMode().ordinal(); + FrankConfig.InfoDisplayMode[] infoDisplayModes = FrankConfig.InfoDisplayMode.values(); + if (++ordinal >= infoDisplayModes.length) { + ordinal = 0; + } + + modifiedConfig.setDisplayMode(infoDisplayModes[ordinal]); + thisButton.setMessage(Text.translatable(modifiedConfig.getDisplayMode().translationKey())); + } + ) + .size(DEFAULT_WIDTH_SMALL, DEFAULT_HEIGHT) + .position(this.width / 2 - DEFAULT_WIDTH_SMALL, 15) + .build(); + + TextFieldWidget colourField = new TextFieldWidget( + this.textRenderer, + this.width / 2 - DEFAULT_WIDTH_SMALL, + 35, + DEFAULT_WIDTH_SMALL, + DEFAULT_HEIGHT, + Text.translatable("ui.frank.config.text_colour") + ); + colourField.setChangedListener(input -> { + try { + int newColour = Integer.parseInt(input, 16); + modifiedConfig.setTextColour(newColour); + } catch (NumberFormatException ex) { /* how */ } + }); + colourField.setTextPredicate(text -> + text.length() <= 6 && text.chars().allMatch(c -> + (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9') + ) + ); + this.addDrawableChild(backButton); this.addDrawableChild(saveButton); + this.addDrawableChild(modeToggleButton); + this.addDrawableChild(colourField); } @Override @@ -63,48 +106,87 @@ public class ConfigScreen extends Screen { context.drawCenteredTextWithShadow(this.textRenderer, Text.translatable("ui.frank.config"), this.width / 2, 5, 0xffffff); int x = (this.width / 2) - (FURNACE_TEXTURE_WIDTH / 2); - int y = this.height / 2; + int y = this.height / 2 - (FURNACE_TEXTURE_HEIGHT / 2); renderPreview(context, x, y); } private void renderPreview(DrawContext context, int x, int y) { - context.drawCenteredTextWithShadow( + context.drawTexture(FURNACE_UI_TEXTURE, x, y, 0, 0, FURNACE_TEXTURE_WIDTH, FURNACE_TEXTURE_HEIGHT); + drawCenteredText( + context, this.textRenderer, Text.translatable("ui.frank.config.preview"), x + (FURNACE_TEXTURE_WIDTH / 2), - y - 10, - 0xffffff + y + 6, + 0x404040 ); - context.drawTexture(FURNACE_UI_TEXTURE, x, y, 0, 0, FURNACE_TEXTURE_WIDTH, FURNACE_TEXTURE_HEIGHT); int infoX = x + FURNACE_TEXTURE_WIDTH + 2; int infoY = y + 3; - for (FrankConfig.InfoLine infoLine : modifiedConfig.getActiveInfoLines()) { - switch (infoLine) { - case TIME_LEFT -> { - context.drawTextWithShadow( - this.textRenderer, - Text.translatable("ui.frank.time_left", 0, 0), - infoX, - infoY, - modifiedConfig.getTextColour() - ); - break; - } + switch (modifiedConfig.getDisplayMode()) { + case TIME_LEFT_FIRST -> { + context.drawTextWithShadow( + this.textRenderer, + Text.translatable("ui.frank.time_left", 0, 0), + infoX, + infoY, + modifiedConfig.getTextColour() + ); + context.drawTextWithShadow( + this.textRenderer, + Text.translatable("ui.frank.smeltable", 0), + infoX, + infoY + 10, + modifiedConfig.getTextColour() + ); + break; + } - case SMELTABLE -> { - context.drawTextWithShadow( - this.textRenderer, - Text.translatable("ui.frank.smeltable", 0), - infoX, - infoY, - modifiedConfig.getTextColour() - ); - break; - } + case TIME_LEFT_ONLY -> { + context.drawTextWithShadow( + this.textRenderer, + Text.translatable("ui.frank.time_left", 0, 0), + infoX, + infoY, + modifiedConfig.getTextColour() + ); + break; } - infoY += 10; + case ITEMS_SMELTABLE_FIRST -> { + context.drawTextWithShadow( + this.textRenderer, + Text.translatable("ui.frank.smeltable", 0), + infoX, + infoY, + modifiedConfig.getTextColour() + ); + context.drawTextWithShadow( + this.textRenderer, + Text.translatable("ui.frank.time_left", 0, 0), + infoX, + infoY + 10, + modifiedConfig.getTextColour() + ); + break; + } + + case ITEMS_SMELTABLE_ONLY -> { + context.drawTextWithShadow( + this.textRenderer, + Text.translatable("ui.frank.smeltable", 0), + infoX, + infoY, + modifiedConfig.getTextColour() + ); + break; + } + + case DISABLED -> {} } } + + private void drawCenteredText(DrawContext context, TextRenderer renderer, Text text, int centerX, int y, int colour) { + context.drawText(renderer, text, centerX - renderer.getWidth(text) / 2, y, colour, false); + } } diff --git a/src/main/resources/assets/frank/lang/en_us.json b/src/main/resources/assets/frank/lang/en_us.json index bdb1422..0a4e82f 100644 --- a/src/main/resources/assets/frank/lang/en_us.json +++ b/src/main/resources/assets/frank/lang/en_us.json @@ -4,6 +4,11 @@ "ui.frank.config": "Configuration - Frank", "ui.frank.config.preview": "Preview", + "ui.frank.config.time_left_first": "Time Left First", + "ui.frank.config.time_left_only": "Time Left Only", + "ui.frank.config.items_smeltable_first": "Items Smeltable First", + "ui.frank.config.items_smeltable_only": "Items Smeltable Only", + "ui.frank.config.disabled": "Disabled", "frank.matrix": "Matrix" } -- cgit v1.3.1 From 3f596f5f02bb9dc34e644a04d1d21ba703a0ad1f Mon Sep 17 00:00:00 2001 From: inyourwalls Date: Mon, 29 Jan 2024 00:10:15 -0500 Subject: make the screen look somewhat passable --- .../net/inyourwalls/frank/config/ConfigScreen.java | 48 +++++++++++++++------- src/main/resources/assets/frank/lang/en_us.json | 3 ++ 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/inyourwalls/frank/config/ConfigScreen.java b/src/main/java/net/inyourwalls/frank/config/ConfigScreen.java index f074f9a..211dee5 100644 --- a/src/main/java/net/inyourwalls/frank/config/ConfigScreen.java +++ b/src/main/java/net/inyourwalls/frank/config/ConfigScreen.java @@ -5,14 +5,15 @@ import net.inyourwalls.frank.Frank; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import java.io.IOException; -import java.util.stream.IntStream; +import static net.minecraft.client.gui.widget.ButtonWidget.DEFAULT_WIDTH; import static net.minecraft.client.gui.widget.ButtonWidget.DEFAULT_WIDTH_SMALL; import static net.minecraft.client.gui.widget.ButtonWidget.DEFAULT_HEIGHT; @@ -20,6 +21,8 @@ public class ConfigScreen extends Screen { private static final Identifier FURNACE_UI_TEXTURE = new Identifier("textures/gui/container/furnace.png"); private static final int FURNACE_TEXTURE_WIDTH = 176; private static final int FURNACE_TEXTURE_HEIGHT = 166; + private static final Text DISPLAY_MODE_LABEL = Text.translatable("ui.frank.config.display_mode"); + private static final Text TEXT_COLOUR_LABEL = Text.translatable("ui.frank.config.text_colour"); private final FrankConfig modifiedConfig = new FrankConfig(); private final Screen previousScreen; @@ -32,24 +35,21 @@ public class ConfigScreen extends Screen { @Override public void init() { - int exitButtonY = this.height / 2 + FURNACE_TEXTURE_HEIGHT + 10; - ButtonWidget backButton = ButtonWidget.builder(Text.translatable("gui.back"), thisButton -> { - this.close(); - }) - .size(DEFAULT_WIDTH_SMALL, DEFAULT_HEIGHT) - .position(this.width / 2 - DEFAULT_WIDTH_SMALL, exitButtonY) - .build(); + ButtonWidget backButton = ButtonWidget.builder(Text.translatable("gui.back"), thisButton -> this.close()) + .size(DEFAULT_WIDTH, DEFAULT_HEIGHT) + .position(this.width / 2 - DEFAULT_WIDTH - 4, this.height - 28) + .build(); ButtonWidget saveButton = ButtonWidget.builder(Text.translatable("selectWorld.edit.save"), thisButton -> { try { Frank.saveConfig(modifiedConfig); - Frank.LOGGER.info("Configuration file was successfully saved."); + Frank.LOGGER.debug("Configuration file was successfully saved."); } catch (IOException ex) { Frank.LOGGER.error("Failed to save configuration file", ex); } }) - .size(DEFAULT_WIDTH_SMALL, DEFAULT_HEIGHT) - .position(this.width / 2, exitButtonY) + .size(DEFAULT_WIDTH, DEFAULT_HEIGHT) + .position(this.width / 2 + 4, this.height - 28) .build(); ButtonWidget modeToggleButton = ButtonWidget.builder( @@ -66,16 +66,16 @@ public class ConfigScreen extends Screen { } ) .size(DEFAULT_WIDTH_SMALL, DEFAULT_HEIGHT) - .position(this.width / 2 - DEFAULT_WIDTH_SMALL, 15) + .position(this.width / 2 + 4, 25) .build(); TextFieldWidget colourField = new TextFieldWidget( this.textRenderer, - this.width / 2 - DEFAULT_WIDTH_SMALL, - 35, + this.width / 2 + 4, + 55, DEFAULT_WIDTH_SMALL, DEFAULT_HEIGHT, - Text.translatable("ui.frank.config.text_colour") + TEXT_COLOUR_LABEL ); colourField.setChangedListener(input -> { try { @@ -88,6 +88,8 @@ public class ConfigScreen extends Screen { (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9') ) ); + colourField.setText(String.format("%x", modifiedConfig.getTextColour())); + colourField.setTooltip(Tooltip.of(Text.translatable("ui.frank.config.text_colour.tooltip"))); this.addDrawableChild(backButton); this.addDrawableChild(saveButton); @@ -105,6 +107,22 @@ public class ConfigScreen extends Screen { super.render(context, mouseX, mouseY, delta); context.drawCenteredTextWithShadow(this.textRenderer, Text.translatable("ui.frank.config"), this.width / 2, 5, 0xffffff); + int labelX = this.width / 2 - Math.max(this.textRenderer.getWidth(DISPLAY_MODE_LABEL), this.textRenderer.getWidth(TEXT_COLOUR_LABEL)) - 4; + context.drawTextWithShadow( + this.textRenderer, + DISPLAY_MODE_LABEL, + labelX, + 30, + 0xffffff + ); + context.drawTextWithShadow( + this.textRenderer, + TEXT_COLOUR_LABEL, + labelX, + 60, + 0xffffff + ); + int x = (this.width / 2) - (FURNACE_TEXTURE_WIDTH / 2); int y = this.height / 2 - (FURNACE_TEXTURE_HEIGHT / 2); renderPreview(context, x, y); diff --git a/src/main/resources/assets/frank/lang/en_us.json b/src/main/resources/assets/frank/lang/en_us.json index 0a4e82f..1a7471d 100644 --- a/src/main/resources/assets/frank/lang/en_us.json +++ b/src/main/resources/assets/frank/lang/en_us.json @@ -9,6 +9,9 @@ "ui.frank.config.items_smeltable_first": "Items Smeltable First", "ui.frank.config.items_smeltable_only": "Items Smeltable Only", "ui.frank.config.disabled": "Disabled", + "ui.frank.config.display_mode": "Display Mode", + "ui.frank.config.text_colour": "Text Color", + "ui.frank.config.text_colour.tooltip": "Hexadecimal RGB value for the text color.", "frank.matrix": "Matrix" } -- cgit v1.3.1 From a8e9e6c26c598a0f967f1aaaf5e831b22a4b4d9e Mon Sep 17 00:00:00 2001 From: inyourwalls Date: Mon, 29 Jan 2024 00:20:23 -0500 Subject: add en_ca localisation (hugely important) --- src/main/resources/assets/frank/lang/en_ca.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/resources/assets/frank/lang/en_ca.json diff --git a/src/main/resources/assets/frank/lang/en_ca.json b/src/main/resources/assets/frank/lang/en_ca.json new file mode 100644 index 0000000..07f9fda --- /dev/null +++ b/src/main/resources/assets/frank/lang/en_ca.json @@ -0,0 +1,4 @@ +{ + "ui.frank.config.text_colour": "Text Colour", + "ui.frank.config.text_colour.tooltip": "Hexadecimal RGB value for the text colour." +} -- cgit v1.3.1 From 3567fea6ca8749d66e0ad4f62ba5efd5ea705d9f Mon Sep 17 00:00:00 2001 From: inyourwalls Date: Mon, 29 Jan 2024 12:14:18 -0500 Subject: remove a 10px offset that should not have been there --- src/main/java/net/inyourwalls/frank/Frank.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/inyourwalls/frank/Frank.java b/src/main/java/net/inyourwalls/frank/Frank.java index e402076..0aebd73 100644 --- a/src/main/java/net/inyourwalls/frank/Frank.java +++ b/src/main/java/net/inyourwalls/frank/Frank.java @@ -88,7 +88,7 @@ public class Frank implements ClientModInitializer { drawContext, client.textRenderer, x, - y + 10, + y, config.getTextColour(), handler.getSlot(FUEL_SLOT_INDEX).getStack(), handler.getFuelProgress() -- cgit v1.3.1