diff --git a/MaxSlurper/MainWindow.xaml b/MaxSlurper/MainWindow.xaml index 70fc34a..a2d0f5a 100644 --- a/MaxSlurper/MainWindow.xaml +++ b/MaxSlurper/MainWindow.xaml @@ -112,63 +112,80 @@ Padding="16,8" - - - - + + + + + + + + + + - - + + - + - - - - - + + + - + - - - - - - - + + + + + + + diff --git a/MaxSlurper/Services/SettingsService.cs b/MaxSlurper/Services/SettingsService.cs index 9029c76..b349344 100644 --- a/MaxSlurper/Services/SettingsService.cs +++ b/MaxSlurper/Services/SettingsService.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text.Json; using System.Windows.Input; using MaxSlurper.Models; @@ -10,11 +12,14 @@ namespace MaxSlurper.Services { AppSettings LoadSettings(); void SaveSettings(AppSettings settings); + List LoadHistory(); + void SaveHistory(IEnumerable history); } public class SettingsService : ISettingsService { private readonly string _settingsPath; + private readonly string _historyPath; public SettingsService() { @@ -22,6 +27,7 @@ namespace MaxSlurper.Services var appFolder = Path.Combine(appData, "MaxSlurper"); Directory.CreateDirectory(appFolder); _settingsPath = Path.Combine(appFolder, "settings.json"); + _historyPath = Path.Combine(appFolder, "history.json"); } public AppSettings LoadSettings() @@ -94,10 +100,52 @@ var json = File.ReadAllText(_settingsPath); catch { } } + public List LoadHistory() + { + try + { + if (File.Exists(_historyPath)) + { + var json = File.ReadAllText(_historyPath); + var items = JsonSerializer.Deserialize>(json); + if (items != null) + { + return items.Select(e => + { + var item = new ColorItem { R = e.R, G = e.G, B = e.B }; + item.UpdateDerived(); + return item; + }).ToList(); + } + } + } + catch { } + + return new List(); + } + + public void SaveHistory(IEnumerable history) + { + try + { + var entries = history.Select(c => new HistoryEntry { R = c.R, G = c.G, B = c.B }).ToList(); + var json = JsonSerializer.Serialize(entries, new JsonSerializerOptions { WriteIndented = true }); + File.WriteAllText(_historyPath, json); + } + catch { } + } + private class SettingsData { public string[]? HotkeyModifiers { get; set; } public string? HotkeyKey { get; set; } } + + private class HistoryEntry + { + public byte R { get; set; } + public byte G { get; set; } + public byte B { get; set; } + } } } diff --git a/MaxSlurper/ViewModels/MainViewModel.cs b/MaxSlurper/ViewModels/MainViewModel.cs index a432c36..d49f33b 100644 --- a/MaxSlurper/ViewModels/MainViewModel.cs +++ b/MaxSlurper/ViewModels/MainViewModel.cs @@ -38,6 +38,7 @@ namespace MaxSlurper.ViewModels public ICommand PickColorCommand { get; } public ICommand ClearHistoryCommand { get; } + public ICommand RemoveColorCommand { get; } public ICommand CopyHexCommand { get; } public ICommand OpenColorPickerCommand { get; } public ICommand OpenSettingsCommand { get; } @@ -51,10 +52,18 @@ namespace MaxSlurper.ViewModels Settings = _settingsService.LoadSettings(); PickColorCommand = new RelayCommand(async _ => await PickColor()); - ClearHistoryCommand = new RelayCommand(_ => ClearHistory()); + ClearHistoryCommand = new RelayCommand(_ => ClearHistory(), _ => History.Count > 0); + RemoveColorCommand = new RelayCommand(RemoveColor, _ => _ is ColorItem); CopyHexCommand = new RelayCommand(CopyHex, _ => Selected != null || _ is ColorItem); OpenColorPickerCommand = new RelayCommand(_ => OpenColorPicker()); OpenSettingsCommand = new RelayCommand(_ => OpenSettings()); + + // Restore persisted history + foreach (var item in _settingsService.LoadHistory()) + History.Add(item); + + if (History.Count > 0) + Selected = History[0]; } public System.Action? OnSettingsChanged { get; set; } @@ -79,6 +88,8 @@ namespace MaxSlurper.ViewModels Selected = item; System.Windows.Clipboard.SetText(item.Hex); + _settingsService.SaveHistory(History); + ((RelayCommand)ClearHistoryCommand).RaiseCanExecuteChanged(); } private void OpenColorPicker() @@ -104,6 +115,8 @@ namespace MaxSlurper.ViewModels Selected = item; System.Windows.Clipboard.SetText(item.Hex); + _settingsService.SaveHistory(History); + ((RelayCommand)ClearHistoryCommand).RaiseCanExecuteChanged(); } } @@ -119,6 +132,23 @@ namespace MaxSlurper.ViewModels private void ClearHistory() { History.Clear(); + Selected = null; + _settingsService.SaveHistory(History); + ((RelayCommand)ClearHistoryCommand).RaiseCanExecuteChanged(); + } + + private void RemoveColor(object? parameter) + { + if (parameter is not ColorItem item) return; + + var wasSelected = item == Selected; + History.Remove(item); + + if (wasSelected) + Selected = History.Count > 0 ? History[0] : null; + + _settingsService.SaveHistory(History); + ((RelayCommand)ClearHistoryCommand).RaiseCanExecuteChanged(); } private void CopyHex(object? parameter) @@ -136,7 +166,13 @@ namespace MaxSlurper.ViewModels private void UpdateSelected() { - if (Selected == null) return; + if (Selected == null) + { + SelectedColorBrush = System.Windows.Media.Brushes.White; + SelectedHex = "#FFFFFF"; + SelectedRgb = "255,255,255"; + return; + } SelectedColorBrush = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(Selected.R, Selected.G, Selected.B)); SelectedHex = Selected.Hex; SelectedRgb = Selected.Rgb;