Implement Settings (#12)

* Add settings class

* Serialize settings to XML when settings window is closed

* Rename Settings class to Config

* Create functions for loading, saving and creating the default config

* Use the new functions to write ConfigXML to disk when settings window is closed

* Load config on startup + move default config from constructor to function

* Move Config out of XML Folder

* Implement saving and restoring field info

* Fix unnecessary object creation and XML Attribute names

* Save "SystemLanguage" option to config properly

* Load text dynamically + Choose proper language when "SystemLanguage" is selected

* Restore SystemLanguage setting properly + Make System Language the default

* Fix typo in English locale

* Change XmlRoot attributes to more descriptive ones

* Move Config saving when closing application to a separate method

* Move Config saving when closing Settings window to separate method

* Use path.combine properly

* Make LoadAndReturnConfig more concise

* Reset to SystemLanguage if trying to load a invalid language

* Enable Fill in fields by default

* Add documentation to Config.cs and FieldContents.cs
pull/16/head
LiveLM 3 years ago committed by GitHub
parent be653aae76
commit 65c70fa9be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -142,7 +142,7 @@
<value>System Language</value>
</data>
<data name="LanguageNotice" xml:space="preserve">
<value>Language (change requires a retart)</value>
<value>Language (change requires a restart)</value>
</data>
<data name="SettingsTitle" xml:space="preserve">
<value>Settings</value>
@ -159,4 +159,4 @@
<data name="FileMenu" xml:space="preserve">
<value>&amp;File</value>
</data>
</root>
</root>

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using Eto.Forms;
using Eto.Drawing;
@ -5,8 +6,11 @@ using AtomicLib.XML;
using System.IO;
using System.Net.Mime;
using System.Reflection;
using System.Threading;
using AtomicLib;
using Atomic.Language;
using System.Globalization;
using System.Linq;
namespace Atomic;
@ -56,7 +60,46 @@ public partial class ModPacker : Form
// loop through all resource files for test
//ResXResourceReader rsxr = new ResXResourceReader("items.resx");
currentConfig = Config.LoadAndReturnConfig();
if (!currentConfig.Language.Equals("SystemLanguage"))
{
CultureInfo language = CultureInfo.GetCultures(CultureTypes.AllCultures).FirstOrDefault(c => c.NativeName.ToLower().Contains(currentConfig.Language.ToLower()));
if (language is null) currentConfig.Language = "SystemLanguage";
else Thread.CurrentThread.CurrentUICulture = language;
}
nameLabel.Text = Text.ModName;
authorLabel.Text = Text.Author;
versionLabel.Text = Text.Version;
modNotesLabel.Text = Text.ModNotes;
customSaveCheckBox.Text = Text.UsesCustomSaves;
customSaveButton.Text = Text.SelectFolder;
musicCheckBox.Text = Text.UsesCustomMusic;
yycCheckBox.Text = Text.UsesYYC;
windowsCheckBox.Text = Text.SupportsOS.Replace("$1", Text.Windows);
windowsButton.Text = Text.LoadOSZip.Replace("$1", Text.Windows);
windowsLabel.Text = Text.OSGameLoaded.Replace("$1", Text.Windows);
apkCheckBox.Text = Text.BundleAndroid;
apkButton.Text = Text.LoadAndroidAPK;
apkLabel.Text = Text.AndroidLoaded;
linuxCheckBox.Text = Text.SupportsOS.Replace("$1", Text.Linux);
linuxButton.Text = Text.LoadOSZip.Replace("$1", Text.Linux);
linuxLabel.Text = Text.OSGameLoaded.Replace("$1", Text.Linux);
macCheckBox.Text = Text.SupportsOS.Replace("$1", Text.Mac);
macButton.Text = Text.LoadOSZip.Replace("$1", Text.Mac);
macLabel.Text = Text.OSGameLoaded.Replace("$1", Text.Mac);
originalZipButton.Text = Text.LoadAM2R11;
originalZipLabel.Text = Text.AM2R11Loaded;
createButton.Text = Text.CreateModPackage;
createLabel.Text = Text.ModPackageCreated;
Title = "Atomic v" + version;
Icon = new Icon(1f, new Bitmap(Resources.icon64));
@ -144,12 +187,29 @@ public partial class ModPacker : Form
customSaveCheckBox.CheckedChanged += CustomSaveCheckBoxChecked_Changed;
customSaveButton.Click += CustomSaveDataButton_Click;
yycCheckBox.CheckedChanged += YYCCheckBox_CheckedChanged;
this.Closing += ModPacker_Closing;
if (currentConfig.FillInContents && currentConfig.Fields != null)
{
nameTextBox.Text = currentConfig.Fields.ModName;
authorTextBox.Text = currentConfig.Fields.Author;
versionTextBox.Text = currentConfig.Fields.Version;
modNotesTextBox.Text = currentConfig.Fields.Notes;
customSaveCheckBox.Checked = currentConfig.Fields.UsesCustomSave;
customSaveTextBox.Text = currentConfig.Fields.CustomSaveDir;
musicCheckBox.Checked = currentConfig.Fields.UsesCustomMusic;
yycCheckBox.Checked = currentConfig.Fields.UsesYYC;
windowsCheckBox.Checked = currentConfig.Fields.SupportsWindows;
linuxCheckBox.Checked = currentConfig.Fields.SupportsLinux;
macCheckBox.Checked = currentConfig.Fields.SupportsMac;
apkCheckBox.Checked = currentConfig.Fields.SupportsAndroid;
}
// Menu items
var settings = new Command() { MenuText = Text.SettingsMenu, Shortcut = Application.Instance.CommonModifier | Application.Instance.AlternateModifier | Keys.P};
settings.Executed += (sender, args) =>
{
var settings = new SettingsForm();
var settings = new SettingsForm(currentConfig);
settings.ShowModal();
};
var quit = new Command() { MenuText = Text.QuitMenu, Shortcut = Application.Instance.CommonModifier | Keys.Q};
@ -159,43 +219,45 @@ public partial class ModPacker : Form
Menu = new MenuBar() {Items = { file }};
}
private Config currentConfig;
#region Design Elements
private Label nameLabel = new Label() { Text = Text.ModName };
private Label nameLabel = new Label();
private TextBox nameTextBox = new TextBox();
private Label authorLabel = new Label() { Text = Text.Author };
private Label authorLabel = new Label();
private TextBox authorTextBox = new TextBox();
private Label versionLabel = new Label() { Text = Text.Version };
private Label versionLabel = new Label();
private TextBox versionTextBox = new TextBox();
private Label modNotesLabel = new Label() { Text = Text.ModNotes };
private TextArea modNotesTextBox = new TextArea() { };
private Label modNotesLabel = new Label();
private TextArea modNotesTextBox = new TextArea();
private CheckBox customSaveCheckBox = new CheckBox() { Text = Text.UsesCustomSaves };
private Button customSaveButton = new Button() { Text = Text.SelectFolder, Enabled = false };
private CheckBox customSaveCheckBox = new CheckBox();
private Button customSaveButton = new Button() { Enabled = false };
// TODO: remove read only and make it correctly respond to user input
private TextBox customSaveTextBox = new TextBox() { ReadOnly = true };
private CheckBox musicCheckBox = new CheckBox() { Text = Text.UsesCustomMusic };
private CheckBox musicCheckBox = new CheckBox();
private CheckBox yycCheckBox = new CheckBox();
private CheckBox yycCheckBox = new CheckBox() { Text = Text.UsesYYC };
private CheckBox windowsCheckBox = new CheckBox();
private Button windowsButton = new Button() { Enabled = false };
private Label windowsLabel = new Label() { Visible = false };
private CheckBox windowsCheckBox = new CheckBox() { Text = Text.SupportsOS.Replace("$1", Text.Windows) };
private Button windowsButton = new Button() { Text = Text.LoadOSZip.Replace("$1", Text.Windows), Enabled = false };
private Label windowsLabel = new Label() { Text = Text.OSGameLoaded.Replace("$1", Text.Windows), Visible = false };
private CheckBox apkCheckBox = new CheckBox() { Text = Text.BundleAndroid };
private Button apkButton = new Button() { Text = Text.LoadAndroidAPK, Enabled = false };
private Label apkLabel = new Label() { Text = Text.AndroidLoaded, Visible = false };
private CheckBox apkCheckBox = new CheckBox();
private Button apkButton = new Button() { Enabled = false };
private Label apkLabel = new Label() { Visible = false };
private CheckBox linuxCheckBox = new CheckBox() { Text = Text.SupportsOS.Replace("$1", Text.Linux)};
private Button linuxButton = new Button() { Text = Text.LoadOSZip.Replace("$1", Text.Linux), Enabled = false };
private Label linuxLabel = new Label() { Text = Text.OSGameLoaded.Replace("$1", Text.Linux), Visible = false };
private CheckBox macCheckBox = new CheckBox() { Text = Text.SupportsOS.Replace("$1", Text.Mac) };
private Button macButton = new Button() { Text = Text.LoadOSZip.Replace("$1", Text.Mac), Enabled = false };
private Label macLabel = new Label() { Text = Text.OSGameLoaded.Replace("$1", Text.Mac), Visible = false };
private Button originalZipButton = new Button() { Text = Text.LoadAM2R11 };
private Label originalZipLabel = new Label() { Text = Text.AM2R11Loaded, Visible = false};
private Button createButton = new Button() { Text = Text.CreateModPackage, Enabled = false };
private Label createLabel = new Label() { Text = Text.ModPackageCreated, Visible = false};
private CheckBox linuxCheckBox = new CheckBox();
private Button linuxButton = new Button() { Enabled = false };
private Label linuxLabel = new Label() { Visible = false };
private CheckBox macCheckBox = new CheckBox();
private Button macButton = new Button() { Enabled = false };
private Label macLabel = new Label() { Visible = false };
private Button originalZipButton = new Button();
private Label originalZipLabel = new Label() { Visible = false };
private Button createButton = new Button() { Enabled = false };
private Label createLabel = new Label() { Visible = false };
#endregion
}

