add remove button
This commit is contained in:
@@ -112,54 +112,71 @@ Padding="16,8"
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Margin="0,0,0,12">
|
||||
<DockPanel Grid.Row="0" Margin="0,0,0,12">
|
||||
<ui:Button DockPanel.Dock="Right"
|
||||
Content="Verlauf löschen"
|
||||
Appearance="Secondary"
|
||||
Icon="{ui:SymbolIcon Delete24}"
|
||||
Command="{Binding ClearHistoryCommand}"
|
||||
Padding="8,4"
|
||||
VerticalAlignment="Center" />
|
||||
<StackPanel>
|
||||
<TextBlock Text="Farbverlauf"
|
||||
Style="{StaticResource HeaderText}" />
|
||||
<TextBlock Text="Klicken zum Kopieren"
|
||||
Style="{StaticResource SubtleText}"
|
||||
Margin="0,4,0,0" />
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
|
||||
<ScrollViewer Grid.Row="1"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
<ItemsControl ItemsSource="{Binding History}">
|
||||
<ItemsControl.ItemContainerStyle>
|
||||
<Style TargetType="ContentPresenter">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
</Style>
|
||||
</ItemsControl.ItemContainerStyle>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ui:CardControl Margin="0,0,0,8"
|
||||
Padding="8"
|
||||
<ui:Card Margin="0,0,0,8"
|
||||
Padding="12"
|
||||
Cursor="Hand"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Left">
|
||||
<ui:CardControl.InputBindings>
|
||||
HorizontalAlignment="Stretch">
|
||||
<ui:Card.InputBindings>
|
||||
<MouseBinding MouseAction="LeftClick"
|
||||
Command="{Binding DataContext.CopyHexCommand, RelativeSource={RelativeSource AncestorType=ui:FluentWindow}}"
|
||||
CommandParameter="{Binding}" />
|
||||
</ui:CardControl.InputBindings>
|
||||
</ui:Card.InputBindings>
|
||||
|
||||
<Grid HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<DockPanel LastChildFill="True">
|
||||
<!-- Delete button pinned to the right -->
|
||||
<ui:Button DockPanel.Dock="Right"
|
||||
Icon="{ui:SymbolIcon Dismiss24}"
|
||||
Appearance="Secondary"
|
||||
ToolTip="Farbe entfernen"
|
||||
Command="{Binding DataContext.RemoveColorCommand, RelativeSource={RelativeSource AncestorType=ui:FluentWindow}}"
|
||||
CommandParameter="{Binding}"
|
||||
Padding="6"
|
||||
Margin="8,0,0,0"
|
||||
VerticalAlignment="Center" />
|
||||
|
||||
<!-- Color preview on the left -->
|
||||
<Border Width="48"
|
||||
<Border DockPanel.Dock="Left"
|
||||
Width="48"
|
||||
Height="48"
|
||||
Background="{Binding Brush}"
|
||||
CornerRadius="8"
|
||||
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left" />
|
||||
VerticalAlignment="Center" />
|
||||
|
||||
<!-- Text info in the middle -->
|
||||
<StackPanel Grid.Column="1"
|
||||
Margin="12,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left">
|
||||
<!-- Text info fills the middle -->
|
||||
<StackPanel Margin="12,0,0,0"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding Hex}"
|
||||
FontWeight="Medium"
|
||||
FontWeight="Medium"
|
||||
FontSize="15"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
|
||||
<TextBlock Text="{Binding Rgb}"
|
||||
@@ -167,8 +184,8 @@ FontWeight="Medium"
|
||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||
Margin="0,2,0,0" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ui:CardControl>
|
||||
</DockPanel>
|
||||
</ui:Card>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
@@ -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<ColorItem> LoadHistory();
|
||||
void SaveHistory(IEnumerable<ColorItem> 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<ColorItem> LoadHistory()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(_historyPath))
|
||||
{
|
||||
var json = File.ReadAllText(_historyPath);
|
||||
var items = JsonSerializer.Deserialize<List<HistoryEntry>>(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<ColorItem>();
|
||||
}
|
||||
|
||||
public void SaveHistory(IEnumerable<ColorItem> 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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<AppSettings>? 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;
|
||||
|
||||
Reference in New Issue
Block a user