diff --git a/DiscordBotCore/Others/SettingsDictionary.cs b/DiscordBotCore/Others/SettingsDictionary.cs index 4b37118..2e6356d 100644 --- a/DiscordBotCore/Others/SettingsDictionary.cs +++ b/DiscordBotCore/Others/SettingsDictionary.cs @@ -35,7 +35,8 @@ public class SettingsDictionary if(!File.Exists(_File)) { _Dictionary = new Dictionary(); - return false; + await SaveToFile(); + return true; } string fileAsText = await File.ReadAllTextAsync(_File); diff --git a/DiscordBotUI/Config.cs b/DiscordBotUI/Config.cs new file mode 100644 index 0000000..790c7cf --- /dev/null +++ b/DiscordBotUI/Config.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DiscordBotUI_Windows +{ + internal class Config + { + internal static DiscordBotCore.Others.SettingsDictionary ApplicationSettings = new DiscordBotCore.Others.SettingsDictionary(Path.Combine(DiscordBotCore.Application.CurrentApplication.DataFolder, "DiscordBotUI/config.json")); + internal static ThemeManager ThemeManager = new ThemeManager(); + } +} diff --git a/DiscordBotUI/Program.cs b/DiscordBotUI/Program.cs index a486818..97c5184 100644 --- a/DiscordBotUI/Program.cs +++ b/DiscordBotUI/Program.cs @@ -4,6 +4,7 @@ using DiscordBotCore.Interfaces; using DiscordBotCore.Others; using DiscordBotCore.Others.Actions; +using DiscordBotUI_Windows; using DiscordBotUI_Windows.WindowsForms; namespace DiscordBotUI @@ -16,11 +17,23 @@ namespace DiscordBotUI public bool RequireOtherThread => true; public string Description => "Discord UI desc"; - public void Start(DiscordSocketClient client) + public async void Start(DiscordSocketClient client) { + await Config.ApplicationSettings.LoadFromFile(); + + await Config.ThemeManager.LoadThemesFromThemesFolder(); + + if (Config.ApplicationSettings.ContainsKey("AppTheme")) + { + Config.ThemeManager.SetTheme(Config.ApplicationSettings["AppTheme"]); + } else Config.ApplicationSettings.Add("AppTheme", "Default"); + Thread thread = new Thread(() => { - Application.Run(new MainWindow()); + MainWindow mainWindow = new MainWindow(); + Config.ThemeManager.SetFormTheme(Config.ThemeManager.CurrentTheme, mainWindow); + Application.Run(mainWindow); + }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); @@ -41,25 +54,79 @@ namespace DiscordBotUI public InternalActionRunType RunType => InternalActionRunType.ON_CALL; - public Task Execute(string[]? args) + public async Task Execute(string[]? args) { if(args == null || args.Length == 0) { Console.WriteLine("Please provide an option"); - return Task.CompletedTask; + return; + } + + + + if (args[0] == "theme") + { + if (args.Length == 1) + { + Console.WriteLine("Please provide a theme name"); + return; + } + + if(args[1] == "save") + { + if (args.Length == 2) + { + Console.WriteLine("Please provide a theme name"); + return; + } + + await Config.ThemeManager.SaveThemeToFile(args[2]); + Console.WriteLine("Theme saved"); + } + + if(args[1] == "set") + { + if (args.Length == 2) + { + Console.WriteLine("Please provide a theme name"); + return; + } + + Config.ThemeManager.SetTheme(args[2]); + } + + if (args[1] == "list") + { + foreach (var theme in Config.ThemeManager._InstalledThemes) + { + Console.WriteLine(theme.Name); + } + } + + return; } if(args[0] == "start") { + await Config.ApplicationSettings.LoadFromFile(); + + await Config.ThemeManager.LoadThemesFromThemesFolder(); + + if (Config.ApplicationSettings.ContainsKey("AppTheme")) + { + Config.ThemeManager.SetTheme(Config.ApplicationSettings["AppTheme"]); + } + Thread thread = new Thread(() => { - Application.Run(new MainWindow()); + MainWindow mainWindow = new MainWindow(); + Config.ThemeManager.SetFormTheme(Config.ThemeManager.CurrentTheme, mainWindow); + Application.Run(mainWindow); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } - return Task.CompletedTask; } } } \ No newline at end of file diff --git a/DiscordBotUI/ThemeManager.cs b/DiscordBotUI/ThemeManager.cs new file mode 100644 index 0000000..5e32b95 --- /dev/null +++ b/DiscordBotUI/ThemeManager.cs @@ -0,0 +1,115 @@ +using DiscordBotUI_Windows.Theming; + +namespace DiscordBotUI_Windows +{ + internal class ThemeManager + { + private readonly string _ThemesFolder = "DiscordBotUI/Themes"; + private readonly Theme _DefaultTheme = new Theme + { + Name = "Default", + Description = "Default theme", + Type = ThemeType.Undefined, + ThemeValues = new Dictionary + { + { "BackgroundColor", "#36393F" }, + { "TextColor", "#000000" } + } + }; + + internal Theme CurrentTheme { get; private set; } + + internal IList _InstalledThemes { get; private set; } + + internal ThemeManager() + { + _InstalledThemes = new List(); + CurrentTheme = _DefaultTheme; + } + + private void SetControlTheme(Control control, Theme theme, bool doChildToo) + { + + control.BackColor = ColorTranslator.FromHtml(theme.ThemeValues["BackgroundColor"]); + control.ForeColor = ColorTranslator.FromHtml(theme.ThemeValues["TextColor"]); + + // Fix for data grid view + if (control is DataGridView dataGridView) + { + dataGridView.BackgroundColor = control.BackColor; + dataGridView.DefaultCellStyle.BackColor = control.BackColor; + dataGridView.DefaultCellStyle.ForeColor = control.ForeColor; + dataGridView.DefaultCellStyle.SelectionBackColor = control.BackColor; + dataGridView.DefaultCellStyle.SelectionForeColor = control.ForeColor; + + dataGridView.ColumnHeadersDefaultCellStyle.BackColor = control.BackColor; + dataGridView.ColumnHeadersDefaultCellStyle.ForeColor = control.ForeColor; + dataGridView.ColumnHeadersDefaultCellStyle.SelectionBackColor = control.BackColor; + dataGridView.ColumnHeadersDefaultCellStyle.SelectionForeColor = control.ForeColor; + + } + + + + if (doChildToo) + { + foreach (Control childControl in control.Controls) + { + SetControlTheme(childControl, theme, true); + } + } + } + + internal void SetFormTheme(Theme theme, Form windowsForm) + { + CurrentTheme = theme; + SetControlTheme(windowsForm, theme, true); + Config.ApplicationSettings["AppTheme"] = theme.Name; + } + + internal void SetTheme(string themeName) + { + CurrentTheme = _InstalledThemes.FirstOrDefault(x => x.Name == themeName, _DefaultTheme); + Config.ApplicationSettings["AppTheme"] = themeName; + + } + + private async Task LoadThemeFromFile(string fileName) + { + return await DiscordBotCore.Others.JsonManager.ConvertFromJson(fileName); + } + + internal async Task SaveThemeToFile(string themeName) + { + Theme? theme = _InstalledThemes.FirstOrDefault(x => x.Name == themeName); + if (theme == null) + throw new Exception("Theme not found"); + + string basefolderPath = Path.Combine(DiscordBotCore.Application.CurrentApplication.DataFolder, _ThemesFolder); + Directory.CreateDirectory(basefolderPath); + string filePath = Path.Combine(basefolderPath, $"{themeName}.json"); + await DiscordBotCore.Others.JsonManager.SaveToJsonFile(filePath, theme); + } + + internal async Task LoadThemesFromThemesFolder() + { + string basefolderPath = Path.Combine(DiscordBotCore.Application.CurrentApplication.DataFolder, _ThemesFolder); + Directory.CreateDirectory(basefolderPath); + var files = Directory.GetFiles(basefolderPath, "*.json"); + _InstalledThemes.Clear(); + if(files.Length == 0) + { + _InstalledThemes.Add(_DefaultTheme); + return 1; + } + + foreach (var file in files) + { + var theme = await LoadThemeFromFile(file); + _InstalledThemes.Add(theme); + } + + return _InstalledThemes.Count; + } + } +} diff --git a/DiscordBotUI/Theming/Theme.cs b/DiscordBotUI/Theming/Theme.cs new file mode 100644 index 0000000..5314b42 --- /dev/null +++ b/DiscordBotUI/Theming/Theme.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace DiscordBotUI_Windows.Theming +{ + internal class Theme + { + public string Name { get; set; } + public string Description { get; set; } + public ThemeType Type { get; set; } + public IDictionary ThemeValues { get; set; } + + internal void SetThemeValue(string key, string value) + { + if (ThemeValues.ContainsKey(key)) + { + ThemeValues[key] = value; + } + } + } +} diff --git a/DiscordBotUI/Theming/ThemeType.cs b/DiscordBotUI/Theming/ThemeType.cs new file mode 100644 index 0000000..4c32333 --- /dev/null +++ b/DiscordBotUI/Theming/ThemeType.cs @@ -0,0 +1,9 @@ +namespace DiscordBotUI_Windows.Theming +{ + public enum ThemeType + { + Undefined, + Light, + Dark + } +} diff --git a/DiscordBotUI/WindowsForms/MainWindow.Designer.cs b/DiscordBotUI/WindowsForms/MainWindow.Designer.cs index 53cf601..d43b0a8 100644 --- a/DiscordBotUI/WindowsForms/MainWindow.Designer.cs +++ b/DiscordBotUI/WindowsForms/MainWindow.Designer.cs @@ -30,12 +30,13 @@ { menuStrip1 = new MenuStrip(); pluginListToolStripMenuItem = new ToolStripMenuItem(); + themesToolStripMenuItem = new ToolStripMenuItem(); menuStrip1.SuspendLayout(); SuspendLayout(); // // menuStrip1 // - menuStrip1.Items.AddRange(new ToolStripItem[] { pluginListToolStripMenuItem }); + menuStrip1.Items.AddRange(new ToolStripItem[] { pluginListToolStripMenuItem, themesToolStripMenuItem }); menuStrip1.Location = new Point(0, 0); menuStrip1.Name = "menuStrip1"; menuStrip1.Size = new Size(800, 24); @@ -48,6 +49,12 @@ pluginListToolStripMenuItem.Size = new Size(74, 20); pluginListToolStripMenuItem.Text = "Plugin List"; // + // themesToolStripMenuItem + // + themesToolStripMenuItem.Name = "themesToolStripMenuItem"; + themesToolStripMenuItem.Size = new Size(60, 20); + themesToolStripMenuItem.Text = "Themes"; + // // MainWindow // AutoScaleDimensions = new SizeF(7F, 15F); @@ -67,5 +74,6 @@ private MenuStrip menuStrip1; private ToolStripMenuItem pluginListToolStripMenuItem; + private ToolStripMenuItem themesToolStripMenuItem; } } \ No newline at end of file diff --git a/DiscordBotUI/WindowsForms/MainWindow.cs b/DiscordBotUI/WindowsForms/MainWindow.cs index 1473371..a6d224f 100644 --- a/DiscordBotUI/WindowsForms/MainWindow.cs +++ b/DiscordBotUI/WindowsForms/MainWindow.cs @@ -1,27 +1,32 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace DiscordBotUI_Windows.WindowsForms +namespace DiscordBotUI_Windows.WindowsForms { public partial class MainWindow : Form { - public MainWindow() + internal MainWindow() { InitializeComponent(); - Load += (_, _) => MainWindowLoad(); + FormClosed += async (_, _) => + { + await Config.ApplicationSettings.SaveToFile(); + }; } private void MainWindowLoad() { - pluginListToolStripMenuItem.Click += (_, _) => new PluginListWindow().Show(); + pluginListToolStripMenuItem.Click += (_, _) => + { + var form = new PluginListWindow(); + Config.ThemeManager.SetFormTheme(Config.ThemeManager.CurrentTheme, form); + form.Show(); + }; + themesToolStripMenuItem.Click += (_, _) => { + themesToolStripMenuItem.DropDownItems.Clear(); + foreach(var theme in Config.ThemeManager._InstalledThemes) + { + themesToolStripMenuItem.DropDownItems.Add(theme.Name, null, (_, _) => Config.ThemeManager.SetFormTheme(theme, this)); + } + }; } } }