@ -259,6 +259,26 @@ public partial class ModPacker : Form
createLabel.Text = "Mod package(s) created!";
}
private void ModPacker_Closing(object sender, EventArgs e)
{
if (currentConfig.FillInContents)
{
currentConfig.Fields.ModName = nameTextBox.Text;
currentConfig.Fields.Author = authorTextBox.Text;
currentConfig.Fields.Version = versionTextBox.Text;
currentConfig.Fields.Notes = modNotesTextBox.Text;
currentConfig.Fields.UsesCustomSave = customSaveCheckBox.Checked.Value;
currentConfig.Fields.CustomSaveDir = customSaveTextBox.Text;
currentConfig.Fields.UsesCustomMusic = musicCheckBox.Checked.Value;
currentConfig.Fields.UsesYYC = yycCheckBox.Checked.Value;
currentConfig.Fields.SupportsWindows = windowsCheckBox.Checked.Value;
currentConfig.Fields.SupportsLinux = linuxCheckBox.Checked.Value;
currentConfig.Fields.SupportsMac = macCheckBox.Checked.Value;
currentConfig.Fields.SupportsAndroid = apkCheckBox.Checked.Value;
}
Config.SaveConfig(currentConfig);
}
private static string GetLocalizedStringOfOS(ProfileOperatingSystems os)
{
return os switch

@ -9,8 +9,10 @@ namespace Atomic;
public class SettingsForm : Dialog
{
public SettingsForm()
public SettingsForm(Config config)
{
currentConfig = config;
Title = Text.SettingsTitle;
Icon = new Icon(1f, new Bitmap(Resources.icon64));
Resizable = true;
@ -31,21 +33,29 @@ public class SettingsForm : Dialog
"中文(简体)"
};
var langdropDown = new DropDown() { DataStore = languageList };
langdropDown.SelectedIndexChanged += (sender, args) =>
{
// TODO: save new setting
};
languageDropDown = new DropDown() { DataStore = languageList };
languageDropDown.SelectedKey = currentConfig.Language == "SystemLanguage" ? Text.SystemLanguage : currentConfig.Language;
var fillInContents = new CheckBox() { Text = Text.RememberFields };
fillInContents.CheckedChanged += (sender, args) =>
{
// TODO: save new setting
};
fillInContents = new CheckBox() { Text = Text.RememberFields };
fillInContents.Checked = currentConfig.FillInContents;
layout.AddRange(Text.LanguageNotice, langdropDown, fillInContents);
this.Closing += SettingsForm_Closing;
layout.AddRange(Text.LanguageNotice, languageDropDown, fillInContents);
//layout.AddSpace();
Content = layout;
}
private void SettingsForm_Closing(object sender, EventArgs e)
{
currentConfig.Language = languageDropDown.SelectedKey == Text.SystemLanguage ? "SystemLanguage" : languageDropDown.SelectedKey;
currentConfig.FillInContents = fillInContents.Checked.Value;
Config.SaveConfig(currentConfig);
}
private Config currentConfig;
private DropDown languageDropDown;
private CheckBox fillInContents;
}

