diff --git a/Fabric/src/main/java/chylex/customwindowtitle/TitleConfig.java b/Fabric/src/main/java/chylex/customwindowtitle/TitleConfig.java index c4551cb..7d08fa3 100644 --- a/Fabric/src/main/java/chylex/customwindowtitle/TitleConfig.java +++ b/Fabric/src/main/java/chylex/customwindowtitle/TitleConfig.java @@ -1,22 +1,33 @@ package chylex.customwindowtitle; -import com.google.common.collect.ImmutableMap; import java.io.IOException; +import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.stream.Collectors; public final class TitleConfig{ - private static final Map<String, String> DEFAULTS = ImmutableMap.<String, String>builder() - .put("title", "Minecraft {mcversion}") - .build(); + private static final Map<String, String> DEFAULTS; + + static{ + final Map<String, String> defaults = new LinkedHashMap<>(); + + defaults.put("title", "Minecraft {mcversion}"); + defaults.put("icon16", ""); + defaults.put("icon32", ""); + + DEFAULTS = Collections.unmodifiableMap(defaults); + } public static TitleConfig read(final String folder){ final Path configFile = Paths.get(folder, "customwindowtitle-client.toml"); - final Map<String, String> config = new HashMap<>(DEFAULTS); + final Map<String, String> config = new LinkedHashMap<>(DEFAULTS); try{ if (!Files.exists(configFile)){ @@ -45,7 +56,25 @@ public final class TitleConfig{ throw new RuntimeException("CustomWindowTitle configuration error", e); } - return new TitleConfig(config.get("title")); + final String icon16 = config.get("icon16"); + final String icon32 = config.get("icon32"); + + final Path pathIcon16 = icon16.isEmpty() ? null : Paths.get(folder, icon16); + final Path pathIcon32 = icon32.isEmpty() ? null : Paths.get(folder, icon32); + + if ((pathIcon16 == null) != (pathIcon32 == null)){ + throw new RuntimeException("CustomWindowTitle configuration specifies only one icon, both 'icon16' and 'icon32' must be set."); + } + + if (pathIcon16 != null && Files.notExists(pathIcon16)){ + throw new RuntimeException("CustomWindowTitle 16x16 icon not found: " + pathIcon16); + } + + if (pathIcon32 != null && Files.notExists(pathIcon32)){ + throw new RuntimeException("CustomWindowTitle 32x32 icon not found: " + pathIcon32); + } + + return new TitleConfig(config.get("title"), pathIcon16, pathIcon32); } private static String parseTrimmedValue(String value){ @@ -68,12 +97,36 @@ public final class TitleConfig{ } private final String title; + private final Path icon16; + private final Path icon32; - private TitleConfig(final String title){ + private TitleConfig(final String title, final Path icon16, final Path icon32){ this.title = title; + this.icon16 = icon16; + this.icon32 = icon32; } public String getTitle(){ return title; } + + public boolean hasIcon(){ + return icon16 != null && icon32 != null; + } + + public InputStream readIcon16(){ + try{ + return Files.newInputStream(icon16, StandardOpenOption.READ); + }catch(final IOException e){ + throw new RuntimeException("CustomWindowTitle could not open the specified 16x16 icon: " + icon16, e); + } + } + + public InputStream readIcon32(){ + try{ + return Files.newInputStream(icon32, StandardOpenOption.READ); + }catch(final IOException e){ + throw new RuntimeException("CustomWindowTitle could not open the specified 32x32 icon: " + icon16, e); + } + } } diff --git a/Fabric/src/main/java/chylex/customwindowtitle/fabric/CustomWindowTitle.java b/Fabric/src/main/java/chylex/customwindowtitle/fabric/CustomWindowTitle.java index 712478e..3369829 100644 --- a/Fabric/src/main/java/chylex/customwindowtitle/fabric/CustomWindowTitle.java +++ b/Fabric/src/main/java/chylex/customwindowtitle/fabric/CustomWindowTitle.java @@ -4,6 +4,7 @@ import chylex.customwindowtitle.TitleParser; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.util.Window; public class CustomWindowTitle implements ClientModInitializer{ private final TitleConfig config; @@ -19,6 +20,11 @@ public class CustomWindowTitle implements ClientModInitializer{ } private void updateTitle(){ - MinecraftClient.getInstance().getWindow().setTitle(TitleParser.parse(config.getTitle())); + final Window window = MinecraftClient.getInstance().getWindow(); + window.setTitle(TitleParser.parse(config.getTitle())); + + if (config.hasIcon()){ + window.setIcon(config.readIcon16(), config.readIcon32()); + } } } diff --git a/Forge/src/main/java/chylex/customwindowtitle/TitleConfig.java b/Forge/src/main/java/chylex/customwindowtitle/TitleConfig.java index c4551cb..7d08fa3 100644 --- a/Forge/src/main/java/chylex/customwindowtitle/TitleConfig.java +++ b/Forge/src/main/java/chylex/customwindowtitle/TitleConfig.java @@ -1,22 +1,33 @@ package chylex.customwindowtitle; -import com.google.common.collect.ImmutableMap; import java.io.IOException; +import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.stream.Collectors; public final class TitleConfig{ - private static final Map<String, String> DEFAULTS = ImmutableMap.<String, String>builder() - .put("title", "Minecraft {mcversion}") - .build(); + private static final Map<String, String> DEFAULTS; + + static{ + final Map<String, String> defaults = new LinkedHashMap<>(); + + defaults.put("title", "Minecraft {mcversion}"); + defaults.put("icon16", ""); + defaults.put("icon32", ""); + + DEFAULTS = Collections.unmodifiableMap(defaults); + } public static TitleConfig read(final String folder){ final Path configFile = Paths.get(folder, "customwindowtitle-client.toml"); - final Map<String, String> config = new HashMap<>(DEFAULTS); + final Map<String, String> config = new LinkedHashMap<>(DEFAULTS); try{ if (!Files.exists(configFile)){ @@ -45,7 +56,25 @@ public final class TitleConfig{ throw new RuntimeException("CustomWindowTitle configuration error", e); } - return new TitleConfig(config.get("title")); + final String icon16 = config.get("icon16"); + final String icon32 = config.get("icon32"); + + final Path pathIcon16 = icon16.isEmpty() ? null : Paths.get(folder, icon16); + final Path pathIcon32 = icon32.isEmpty() ? null : Paths.get(folder, icon32); + + if ((pathIcon16 == null) != (pathIcon32 == null)){ + throw new RuntimeException("CustomWindowTitle configuration specifies only one icon, both 'icon16' and 'icon32' must be set."); + } + + if (pathIcon16 != null && Files.notExists(pathIcon16)){ + throw new RuntimeException("CustomWindowTitle 16x16 icon not found: " + pathIcon16); + } + + if (pathIcon32 != null && Files.notExists(pathIcon32)){ + throw new RuntimeException("CustomWindowTitle 32x32 icon not found: " + pathIcon32); + } + + return new TitleConfig(config.get("title"), pathIcon16, pathIcon32); } private static String parseTrimmedValue(String value){ @@ -68,12 +97,36 @@ public final class TitleConfig{ } private final String title; + private final Path icon16; + private final Path icon32; - private TitleConfig(final String title){ + private TitleConfig(final String title, final Path icon16, final Path icon32){ this.title = title; + this.icon16 = icon16; + this.icon32 = icon32; } public String getTitle(){ return title; } + + public boolean hasIcon(){ + return icon16 != null && icon32 != null; + } + + public InputStream readIcon16(){ + try{ + return Files.newInputStream(icon16, StandardOpenOption.READ); + }catch(final IOException e){ + throw new RuntimeException("CustomWindowTitle could not open the specified 16x16 icon: " + icon16, e); + } + } + + public InputStream readIcon32(){ + try{ + return Files.newInputStream(icon32, StandardOpenOption.READ); + }catch(final IOException e){ + throw new RuntimeException("CustomWindowTitle could not open the specified 32x32 icon: " + icon16, e); + } + } } diff --git a/Forge/src/main/java/chylex/customwindowtitle/forge/CustomWindowTitle.java b/Forge/src/main/java/chylex/customwindowtitle/forge/CustomWindowTitle.java index f7242a4..760e512 100644 --- a/Forge/src/main/java/chylex/customwindowtitle/forge/CustomWindowTitle.java +++ b/Forge/src/main/java/chylex/customwindowtitle/forge/CustomWindowTitle.java @@ -1,6 +1,7 @@ package chylex.customwindowtitle.forge; import chylex.customwindowtitle.TitleConfig; import chylex.customwindowtitle.TitleParser; +import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @@ -24,6 +25,11 @@ public class CustomWindowTitle{ } private void updateTitle(){ - Minecraft.getInstance().getMainWindow().func_230148_b_(TitleParser.parse(config.getTitle())); + final MainWindow window = Minecraft.getInstance().getMainWindow(); + window.func_230148_b_(TitleParser.parse(config.getTitle())); + + if (config.hasIcon()){ + window.setWindowIcon(config.readIcon16(), config.readIcon32()); + } } }