From f854e0f3a655862c83d8d75cc645ebeb946e9beb Mon Sep 17 00:00:00 2001 From: Miepee Date: Thu, 19 Jan 2023 00:30:22 +0100 Subject: [PATCH] Make icons editable in GUI --- AM2RPortHelperCLI/Program.cs | 5 +- .../AM2RPortHelperGUI/MainForm.cs | 84 +++++++++++++++++-- AM2RPortHelperLib/Core.cs | 3 +- AM2RPortHelperLib/RawMods.cs | 2 +- AM2RPortHelperLib/Resources.Designer.cs | 8 +- 5 files changed, 87 insertions(+), 15 deletions(-) diff --git a/AM2RPortHelperCLI/Program.cs b/AM2RPortHelperCLI/Program.cs index 9fcc609..00d765f 100644 --- a/AM2RPortHelperCLI/Program.cs +++ b/AM2RPortHelperCLI/Program.cs @@ -24,9 +24,10 @@ internal static class Program var linuxOption = new Option(new[] { "-l", "--linux" }, "The output file path for the Linux mod. None given equals to no Linux port."); var androidOption = new Option(new[] { "-a", "--android" }, "The output file path for the Android mod. None given equals to no Android port."); var macOption = new Option(new[] { "-m", "--mac" }, "The output file path for the Mac mod. None given equals to no Mac port."); - var iconOption = new Option(new[] { "-c", "--icon " }, "The file path to an icon PNG that should be used for the taskbar/dock/home screen. " + + var iconOption = new Option(new[] { "-c", "--icon" }, "The file path to an icon PNG that should be used for the taskbar/dock/home screen. " + "If this is not set, it will read \"icon.png\" from the config folder. If that file does not exist, a stock icon will be used."); - var splashOption = new Option(new[] { "-p", "--splash " }, "The file path to a splash PNG that should be used when booting the game. " + + var splashOption = new Option(new[] { "-p", "--splash" }, "The file path to a splash PNG that should be used when booting the game. " + + //TODO: only use splash.png "If this is not set, it will read \"splash.png\" (or \"splashAndroid.png\" for Android) from the config folder. " + "If that file does not exist, a stock splash will be used."); // TODO: double check whether its not possible to have the same splash screen for both desktop and mobile diff --git a/AM2RPortHelperGUI/AM2RPortHelperGUI/MainForm.cs b/AM2RPortHelperGUI/AM2RPortHelperGUI/MainForm.cs index 35d3deb..608f557 100644 --- a/AM2RPortHelperGUI/AM2RPortHelperGUI/MainForm.cs +++ b/AM2RPortHelperGUI/AM2RPortHelperGUI/MainForm.cs @@ -11,12 +11,26 @@ namespace AM2RPortHelperGUI; public partial class MainForm : Form { - // TODO: present icons so user can edit them! Also read them from config dir if they exist + private readonly string userIconPath = Core.ConfigDir + "/icon.png"; + private readonly string userSplashPath = Core.ConfigDir + "/splash.png"; + + private static byte[] GetByteArrayFromResource(string nameOfResource) + { + if (File.Exists(Core.ConfigDir + "/" + nameOfResource + ".png")) + return File.ReadAllBytes(Core.ConfigDir + "/" + nameOfResource + ".png"); + + return nameOfResource switch + { + nameof(Resources.icon) => Resources.icon, + nameof(Resources.splash) => Resources.splash, + _ => throw new InvalidDataException("Invalid Resource name given!") + }; + } + public MainForm() { Title = $"AM2RPortHelper - v{Core.Version}"; MinimumSize = new Size(260, 280); - var mainLayout = new DynamicLayout(); mainLayout.BeginVertical(); @@ -45,7 +59,21 @@ public partial class MainForm : Form mainLayout.BeginCentered(); mainLayout.AddRow(checkboxUseCustomSave); mainLayout.EndCentered(); + mainLayout.AddRow(new Label { Height = 5 }); + mainLayout.BeginCentered(); + mainLayout.AddRow(buttonEditIcon); + mainLayout.AddRow(new Label { Height = 5 }); + mainLayout.AddRow(imageViewIcon); + mainLayout.AddRow(new Label { Height = 5 }); + mainLayout.EndCentered(); mainLayout.AddSpace(); + mainLayout.AddRow(new Label { Height = 5 }); + mainLayout.BeginCentered(); + mainLayout.AddRow(buttonEditSplash); + mainLayout.AddRow(new Label { Height = 5 }); + mainLayout.AddRow(imageViewSplash); + mainLayout.AddRow(new Label { Height = 5 }); + mainLayout.EndCentered(); mainLayout.BeginVertical(); mainLayout.AddRange(new Label { Height = 10 }, buttonPort, null); mainLayout.EndVertical(); @@ -83,8 +111,29 @@ public partial class MainForm : Form checkboxUseCustomSave.TextChanged += ShouldButtonPortBeEnabled; filePicker.FilePathChanged += ShouldButtonPortBeEnabled; buttonPort.Click += ButtonPortOnClick; + buttonEditIcon.Click += ButtonEditIconClick; + buttonEditSplash.Click += ButtonEditSplashClick; } - + private void ButtonEditSplashClick(object sender, EventArgs e) + { + var dialog = new OpenFileDialog(); + if (dialog.ShowDialog(this) != DialogResult.Ok) + return; + + File.Copy(dialog.FileName, userSplashPath, true); + imageViewSplash.Image = new Bitmap(GetByteArrayFromResource(nameof(Resources.splash))); + } + private void ButtonEditIconClick(object sender, EventArgs e) + { + var dialog = new OpenFileDialog(); + if (dialog.ShowDialog(this) != DialogResult.Ok) + return; + + File.Copy(dialog.FileName, userIconPath, true); + + imageViewIcon.Image = new Bitmap(GetByteArrayFromResource(nameof(Resources.icon))); + } + // Helper functions private async void ButtonPortOnClick(object sender, EventArgs e) { @@ -97,12 +146,15 @@ public partial class MainForm : Form string androidPath = $"{currentDir}/{Path.GetFileNameWithoutExtension(modZipPath)}_ANDROID.apk"; string macPath = $"{currentDir}/{Path.GetFileNameWithoutExtension(modZipPath)}_MACOS.zip"; + string iconPath = RawMods.GetProperPathToBuiltinIcons(nameof(Resources.icon), userIconPath); + string splashPath = RawMods.GetProperPathToBuiltinIcons(nameof(Resources.splash), userSplashPath); + if (checkboxLinux.Checked.Value) { if (File.Exists(linuxPath)) File.Delete(linuxPath); - await Task.Run(() => RawMods.PortToLinux(modZipPath, linuxPath, null, null, OutputHandlerDelegate)); + await Task.Run(() => RawMods.PortToLinux(modZipPath, linuxPath, iconPath, splashPath, OutputHandlerDelegate)); } if (checkboxAndroid.Checked.Value) { @@ -111,7 +163,7 @@ public partial class MainForm : Form bool useCustomSave = checkboxUseCustomSave.Checked.Value; bool useInternet = checkboxAndroidRequiresInternet.Checked.Value; - await Task.Run(() => RawMods.PortToAndroid(modZipPath, androidPath, null, null, useCustomSave, useInternet, OutputHandlerDelegate)); + await Task.Run(() => RawMods.PortToAndroid(modZipPath, androidPath, iconPath, splashPath, useCustomSave, useInternet, OutputHandlerDelegate)); } if (checkboxMac.Checked.Value) { @@ -119,7 +171,7 @@ public partial class MainForm : Form File.Delete(macPath); string modName = checkboxUseCustomSave.Text; - await Task.Run(() => RawMods.PortToMac(modZipPath, macPath, null, null, OutputHandlerDelegate)); + await Task.Run(() => RawMods.PortToMac(modZipPath, macPath, iconPath, splashPath, OutputHandlerDelegate)); } labelProgress.Text = "Done!"; @@ -209,6 +261,26 @@ public partial class MainForm : Form ToolTip = "Only affects Android. Determines whether Android will use a custom save location based on its display name. If you don't " + "want your mod overwriting normal AM2R on Android, you should check this." }; + + private readonly ImageView imageViewIcon = new ImageView + { + Image = new Bitmap(GetByteArrayFromResource(nameof(Resources.icon))), + Size = new Size(64, 64) + }; + private readonly Button buttonEditIcon = new Button + { + Text = "Edit Icon:" + }; + + private readonly ImageView imageViewSplash = new ImageView + { + Image = new Bitmap(GetByteArrayFromResource(nameof(Resources.splash))), + Size = new Size(128, 96), + }; + private readonly Button buttonEditSplash = new Button + { + Text = "Edit Splash:" + }; private readonly Button buttonPort = new Button { diff --git a/AM2RPortHelperLib/Core.cs b/AM2RPortHelperLib/Core.cs index 837061a..243be72 100644 --- a/AM2RPortHelperLib/Core.cs +++ b/AM2RPortHelperLib/Core.cs @@ -5,7 +5,6 @@ public static class Core private static string ReturnAndCreateConfigDir() { string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.Create) + "/PortHelper/"; - Console.WriteLine(path); Directory.CreateDirectory(path); return path; } @@ -13,7 +12,7 @@ public static class Core /// /// The full path to the PortHelper's place in Configuration Application Data. /// - internal static readonly string ConfigDir = ReturnAndCreateConfigDir(); + public static readonly string ConfigDir = ReturnAndCreateConfigDir(); /// /// The current version of . diff --git a/AM2RPortHelperLib/RawMods.cs b/AM2RPortHelperLib/RawMods.cs index bf76ff1..d3bd75c 100644 --- a/AM2RPortHelperLib/RawMods.cs +++ b/AM2RPortHelperLib/RawMods.cs @@ -43,7 +43,7 @@ public abstract class RawMods : ModsBase /// /// /// - private static string GetProperPathToBuiltinIcons(string nameOfResource, string userIconPath) + public static string GetProperPathToBuiltinIcons(string nameOfResource, string userIconPath) { string SubCaseFunction(string resource) { diff --git a/AM2RPortHelperLib/Resources.Designer.cs b/AM2RPortHelperLib/Resources.Designer.cs index 333e613..8af4cb1 100644 --- a/AM2RPortHelperLib/Resources.Designer.cs +++ b/AM2RPortHelperLib/Resources.Designer.cs @@ -14,7 +14,7 @@ namespace AM2RPortHelperLib { [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [System.Diagnostics.DebuggerNonUserCodeAttribute()] [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { + public class Resources { private static System.Resources.ResourceManager resourceMan; @@ -48,7 +48,7 @@ namespace AM2RPortHelperLib { /// /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] icon { + public static byte[] icon { get { object obj = ResourceManager.GetObject("icon", resourceCulture); return ((byte[])(obj)); @@ -58,7 +58,7 @@ namespace AM2RPortHelperLib { /// /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] splash { + public static byte[] splash { get { object obj = ResourceManager.GetObject("splash", resourceCulture); return ((byte[])(obj)); @@ -68,7 +68,7 @@ namespace AM2RPortHelperLib { /// /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] splashAndroid { + public static byte[] splashAndroid { get { object obj = ResourceManager.GetObject("splashAndroid", resourceCulture); return ((byte[])(obj));