@ -0,0 +1,81 @@
using System.Xml.Serialization;
using AtomicLib.XML;
namespace AtomicLib;
/// <summary>
/// Class that handles saving and loading the modpacker configuration.
/// </summary>
[Serializable]
[XmlRoot("config")]
public class Config
{
public static string ConfigFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Atomic", "config.xml");
/// <summary>
/// Language used for the modpacker.
/// </summary>
[XmlAttribute("Language")]
public string Language
{ get; set; }
/// <summary>
/// Determines if the modpacker should remember information entered into the fields between usages.
/// </summary>
[XmlAttribute("FillInContents")]
public bool FillInContents
{ get; set; }
/// <summary>
/// Used to save information from the fields. Only used when <see cref="FillInContents"/> is <see langword="true"/>
/// </summary>
[XmlElement("Fields")]
public FieldContents Fields
{ get; set; }
public Config()
{
}
public Config(string language, bool fillIn)
{
Language = language;
FillInContents = fillIn;
Fields = new FieldContents();
}
/// <summary>
/// Reads the configuration from disk and returns a <see cref="Config"/> object. If the configuration does not exist, a default configuration will be created.
/// </summary>
/// <returns> Returns a <see cref="Config"/> object containing either the configuration read from disk or the default one.</returns>
public static Config LoadAndReturnConfig()
{
if (!File.Exists(ConfigFilePath))
return CreateAndReturnDefaultConfig();
return Serializer.Deserialize<Config>(File.ReadAllText(ConfigFilePath));
}
/// <summary>
/// Saves a default configuration to disk and returns it, creating the config folders if necessary.
/// </summary>
/// <returns> Returns the <see cref="Config"/> object.</returns>
public static Config CreateAndReturnDefaultConfig()
{
Directory.CreateDirectory(Path.GetDirectoryName(ConfigFilePath));
Config defaultConfig = new Config("SystemLanguage", true);
SaveConfig(defaultConfig);
return defaultConfig;
}
/// <summary>
/// Writes the <see cref="Config"/> to disk.
/// </summary>
/// <param name="config">The <see cref="Config"/> that should be saved to the disk.</param>
public static void SaveConfig(Config config)
{
string xmlOutput = Serializer.Serialize<Config>(config);
File.WriteAllText(ConfigFilePath, xmlOutput);
}
}

