Compare commits
4 Commits
5811421ca2
...
541135e063
| Author | SHA1 | Date | |
|---|---|---|---|
| 541135e063 | |||
| 73711b9342 | |||
| 497795604e | |||
| bfd3581f26 |
@@ -3,7 +3,7 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="clr-namespace:MaxSlurper"
|
xmlns:local="clr-namespace:MaxSlurper"
|
||||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||||
StartupUri="MainWindow.xaml">
|
>
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Configuration;
|
using System.Linq;
|
||||||
using System.Data;
|
|
||||||
using Wpf.Ui.Appearance;
|
using Wpf.Ui.Appearance;
|
||||||
|
|
||||||
namespace MaxSlurper
|
namespace MaxSlurper
|
||||||
@@ -13,7 +12,22 @@ namespace MaxSlurper
|
|||||||
{
|
{
|
||||||
base.OnStartup(e);
|
base.OnStartup(e);
|
||||||
|
|
||||||
// The theme will be applied automatically when the window is shown
|
bool startMinimized = e.Args.Contains("--minimized", System.StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
var mainWindow = new MainWindow();
|
||||||
|
MainWindow = mainWindow;
|
||||||
|
|
||||||
|
if (startMinimized)
|
||||||
|
{
|
||||||
|
// Only show the tray icon, don't show the window
|
||||||
|
mainWindow.WindowState = System.Windows.WindowState.Minimized;
|
||||||
|
mainWindow.ShowInTaskbar = false;
|
||||||
|
mainWindow.Hide();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mainWindow.Show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||||
Title="Farbe aussuche"
|
Title="Farbe auswählen"
|
||||||
Height="500"
|
Height="500"
|
||||||
Width="400"
|
Width="400"
|
||||||
ResizeMode="NoResize"
|
ResizeMode="NoResize"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
@@ -26,8 +26,8 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|||||||
|
|
||||||
<!-- Title bar -->
|
<!-- Title bar -->
|
||||||
<ui:TitleBar Grid.Row="0"
|
<ui:TitleBar Grid.Row="0"
|
||||||
Title="Farbe aussuche"
|
Title="Farbe auswählen"
|
||||||
ShowMaximize="False"
|
ShowMaximize="False"
|
||||||
ShowMinimize="False"
|
ShowMinimize="False"
|
||||||
Icon="/logo.png" />
|
Icon="/logo.png" />
|
||||||
|
|
||||||
@@ -176,14 +176,14 @@ Height="20"
|
|||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<ui:Button Content="Lass ma"
|
<ui:Button Content="Abbrechen"
|
||||||
Height="44"
|
Height="44"
|
||||||
Margin="0,0,8,0"
|
Margin="0,0,8,0"
|
||||||
Click="CancelButton_Click"
|
Click="CancelButton_Click"
|
||||||
Appearance="Secondary"/>
|
Appearance="Secondary"/>
|
||||||
|
|
||||||
<ui:Button Grid.Column="1"
|
<ui:Button Grid.Column="1"
|
||||||
Content="Kopieren & Tschüss"
|
Content="Kopieren & Schließen"
|
||||||
Height="44"
|
Height="44"
|
||||||
Padding="24,0"
|
Padding="24,0"
|
||||||
Click="OkButton_Click"
|
Click="OkButton_Click"
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
FontSize="12"
|
FontSize="12"
|
||||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||||
Margin="0,2,0,0"><Run Language="de-de" Text="H"/><Run Text="otkey zum Farben schlürfen"/></TextBlock>
|
Margin="0,2,0,0">Hotkey zum Farben aufnehmen</TextBlock>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
@@ -99,6 +99,37 @@ Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ui:Card>
|
</ui:Card>
|
||||||
|
|
||||||
|
<!-- Autostart Card -->
|
||||||
|
<ui:Card Margin="0,0,0,16" Padding="20">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<ui:SymbolIcon Symbol="Power24"
|
||||||
|
FontSize="24"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0,0,12,0"/>
|
||||||
|
|
||||||
|
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||||
|
<TextBlock Text="Autostart"
|
||||||
|
FontSize="16"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="{DynamicResource TextFillColorPrimaryBrush}"/>
|
||||||
|
<TextBlock Text="Beim Systemstart minimiert starten"
|
||||||
|
FontSize="12"
|
||||||
|
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||||
|
Margin="0,2,0,0"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<CheckBox Grid.Column="2"
|
||||||
|
IsChecked="{Binding IsAutostart}"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
</ui:Card>
|
||||||
|
|
||||||
<!-- About Card -->
|
<!-- About Card -->
|
||||||
<ui:Card Padding="20">
|
<ui:Card Padding="20">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
@@ -121,7 +152,7 @@ FontWeight="SemiBold"
|
|||||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"/>
|
Foreground="{DynamicResource TextFillColorPrimaryBrush}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<TextBlock Text="DER ColorPicker für Max"
|
<TextBlock Text="Der Farbwähler für Max"
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
FontSize="13"
|
FontSize="13"
|
||||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||||
@@ -129,7 +160,7 @@ TextWrapping="Wrap"
|
|||||||
<TextBlock TextWrapping="Wrap"
|
<TextBlock TextWrapping="Wrap"
|
||||||
FontSize="13"
|
FontSize="13"
|
||||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}">
|
Foreground="{DynamicResource TextFillColorSecondaryBrush}">
|
||||||
<Run Text="Gemacht mit "/>
|
<Run Text="Erstellt mit "/>
|
||||||
<Run Text="♥" Foreground="Red" FontSize="14"/>
|
<Run Text="♥" Foreground="Red" FontSize="14"/>
|
||||||
<Run Text=" von Mathias"/>
|
<Run Text=" von Mathias"/>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
@@ -151,13 +182,13 @@ BorderThickness="0,1,0,0"
|
|||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<TextBlock Text="Änderungen werden direkt jespeichert"
|
<TextBlock Text="Änderungen werden automatisch gespeichert"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontSize="12"
|
FontSize="12"
|
||||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"/>
|
Foreground="{DynamicResource TextFillColorSecondaryBrush}"/>
|
||||||
|
|
||||||
<ui:Button Grid.Column="1"
|
<ui:Button Grid.Column="1"
|
||||||
Content="Zumachen"
|
Content="Schließen"
|
||||||
Height="36"
|
Height="36"
|
||||||
Padding="24,0"
|
Padding="24,0"
|
||||||
Click="Close_Click"
|
Click="Close_Click"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
@@ -7,6 +7,7 @@ using System.Windows.Controls;
|
|||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using MaxSlurper.Models;
|
using MaxSlurper.Models;
|
||||||
using MaxSlurper.Services;
|
using MaxSlurper.Services;
|
||||||
|
using Microsoft.Win32;
|
||||||
using Wpf.Ui.Controls;
|
using Wpf.Ui.Controls;
|
||||||
|
|
||||||
namespace MaxSlurper.Controls
|
namespace MaxSlurper.Controls
|
||||||
@@ -31,6 +32,35 @@ public event PropertyChangedEventHandler? PropertyChanged;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const string RegistryRunKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
|
||||||
|
private const string AppName = "MaxSlurper";
|
||||||
|
|
||||||
|
public bool IsAutostart
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
using var key = Registry.CurrentUser.OpenSubKey(RegistryRunKey, false);
|
||||||
|
return key?.GetValue(AppName) != null;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
using var key = Registry.CurrentUser.OpenSubKey(RegistryRunKey, true);
|
||||||
|
if (key == null) return;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
var exePath = Environment.ProcessPath ?? System.Reflection.Assembly.GetEntryAssembly()!.Location;
|
||||||
|
key.SetValue(AppName, $"\"{exePath}\" --minimized");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
key.DeleteValue(AppName, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public SettingsWindow(AppSettings settings, ISettingsService settingsService, Action<AppSettings> onSettingsChanged)
|
public SettingsWindow(AppSettings settings, ISettingsService settingsService, Action<AppSettings> onSettingsChanged)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@@ -54,7 +84,7 @@ public event PropertyChangedEventHandler? PropertyChanged;
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_isCapturingHotkey = true;
|
_isCapturingHotkey = true;
|
||||||
CurrentHotkey = "Drück deine Tasten...";
|
CurrentHotkey = "Tastenkombination eingeben...";
|
||||||
|
|
||||||
var captureWindow = new HotkeyCapture();
|
var captureWindow = new HotkeyCapture();
|
||||||
captureWindow.Owner = this;
|
captureWindow.Owner = this;
|
||||||
@@ -131,7 +161,7 @@ ExtendsContentIntoTitleBar = true;
|
|||||||
|
|
||||||
var infoText = new System.Windows.Controls.TextBlock
|
var infoText = new System.Windows.Controls.TextBlock
|
||||||
{
|
{
|
||||||
Text = "Drück die Tastenkombination, die de haben willst",
|
Text = "Drücken Sie die gewünschte Tastenkombination",
|
||||||
FontSize = 14,
|
FontSize = 14,
|
||||||
TextAlignment = TextAlignment.Center,
|
TextAlignment = TextAlignment.Center,
|
||||||
Foreground = (System.Windows.Media.Brush)FindResource("TextFillColorSecondaryBrush"),
|
Foreground = (System.Windows.Media.Brush)FindResource("TextFillColorSecondaryBrush"),
|
||||||
@@ -142,7 +172,7 @@ ExtendsContentIntoTitleBar = true;
|
|||||||
|
|
||||||
var keyDisplay = new System.Windows.Controls.TextBlock
|
var keyDisplay = new System.Windows.Controls.TextBlock
|
||||||
{
|
{
|
||||||
Text = "Warte uff Eingabe...",
|
Text = "Warte auf Eingabe...",
|
||||||
FontSize = 18,
|
FontSize = 18,
|
||||||
FontWeight = FontWeights.SemiBold,
|
FontWeight = FontWeights.SemiBold,
|
||||||
TextAlignment = TextAlignment.Center,
|
TextAlignment = TextAlignment.Center,
|
||||||
@@ -204,7 +234,7 @@ key == Key.LWin || key == Key.RWin)
|
|||||||
// Require at least one modifier
|
// Require at least one modifier
|
||||||
if (modifiers == ModifierKeys.None)
|
if (modifiers == ModifierKeys.None)
|
||||||
{
|
{
|
||||||
keyDisplay.Text = "Mindestens ein Modifier (Strg, Alt, Shift, Win) musste drücken!";
|
keyDisplay.Text = "Mindestens eine Zusatztaste (Strg, Alt, Shift, Win) erforderlich!";
|
||||||
okButton.IsEnabled = false;
|
okButton.IsEnabled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Cursor="Hand"
|
Cursor="Hand"
|
||||||
ToolTip="Drück ma druff, dann kannste dir 'ne Farbe raussuche">
|
ToolTip="Klicken, um eine Farbe auszuwählen">
|
||||||
<Border.Effect>
|
<Border.Effect>
|
||||||
<DropShadowEffect BlurRadius="8"
|
<DropShadowEffect BlurRadius="8"
|
||||||
ShadowDepth="2"
|
ShadowDepth="2"
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
<StackPanel Orientation="Vertical"
|
<StackPanel Orientation="Vertical"
|
||||||
Margin="16,0,16,0"
|
Margin="16,0,16,0"
|
||||||
VerticalAlignment="Center">
|
VerticalAlignment="Center">
|
||||||
<TextBlock Text="Zuletzt jeklaut"
|
<TextBlock Text="Zuletzt aufgenommen"
|
||||||
Style="{StaticResource SubtleText}"
|
Style="{StaticResource SubtleText}"
|
||||||
Margin="0,0,0,4" />
|
Margin="0,0,0,4" />
|
||||||
<TextBlock Text="{Binding SelectedHex}"
|
<TextBlock Text="{Binding SelectedHex}"
|
||||||
@@ -87,7 +87,7 @@ Style="{StaticResource SubtleText}" />
|
|||||||
<!-- Actions -->
|
<!-- Actions -->
|
||||||
<StackPanel Orientation="Vertical"
|
<StackPanel Orientation="Vertical"
|
||||||
DockPanel.Dock="Right">
|
DockPanel.Dock="Right">
|
||||||
<ui:Button Content="Farbe schlürfen"
|
<ui:Button Content="Farbe aufnehmen"
|
||||||
Appearance="Primary"
|
Appearance="Primary"
|
||||||
Icon="{ui:SymbolIcon Eyedropper24}"
|
Icon="{ui:SymbolIcon Eyedropper24}"
|
||||||
Command="{Binding PickColorCommand}"
|
Command="{Binding PickColorCommand}"
|
||||||
@@ -112,63 +112,88 @@ 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">
|
||||||
<TextBlock Text="Wat ick schon so jeklaut hab"
|
<ui:Button DockPanel.Dock="Right"
|
||||||
Style="{StaticResource HeaderText}" />
|
Content="Verlauf löschen"
|
||||||
<TextBlock Text="Druff klicken und ab dafuer, wa"
|
Appearance="Secondary"
|
||||||
Style="{StaticResource SubtleText}"
|
Icon="{ui:SymbolIcon Delete24}"
|
||||||
Margin="0,4,0,0" />
|
Command="{Binding ClearHistoryCommand}"
|
||||||
</StackPanel>
|
Padding="8,4"
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
<ui:Button DockPanel.Dock="Right"
|
||||||
|
Content="Exportieren"
|
||||||
|
Appearance="Secondary"
|
||||||
|
Icon="{ui:SymbolIcon ArrowExportUp24}"
|
||||||
|
Command="{Binding ExportHistoryCommand}"
|
||||||
|
Padding="8,4"
|
||||||
|
Margin="0,0,8,0"
|
||||||
|
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"
|
<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"
|
||||||
Height="48"
|
Width="48"
|
||||||
Background="{Binding Brush}"
|
Height="48"
|
||||||
CornerRadius="8"
|
Background="{Binding Brush}"
|
||||||
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
CornerRadius="8"
|
||||||
BorderThickness="1"
|
BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}"
|
||||||
VerticalAlignment="Center"
|
BorderThickness="1"
|
||||||
HorizontalAlignment="Left" />
|
VerticalAlignment="Center" />
|
||||||
|
|
||||||
<!-- 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"
|
<TextBlock Text="{Binding Hex}"
|
||||||
HorizontalAlignment="Left">
|
FontWeight="Medium"
|
||||||
<TextBlock Text="{Binding Hex}"
|
FontSize="15"
|
||||||
FontWeight="Medium"
|
Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
|
||||||
FontSize="15"
|
<TextBlock Text="{Binding Rgb}"
|
||||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
|
FontSize="12"
|
||||||
<TextBlock Text="{Binding Rgb}"
|
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
||||||
FontSize="12"
|
Margin="0,2,0,0" />
|
||||||
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
|
</StackPanel>
|
||||||
Margin="0,2,0,0" />
|
</DockPanel>
|
||||||
</StackPanel>
|
</ui:Card>
|
||||||
</Grid>
|
|
||||||
</ui:CardControl>
|
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
|
|||||||
@@ -77,14 +77,14 @@ namespace MaxSlurper
|
|||||||
_notifyIcon.Text = "MaxSlurper";
|
_notifyIcon.Text = "MaxSlurper";
|
||||||
|
|
||||||
var contextMenu = new ContextMenuStrip();
|
var contextMenu = new ContextMenuStrip();
|
||||||
var pickItem = new ToolStripMenuItem("Farbe schlürfen");
|
var pickItem = new ToolStripMenuItem("Farbe aufnehmen");
|
||||||
// Use BeginInvoke to avoid synchronous invocation while windows may be closing
|
// Use BeginInvoke to avoid synchronous invocation while windows may be closing
|
||||||
pickItem.Click += (s, e) => { Dispatcher.BeginInvoke(new Action(() => _vm.PickColorCommand.Execute(null))); };
|
pickItem.Click += (s, e) => { Dispatcher.BeginInvoke(new Action(() => _vm.PickColorCommand.Execute(null))); };
|
||||||
var openItem = new ToolStripMenuItem("Fenster uffmachen");
|
var openItem = new ToolStripMenuItem("Fenster öffnen");
|
||||||
openItem.Click += (s, e) => { Dispatcher.BeginInvoke(new Action(() => { Show(); WindowState = WindowState.Normal; Activate(); })); };
|
openItem.Click += (s, e) => { Dispatcher.BeginInvoke(new Action(() => { Show(); WindowState = WindowState.Normal; Activate(); })); };
|
||||||
var settingsItem = new ToolStripMenuItem("Einstellungen");
|
var settingsItem = new ToolStripMenuItem("Einstellungen");
|
||||||
settingsItem.Click += (s, e) => { Dispatcher.BeginInvoke(new Action(() => { Show(); WindowState = WindowState.Normal; Activate(); _vm.OpenSettingsCommand.Execute(null); })); };
|
settingsItem.Click += (s, e) => { Dispatcher.BeginInvoke(new Action(() => { Show(); WindowState = WindowState.Normal; Activate(); _vm.OpenSettingsCommand.Execute(null); })); };
|
||||||
var exitItem = new ToolStripMenuItem("Tschüss");
|
var exitItem = new ToolStripMenuItem("Beenden");
|
||||||
exitItem.Click += (s, e) => { _notifyIcon.Visible = false; System.Windows.Application.Current.Shutdown(); };
|
exitItem.Click += (s, e) => { _notifyIcon.Visible = false; System.Windows.Application.Current.Shutdown(); };
|
||||||
contextMenu.Items.Add(pickItem);
|
contextMenu.Items.Add(pickItem);
|
||||||
contextMenu.Items.Add(openItem);
|
contextMenu.Items.Add(openItem);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<Authors>Mathias Wagner</Authors>
|
<Authors>Mathias Wagner</Authors>
|
||||||
<Company>MaxSlurper</Company>
|
<Company>MaxSlurper</Company>
|
||||||
<Product>MaxSlurper</Product>
|
<Product>MaxSlurper</Product>
|
||||||
<Description>Weil Max danach gefragt hat</Description>
|
<Description>Farbwähler-Anwendung</Description>
|
||||||
<Copyright>Copyright © 2025</Copyright>
|
<Copyright>Copyright © 2025</Copyright>
|
||||||
<ApplicationIcon>logo.ico</ApplicationIcon>
|
<ApplicationIcon>logo.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using MaxSlurper.Models;
|
using MaxSlurper.Models;
|
||||||
@@ -38,9 +39,11 @@ 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; }
|
||||||
|
public ICommand ExportHistoryCommand { get; }
|
||||||
|
|
||||||
public MainViewModel(IColorPickerService colorPicker, IAudioPlayer audioPlayer, ISettingsService settingsService)
|
public MainViewModel(IColorPickerService colorPicker, IAudioPlayer audioPlayer, ISettingsService settingsService)
|
||||||
{
|
{
|
||||||
@@ -51,10 +54,19 @@ 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());
|
||||||
|
ExportHistoryCommand = new RelayCommand(_ => ExportHistory(), _ => History.Count > 0);
|
||||||
|
|
||||||
|
// 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 +91,9 @@ 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();
|
||||||
|
((RelayCommand)ExportHistoryCommand).RaiseCanExecuteChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenColorPicker()
|
private void OpenColorPicker()
|
||||||
@@ -104,6 +119,9 @@ 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();
|
||||||
|
((RelayCommand)ExportHistoryCommand).RaiseCanExecuteChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +137,25 @@ namespace MaxSlurper.ViewModels
|
|||||||
private void ClearHistory()
|
private void ClearHistory()
|
||||||
{
|
{
|
||||||
History.Clear();
|
History.Clear();
|
||||||
|
Selected = null;
|
||||||
|
_settingsService.SaveHistory(History);
|
||||||
|
((RelayCommand)ClearHistoryCommand).RaiseCanExecuteChanged();
|
||||||
|
((RelayCommand)ExportHistoryCommand).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();
|
||||||
|
((RelayCommand)ExportHistoryCommand).RaiseCanExecuteChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CopyHex(object? parameter)
|
private void CopyHex(object? parameter)
|
||||||
@@ -134,9 +171,62 @@ namespace MaxSlurper.ViewModels
|
|||||||
// Show a notification (optional - can add UI feedback)
|
// Show a notification (optional - can add UI feedback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ExportHistory()
|
||||||
|
{
|
||||||
|
var dialog = new Microsoft.Win32.SaveFileDialog
|
||||||
|
{
|
||||||
|
Title = "Farbpalette exportieren",
|
||||||
|
Filter = "CSS-Datei (*.css)|*.css|JSON-Datei (*.json)|*.json|Textdatei (*.txt)|*.txt",
|
||||||
|
DefaultExt = ".css",
|
||||||
|
FileName = "palette"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (dialog.ShowDialog() != true) return;
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var ext = System.IO.Path.GetExtension(dialog.FileName).ToLowerInvariant();
|
||||||
|
|
||||||
|
switch (ext)
|
||||||
|
{
|
||||||
|
case ".css":
|
||||||
|
sb.AppendLine(":root {");
|
||||||
|
for (int i = 0; i < History.Count; i++)
|
||||||
|
{
|
||||||
|
var c = History[i];
|
||||||
|
sb.AppendLine($" --color-{i + 1}: {c.Hex};");
|
||||||
|
}
|
||||||
|
sb.AppendLine("}");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ".json":
|
||||||
|
sb.AppendLine("[");
|
||||||
|
for (int i = 0; i < History.Count; i++)
|
||||||
|
{
|
||||||
|
var c = History[i];
|
||||||
|
var comma = i < History.Count - 1 ? "," : "";
|
||||||
|
sb.AppendLine($" {{ \"hex\": \"{c.Hex}\", \"rgb\": \"{c.Rgb}\" }}{comma}");
|
||||||
|
}
|
||||||
|
sb.AppendLine("]");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // .txt
|
||||||
|
foreach (var c in History)
|
||||||
|
sb.AppendLine(c.Hex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.IO.File.WriteAllText(dialog.FileName, sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
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