add remove button
This commit is contained in:
@@ -112,52 +112,69 @@ Padding="16,8"
|
|||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
</Grid.RowDefinitions>
|
</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"
|
<TextBlock Text="Farbverlauf"
|
||||||
Style="{StaticResource HeaderText}" />
|
Style="{StaticResource HeaderText}" />
|
||||||
<TextBlock Text="Klicken zum Kopieren"
|
<TextBlock Text="Klicken zum Kopieren"
|
||||||
Style="{StaticResource SubtleText}"
|
Style="{StaticResource SubtleText}"
|
||||||
Margin="0,4,0,0" />
|
Margin="0,4,0,0" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
</DockPanel>
|
||||||
|
|
||||||
<ScrollViewer Grid.Row="1"
|
<ScrollViewer Grid.Row="1"
|
||||||
VerticalScrollBarVisibility="Auto"
|
VerticalScrollBarVisibility="Auto"
|
||||||
HorizontalScrollBarVisibility="Disabled">
|
HorizontalScrollBarVisibility="Disabled">
|
||||||
<ItemsControl ItemsSource="{Binding History}">
|
<ItemsControl ItemsSource="{Binding History}">
|
||||||
|
<ItemsControl.ItemContainerStyle>
|
||||||
|
<Style TargetType="ContentPresenter">
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
</Style>
|
||||||
|
</ItemsControl.ItemContainerStyle>
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<ui:CardControl Margin="0,0,0,8"
|
<ui:Card Margin="0,0,0,8"
|
||||||
Padding="8"
|
Padding="12"
|
||||||
Cursor="Hand"
|
Cursor="Hand"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch">
|
||||||
HorizontalContentAlignment="Left">
|
<ui:Card.InputBindings>
|
||||||
<ui:CardControl.InputBindings>
|
|
||||||
<MouseBinding MouseAction="LeftClick"
|
<MouseBinding MouseAction="LeftClick"
|
||||||
Command="{Binding DataContext.CopyHexCommand, RelativeSource={RelativeSource AncestorType=ui:FluentWindow}}"
|
Command="{Binding DataContext.CopyHexCommand, RelativeSource={RelativeSource AncestorType=ui:FluentWindow}}"
|
||||||
CommandParameter="{Binding}" />
|
CommandParameter="{Binding}" />
|
||||||
</ui:CardControl.InputBindings>
|
</ui:Card.InputBindings>
|
||||||
|
|
||||||
<Grid HorizontalAlignment="Stretch">
|
<DockPanel LastChildFill="True">
|
||||||
<Grid.ColumnDefinitions>
|
<!-- Delete button pinned to the right -->
|
||||||
<ColumnDefinition Width="Auto" />
|
<ui:Button DockPanel.Dock="Right"
|
||||||
<ColumnDefinition Width="*" />
|
Icon="{ui:SymbolIcon Dismiss24}"
|
||||||
</Grid.ColumnDefinitions>
|
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 -->
|
<!-- Color preview on the left -->
|
||||||
<Border Width="48"
|
<Border DockPanel.Dock="Left"
|
||||||
|
Width="48"
|
||||||
Height="48"
|
Height="48"
|
||||||
Background="{Binding Brush}"
|
Background="{Binding Brush}"
|
||||||
CornerRadius="8"
|
CornerRadius="8"
|
||||||
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center" />
|
||||||
HorizontalAlignment="Left" />
|
|
||||||
|
|
||||||
<!-- Text info in the middle -->
|
<!-- Text info fills the middle -->
|
||||||
<StackPanel Grid.Column="1"
|
<StackPanel Margin="12,0,0,0"
|
||||||
Margin="12,0,0,0"
|
VerticalAlignment="Center">
|
||||||
VerticalAlignment="Center"
|
|
||||||
HorizontalAlignment="Left">
|
|
||||||
<TextBlock Text="{Binding Hex}"
|
<TextBlock Text="{Binding Hex}"
|
||||||
FontWeight="Medium"
|
FontWeight="Medium"
|
||||||
FontSize="15"
|
FontSize="15"
|
||||||
@@ -167,8 +184,8 @@ FontWeight="Medium"
|
|||||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||||
Margin="0,2,0,0" />
|
Margin="0,2,0,0" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</DockPanel>
|
||||||
</ui:CardControl>
|
</ui:Card>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using MaxSlurper.Models;
|
using MaxSlurper.Models;
|
||||||
@@ -10,11 +12,14 @@ namespace MaxSlurper.Services
|
|||||||
{
|
{
|
||||||
AppSettings LoadSettings();
|
AppSettings LoadSettings();
|
||||||
void SaveSettings(AppSettings settings);
|
void SaveSettings(AppSettings settings);
|
||||||
|
List<ColorItem> LoadHistory();
|
||||||
|
void SaveHistory(IEnumerable<ColorItem> history);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SettingsService : ISettingsService
|
public class SettingsService : ISettingsService
|
||||||
{
|
{
|
||||||
private readonly string _settingsPath;
|
private readonly string _settingsPath;
|
||||||
|
private readonly string _historyPath;
|
||||||
|
|
||||||
public SettingsService()
|
public SettingsService()
|
||||||
{
|
{
|
||||||
@@ -22,6 +27,7 @@ namespace MaxSlurper.Services
|
|||||||
var appFolder = Path.Combine(appData, "MaxSlurper");
|
var appFolder = Path.Combine(appData, "MaxSlurper");
|
||||||
Directory.CreateDirectory(appFolder);
|
Directory.CreateDirectory(appFolder);
|
||||||
_settingsPath = Path.Combine(appFolder, "settings.json");
|
_settingsPath = Path.Combine(appFolder, "settings.json");
|
||||||
|
_historyPath = Path.Combine(appFolder, "history.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppSettings LoadSettings()
|
public AppSettings LoadSettings()
|
||||||
@@ -94,10 +100,52 @@ var json = File.ReadAllText(_settingsPath);
|
|||||||
catch { }
|
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
|
private class SettingsData
|
||||||
{
|
{
|
||||||
public string[]? HotkeyModifiers { get; set; }
|
public string[]? HotkeyModifiers { get; set; }
|
||||||
public string? HotkeyKey { 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 PickColorCommand { get; }
|
||||||
public ICommand ClearHistoryCommand { get; }
|
public ICommand ClearHistoryCommand { get; }
|
||||||
|
public ICommand RemoveColorCommand { get; }
|
||||||
public ICommand CopyHexCommand { get; }
|
public ICommand CopyHexCommand { get; }
|
||||||
public ICommand OpenColorPickerCommand { get; }
|
public ICommand OpenColorPickerCommand { get; }
|
||||||
public ICommand OpenSettingsCommand { get; }
|
public ICommand OpenSettingsCommand { get; }
|
||||||
@@ -51,10 +52,18 @@ namespace MaxSlurper.ViewModels
|
|||||||
Settings = _settingsService.LoadSettings();
|
Settings = _settingsService.LoadSettings();
|
||||||
|
|
||||||
PickColorCommand = new RelayCommand(async _ => await PickColor());
|
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);
|
CopyHexCommand = new RelayCommand(CopyHex, _ => Selected != null || _ is ColorItem);
|
||||||
OpenColorPickerCommand = new RelayCommand(_ => OpenColorPicker());
|
OpenColorPickerCommand = new RelayCommand(_ => OpenColorPicker());
|
||||||
OpenSettingsCommand = new RelayCommand(_ => OpenSettings());
|
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; }
|
public System.Action<AppSettings>? OnSettingsChanged { get; set; }
|
||||||
@@ -79,6 +88,8 @@ namespace MaxSlurper.ViewModels
|
|||||||
Selected = item;
|
Selected = item;
|
||||||
|
|
||||||
System.Windows.Clipboard.SetText(item.Hex);
|
System.Windows.Clipboard.SetText(item.Hex);
|
||||||
|
_settingsService.SaveHistory(History);
|
||||||
|
((RelayCommand)ClearHistoryCommand).RaiseCanExecuteChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenColorPicker()
|
private void OpenColorPicker()
|
||||||
@@ -104,6 +115,8 @@ namespace MaxSlurper.ViewModels
|
|||||||
Selected = item;
|
Selected = item;
|
||||||
|
|
||||||
System.Windows.Clipboard.SetText(item.Hex);
|
System.Windows.Clipboard.SetText(item.Hex);
|
||||||
|
_settingsService.SaveHistory(History);
|
||||||
|
((RelayCommand)ClearHistoryCommand).RaiseCanExecuteChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +132,23 @@ namespace MaxSlurper.ViewModels
|
|||||||
private void ClearHistory()
|
private void ClearHistory()
|
||||||
{
|
{
|
||||||
History.Clear();
|
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)
|
private void CopyHex(object? parameter)
|
||||||
@@ -136,7 +166,13 @@ namespace MaxSlurper.ViewModels
|
|||||||
|
|
||||||
private void UpdateSelected()
|
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));
|
SelectedColorBrush = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(Selected.R, Selected.G, Selected.B));
|
||||||
SelectedHex = Selected.Hex;
|
SelectedHex = Selected.Hex;
|
||||||
SelectedRgb = Selected.Rgb;
|
SelectedRgb = Selected.Rgb;
|
||||||
|
|||||||
Reference in New Issue
Block a user