diff --git a/src/DesktopMagic/Helpers/SettingElementGenerator.cs b/src/DesktopMagic/Helpers/SettingElementGenerator.cs index c21acd7..dd236d6 100644 --- a/src/DesktopMagic/Helpers/SettingElementGenerator.cs +++ b/src/DesktopMagic/Helpers/SettingElementGenerator.cs @@ -1,14 +1,18 @@ -using DesktopMagic.Plugins; +using DesktopMagic.Dialogs; +using DesktopMagic.Plugins; + +using Microsoft.Win32; using System; using System.Windows; using System.Windows.Controls; +using System.Windows.Media; namespace DesktopMagic.Helpers; internal class SettingElementGenerator(uint pluginId) { - public Control? Generate(SettingElement settingElement, System.Windows.Controls.TextBlock textBlock) + public FrameworkElement? Generate(SettingElement settingElement, System.Windows.Controls.TextBlock textBlock) { if (settingElement.Input is DesktopMagic.Api.Settings.Label eLabel) { @@ -215,6 +219,148 @@ internal class SettingElementGenerator(uint pluginId) return comboBox; } + else if (settingElement.Input is DesktopMagic.Api.Settings.ColorPicker eColorPicker) + { + Grid panel = new() + { + HorizontalAlignment = HorizontalAlignment.Stretch + }; + panel.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); + panel.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); + + Border colorPreview = new() + { + Width = 30, + Height = 30, + CornerRadius = new CornerRadius(4), + Background = new SolidColorBrush(Color.FromArgb(eColorPicker.Value.A, eColorPicker.Value.R, eColorPicker.Value.G, eColorPicker.Value.B)), + Margin = new Thickness(0, 0, 10, 0), + BorderBrush = Application.Current.FindResource("ControlElevationBorderBrush") as Brush, + BorderThickness = new Thickness(1) + }; + Grid.SetColumn(colorPreview, 0); + + Wpf.Ui.Controls.Button browseButton = new() + { + Content = "Select Color", + VerticalAlignment = VerticalAlignment.Center, + HorizontalAlignment = HorizontalAlignment.Stretch + }; + Grid.SetColumn(browseButton, 1); + + browseButton.Click += (_s, _e) => + { + try + { + ColorDialog colorDialog = new("Select a color", eColorPicker.Value) + { + Owner = Application.Current.MainWindow + }; + + if (colorDialog.ShowDialog() == true) + { + eColorPicker.Value = colorDialog.ResultColor; + colorPreview.Background = new SolidColorBrush(Color.FromArgb(eColorPicker.Value.A, eColorPicker.Value.R, eColorPicker.Value.G, eColorPicker.Value.B)); + } + } + catch (Exception ex) + { + DisplayException(ex.Message); + } + }; + + eColorPicker.OnValueChanged += () => + { + colorPreview.Dispatcher.Invoke(() => + { + colorPreview.Background = new SolidColorBrush(Color.FromArgb(eColorPicker.Value.A, eColorPicker.Value.R, eColorPicker.Value.G, eColorPicker.Value.B)); + }); + }; + + _ = panel.Children.Add(colorPreview); + _ = panel.Children.Add(browseButton); + + return panel; + } + else if (settingElement.Input is DesktopMagic.Api.Settings.FileSelector eFileSelector) + { + Grid grid = new() + { + HorizontalAlignment = HorizontalAlignment.Stretch + }; + grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); + grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); + + Wpf.Ui.Controls.TextBox pathTextBox = new() + { + Text = eFileSelector.Value, + IsReadOnly = true, + VerticalAlignment = VerticalAlignment.Center, + HorizontalAlignment = HorizontalAlignment.Stretch, + Margin = new Thickness(0, 0, 5, 0) + }; + Grid.SetColumn(pathTextBox, 0); + + Wpf.Ui.Controls.Button browseButton = new() + { + Content = "Browse", + VerticalAlignment = VerticalAlignment.Center + }; + Grid.SetColumn(browseButton, 1); + + browseButton.Click += (_s, _e) => + { + try + { + if (eFileSelector.SelectFolder) + { + OpenFolderDialog folderDialog = new() + { + Title = eFileSelector.Title, + InitialDirectory = string.IsNullOrEmpty(eFileSelector.Value) ? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) : System.IO.Path.GetDirectoryName(eFileSelector.Value) + }; + + if (folderDialog.ShowDialog() == true) + { + eFileSelector.Value = folderDialog.FolderName; + pathTextBox.Text = eFileSelector.Value; + } + } + else + { + OpenFileDialog fileDialog = new() + { + Title = eFileSelector.Title, + Filter = eFileSelector.Filter, + InitialDirectory = string.IsNullOrEmpty(eFileSelector.Value) ? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) : System.IO.Path.GetDirectoryName(eFileSelector.Value) + }; + + if (fileDialog.ShowDialog() == true) + { + eFileSelector.Value = fileDialog.FileName; + pathTextBox.Text = eFileSelector.Value; + } + } + } + catch (Exception ex) + { + DisplayException(ex.Message); + } + }; + + eFileSelector.OnValueChanged += () => + { + pathTextBox.Dispatcher.Invoke(() => + { + pathTextBox.Text = eFileSelector.Value; + }); + }; + + _ = grid.Children.Add(pathTextBox); + _ = grid.Children.Add(browseButton); + + return grid; + } return null; } diff --git a/src/DesktopMagic/Pages/MainPage.xaml.cs b/src/DesktopMagic/Pages/MainPage.xaml.cs index a199ceb..0b01fc9 100644 --- a/src/DesktopMagic/Pages/MainPage.xaml.cs +++ b/src/DesktopMagic/Pages/MainPage.xaml.cs @@ -267,7 +267,7 @@ public partial class MainPage : Page _ = optionsPanel.Children.Add(card); - Control? control = settingElementGenerator.Generate(settingElement, textBlock); + FrameworkElement? control = settingElementGenerator.Generate(settingElement, textBlock); if (control is not null) { diff --git a/src/DesktopMagicPluginAPI/Settings/ColorPicker.cs b/src/DesktopMagicPluginAPI/Settings/ColorPicker.cs new file mode 100644 index 0000000..ada24ee --- /dev/null +++ b/src/DesktopMagicPluginAPI/Settings/ColorPicker.cs @@ -0,0 +1,62 @@ +using System.Drawing; +using System.Globalization; + +namespace DesktopMagic.Api.Settings; + +/// +/// Represents a color picker control. +/// +public sealed class ColorPicker : Setting +{ + private Color _value; + + /// + /// Gets or sets the color value assigned to the element. + /// + public Color Value + { + get => _value; + set + { + if (_value != value) + { + _value = value; + ValueChanged(); + } + } + } + + /// + /// Initializes a new instance of the class with the provided . + /// + /// The default color value. + public ColorPicker(Color defaultColor) + { + _value = defaultColor; + } + + /// + /// Initializes a new instance of the class with a default color of White. + /// + public ColorPicker() : this(Color.White) + { + } + + internal override string GetJsonValue() + { + return $"{Value.A},{Value.R},{Value.G},{Value.B}"; + } + + internal override void SetJsonValue(string value) + { + string[] parts = value.Split(','); + if (parts.Length == 4 && + byte.TryParse(parts[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out byte a) && + byte.TryParse(parts[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out byte r) && + byte.TryParse(parts[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out byte g) && + byte.TryParse(parts[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out byte b)) + { + Value = Color.FromArgb(a, r, g, b); + } + } +} diff --git a/src/DesktopMagicPluginAPI/Settings/FileSelector.cs b/src/DesktopMagicPluginAPI/Settings/FileSelector.cs new file mode 100644 index 0000000..0fde70a --- /dev/null +++ b/src/DesktopMagicPluginAPI/Settings/FileSelector.cs @@ -0,0 +1,65 @@ +namespace DesktopMagic.Api.Settings; + +/// +/// Represents a file selector control that allows the user to browse for a file. +/// +public sealed class FileSelector : Setting +{ + private string _value = string.Empty; + + /// + /// Gets or sets the selected file path. + /// + public string Value + { + get => _value; + set + { + if (_value != value) + { + _value = value; + ValueChanged(); + } + } + } + + /// + /// Gets or sets the file filter for the file dialog (e.g., "Image Files|*.png;*.jpg|All Files|*.*"). + /// + public string Filter { get; set; } + + /// + /// Gets or sets the title of the file dialog. + /// + public string Title { get; set; } + + /// + /// Gets or sets a value indicating whether the file selector should select folders instead of files. + /// + public bool SelectFolder { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The default file path. + /// The file filter for the file dialog. + /// The title of the file dialog. + /// If true, selects folders instead of files. + public FileSelector(string defaultPath = "", string filter = "All Files|*.*", string title = "Select File", bool selectFolder = false) + { + _value = defaultPath; + Filter = filter; + Title = title; + SelectFolder = selectFolder; + } + + internal override string GetJsonValue() + { + return Value; + } + + internal override void SetJsonValue(string value) + { + Value = value; + } +}