@ -0,0 +1,68 @@
using System.Reflection;
using System.Xml.Serialization;
using AtomicLib.XML;
namespace AtomicLib;
/// <summary>
/// Class that handles how field information is saved as XML.
/// </summary>
[Serializable]
[XmlRoot("fieldcontents")]
public class FieldContents
{
/// <summary>The text entered into a field for the mod name.</summary>
[XmlAttribute("ModName")]
public string ModName
{ get; set; }
/// <summary>The text entered into a field for the mod author.</summary>
[XmlAttribute("Author")]
public string Author
{ get; set; }
/// <summary>The text entered into a field for the mod version.</summary>
[XmlAttribute("Version")]
public string Version
{ get; set; }
/// <summary>The text entered into a field for the mod notes.</summary>
[XmlAttribute("Notes")]
public string Notes
{ get; set; }
/// <summary>The checkbox that indicates if the mod uses custom saves.</summary>
[XmlAttribute("UsesCustomSave")]
public bool UsesCustomSave
{ get; set; }
/// <summary>The text that indicates the path used to store the mod's custom saves.</summary>
[XmlAttribute("CustomSaveDir")]
public string CustomSaveDir
{ get; set; }
/// <summary>The checkbox that indicates if the mod uses custom music.</summary>
[XmlAttribute("UsesCustomMusic")]
public bool UsesCustomMusic
{ get; set; }
/// <summary>The checkbox that indicates if the mod uses the YoYo Compiler.</summary>
[XmlAttribute("UsesYYC")]
public bool UsesYYC
{ get; set; }
/// <summary>The checkbox that indicates if the mod supports Windows</summary>
[XmlAttribute("SupportsWindows")]
public bool SupportsWindows
{ get; set; }
/// <summary>The checkbox that indicates if the mod supports Linux</summary>
[XmlAttribute("SupportsLinux")]
public bool SupportsLinux
{ get; set; }
/// <summary>The checkbox that indicates if the mod supports Mac</summary>
[XmlAttribute("SupportsMac")]
public bool SupportsMac
{ get; set; }
/// <summary>The checkbox that indicates if the mod supports Android</summary>
[XmlAttribute("SupportsAndroid")]
public bool SupportsAndroid
{ get; set; }
public FieldContents()
{
}
}
Loading…
Cancel
Save