diff --git a/App.xaml b/App.xaml index 819bf43..bacf9a0 100644 --- a/App.xaml +++ b/App.xaml @@ -2,7 +2,8 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" - xmlns:local="clr-namespace:PrettyScreenSHOT"> + xmlns:local="clr-namespace:PrettyScreenSHOT" + xmlns:converters="clr-namespace:PrettyScreenSHOT.Converters"> @@ -10,9 +11,12 @@ - - + + + + + diff --git a/Converters/NullToVisibilityConverter.cs b/Converters/NullToVisibilityConverter.cs new file mode 100644 index 0000000..2b12479 --- /dev/null +++ b/Converters/NullToVisibilityConverter.cs @@ -0,0 +1,29 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace PrettyScreenSHOT.Converters +{ + /// + /// Converts null or empty values to Visibility + /// + public class NullToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + bool isInverse = parameter?.ToString() == "Inverse"; + bool isNull = value == null || (value is string str && string.IsNullOrEmpty(str)); + + if (isInverse) + return isNull ? Visibility.Visible : Visibility.Collapsed; + else + return !isNull ? Visibility.Visible : Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Helpers/DebugHelper.cs b/Helpers/DebugHelper.cs index c2cf715..2272e2c 100644 --- a/Helpers/DebugHelper.cs +++ b/Helpers/DebugHelper.cs @@ -13,7 +13,7 @@ public static class DebugHelper [System.Diagnostics.Conditional("DEBUG")] public static void ShowMessage(string title, string message) { - System.Windows.MessageBox.Show(message, title); + MessageBoxHelper.Show(message, title); } /// diff --git a/Helpers/MessageBoxHelper.cs b/Helpers/MessageBoxHelper.cs new file mode 100644 index 0000000..f61f4e5 --- /dev/null +++ b/Helpers/MessageBoxHelper.cs @@ -0,0 +1,66 @@ +using System.Windows; +using Wpf.Ui.Controls; + +namespace PrettyScreenSHOT.Helpers +{ + /// + /// Helper for showing Wpf.Ui MessageBoxes with a simplified API + /// + public static class MessageBoxHelper + { + public static MessageBoxResult Show( + string message, + string title, + MessageBoxButton button = MessageBoxButton.OK) + { + return Application.Current.Dispatcher.Invoke(() => + { + var messageBox = new Wpf.Ui.Controls.MessageBox + { + Title = title, + Content = message, + ButtonLeftName = GetButtonName(button, true), + ButtonRightName = GetButtonName(button, false) + }; + + var result = messageBox.ShowDialogAsync().GetAwaiter().GetResult(); + return MapToMessageBoxResult(result, button); + }); + } + + private static string GetButtonName(MessageBoxButton button, bool isLeft) + { + return button switch + { + MessageBoxButton.OK => isLeft ? "OK" : string.Empty, + MessageBoxButton.OKCancel => isLeft ? "OK" : "Cancel", + MessageBoxButton.YesNo => isLeft ? "Yes" : "No", + MessageBoxButton.YesNoCancel => isLeft ? "Yes" : (isLeft ? "No" : "Cancel"), + _ => isLeft ? "OK" : string.Empty + }; + } + + private static MessageBoxResult MapToMessageBoxResult( + Wpf.Ui.Controls.MessageBoxResult wpfUiResult, + MessageBoxButton buttonType) + { + return buttonType switch + { + MessageBoxButton.OK => MessageBoxResult.OK, + MessageBoxButton.OKCancel => wpfUiResult == Wpf.Ui.Controls.MessageBoxResult.Primary + ? MessageBoxResult.OK + : MessageBoxResult.Cancel, + MessageBoxButton.YesNo => wpfUiResult == Wpf.Ui.Controls.MessageBoxResult.Primary + ? MessageBoxResult.Yes + : MessageBoxResult.No, + MessageBoxButton.YesNoCancel => wpfUiResult switch + { + Wpf.Ui.Controls.MessageBoxResult.Primary => MessageBoxResult.Yes, + Wpf.Ui.Controls.MessageBoxResult.Secondary => MessageBoxResult.No, + _ => MessageBoxResult.Cancel + }, + _ => MessageBoxResult.None + }; + } + } +} diff --git a/Themes/Base.xaml b/Themes/Base.xaml new file mode 100644 index 0000000..dce8211 --- /dev/null +++ b/Themes/Base.xaml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + diff --git a/Themes/Colors.xaml b/Themes/Colors.xaml new file mode 100644 index 0000000..9ca3080 --- /dev/null +++ b/Themes/Colors.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Themes/Spacing.xaml b/Themes/Spacing.xaml new file mode 100644 index 0000000..dcf33f1 --- /dev/null +++ b/Themes/Spacing.xaml @@ -0,0 +1,41 @@ + + + + + + 4 + 8 + 12 + 16 + 20 + 24 + + + 8 + 12 + 16 + 20 + + 0,0,0,8 + 0,0,0,12 + 0,0,0,16 + 0,0,0,20 + + + 1 + 2 + 3 + + + 4 + 8 + 12 + 999 + + diff --git a/Themes/Typography.xaml b/Themes/Typography.xaml new file mode 100644 index 0000000..f53446d --- /dev/null +++ b/Themes/Typography.xaml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Views/Dialogs/ColorPickerDialog.xaml b/Views/Dialogs/ColorPickerDialog.xaml new file mode 100644 index 0000000..b9f6cdd --- /dev/null +++ b/Views/Dialogs/ColorPickerDialog.xaml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Views/Dialogs/ColorPickerDialog.xaml.cs b/Views/Dialogs/ColorPickerDialog.xaml.cs new file mode 100644 index 0000000..dae1992 --- /dev/null +++ b/Views/Dialogs/ColorPickerDialog.xaml.cs @@ -0,0 +1,64 @@ +using System.Windows; +using System.Windows.Media; +using Wpf.Ui.Controls; + +namespace PrettyScreenSHOT.Views.Dialogs +{ + public partial class ColorPickerDialog : FluentWindow + { + public Color SelectedColor { get; private set; } + + public ColorPickerDialog() + { + InitializeComponent(); + SelectedColor = Colors.Red; + UpdateColorPreview(); + } + + public ColorPickerDialog(Color initialColor) : this() + { + SelectedColor = initialColor; + RedSlider.Value = initialColor.R; + GreenSlider.Value = initialColor.G; + BlueSlider.Value = initialColor.B; + UpdateColorPreview(); + } + + private void OnColorChanged(object sender, RoutedPropertyChangedEventArgs e) + { + if (RedValueText == null || GreenValueText == null || BlueValueText == null) + return; + + RedValueText.Text = ((int)RedSlider.Value).ToString(); + GreenValueText.Text = ((int)GreenSlider.Value).ToString(); + BlueValueText.Text = ((int)BlueSlider.Value).ToString(); + + UpdateColorPreview(); + } + + private void UpdateColorPreview() + { + if (ColorPreview == null) + return; + + byte r = (byte)RedSlider.Value; + byte g = (byte)GreenSlider.Value; + byte b = (byte)BlueSlider.Value; + + SelectedColor = Color.FromRgb(r, g, b); + ColorPreview.Background = new SolidColorBrush(SelectedColor); + } + + private void OnOkClick(object sender, RoutedEventArgs e) + { + DialogResult = true; + Close(); + } + + private void OnCancelClick(object sender, RoutedEventArgs e) + { + DialogResult = false; + Close(); + } + } +} diff --git a/Views/Windows/ScreenshotEditorWindow.xaml.cs b/Views/Windows/ScreenshotEditorWindow.xaml.cs index 6b017fd..b2b142b 100644 --- a/Views/Windows/ScreenshotEditorWindow.xaml.cs +++ b/Views/Windows/ScreenshotEditorWindow.xaml.cs @@ -15,13 +15,9 @@ using Point = System.Windows.Point; using Color = System.Windows.Media.Color; using Pen = System.Windows.Media.Pen; -using Forms = System.Windows.Forms; // alias to avoid ambiguity with System.Windows using WindowsFontStyle = System.Windows.FontStyle; using WindowsFontWeight = System.Windows.FontWeight; using WindowsFontFamily = System.Windows.Media.FontFamily; -using WpfMessageBoxButton = Wpf.Ui.Controls.MessageBoxButton; -using WpfMessageBoxResult = Wpf.Ui.Controls.MessageBoxResult; -using WpfTextBlock = Wpf.Ui.Controls.TextBlock; namespace PrettyScreenSHOT.Views.Windows { @@ -434,12 +430,14 @@ private void UpdateActiveToolButton(System.Windows.Controls.Button? newActiveBut private void OnColorPickerClick(object sender, RoutedEventArgs e) { - var colorDialog = new Forms.ColorDialog(); - colorDialog.Color = System.Drawing.Color.FromArgb(currentColor.R, currentColor.G, currentColor.B); + var colorDialog = new ColorPickerDialog(currentColor) + { + Owner = this + }; - if (colorDialog.ShowDialog() == Forms.DialogResult.OK) + if (colorDialog.ShowDialog() == true) { - currentColor = System.Windows.Media.Color.FromArgb(colorDialog.Color.A, colorDialog.Color.R, colorDialog.Color.G, colorDialog.Color.B); + currentColor = colorDialog.SelectedColor; ColorButton.Background = new SolidColorBrush(currentColor); DebugHelper.LogDebug($"Kolor zmieniony: RGB({currentColor.R},{currentColor.G},{currentColor.B})"); } @@ -455,11 +453,10 @@ private async void OnUploadClick(object sender, RoutedEventArgs e) var provider = SettingsManager.Instance.CloudProvider; if (string.IsNullOrWhiteSpace(provider)) { - System.Windows.MessageBox.Show( + MessageBoxHelper.Show( LocalizationHelper.GetString("Editor_CloudNotConfigured"), LocalizationHelper.GetString("Editor_CloudNotConfiguredTitle"), - System.Windows.MessageBoxButton.OK, - System.Windows.MessageBoxImage.Information); + System.Windows.MessageBoxButton.OK); return; } @@ -495,17 +492,17 @@ private async void OnUploadClick(object sender, RoutedEventArgs e) { // Skopiuj URL do schowka System.Windows.Clipboard.SetText(result.Url); - + var message = string.Format(LocalizationHelper.GetString("Editor_UploadSuccessMessage"), "\n", result.Url); - System.Windows.MessageBox.Show(message, LocalizationHelper.GetString("Editor_UploadSuccess"), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information); - + MessageBoxHelper.Show(message, LocalizationHelper.GetString("Editor_UploadSuccess"), System.Windows.MessageBoxButton.OK); + DebugHelper.LogInfo("Editor", $"Upload successful: {result.Url}"); } else { var errorMsg = result.ErrorMessage ?? LocalizationHelper.GetString("Editor_Error"); var message = string.Format(LocalizationHelper.GetString("Editor_UploadErrorMessage"), "\n", errorMsg); - System.Windows.MessageBox.Show(message, LocalizationHelper.GetString("Editor_UploadError"), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); + MessageBoxHelper.Show(message, LocalizationHelper.GetString("Editor_UploadError"), System.Windows.MessageBoxButton.OK); DebugHelper.LogError("Editor", $"Upload failed: {errorMsg}"); } } @@ -513,7 +510,7 @@ private async void OnUploadClick(object sender, RoutedEventArgs e) { DebugHelper.LogError("Editor", "Error during upload", ex); var message = string.Format(LocalizationHelper.GetString("Editor_ErrorWithMessage"), ex.Message); - System.Windows.MessageBox.Show(message, LocalizationHelper.GetString("Editor_Error"), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); + MessageBoxHelper.Show(message, LocalizationHelper.GetString("Editor_Error"), System.Windows.MessageBoxButton.OK); } } @@ -567,7 +564,7 @@ private void OnCancelClick(object sender, RoutedEventArgs e) private void OnClearClick(object sender, RoutedEventArgs e) { - if (System.Windows.MessageBox.Show("Czy na pewno chcesz wyczyścić wszystkie zmiany?", "Potwierdzenie", System.Windows.MessageBoxButton.YesNo) == System.Windows.MessageBoxResult.Yes) + if (MessageBoxHelper.Show("Czy na pewno chcesz wyczyścić wszystkie zmiany?", "Potwierdzenie", System.Windows.MessageBoxButton.YesNo) == System.Windows.MessageBoxResult.Yes) { ClearAll(); } diff --git a/Views/Windows/ScreenshotHistoryWindow.xaml b/Views/Windows/ScreenshotHistoryWindow.xaml index 48ac27d..07e4801 100644 --- a/Views/Windows/ScreenshotHistoryWindow.xaml +++ b/Views/Windows/ScreenshotHistoryWindow.xaml @@ -4,6 +4,7 @@ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:local="clr-namespace:PrettyScreenSHOT.Views.Windows" xmlns:helpers="clr-namespace:PrettyScreenSHOT.Helpers" + xmlns:converters="clr-namespace:PrettyScreenSHOT.Converters" Title="Screenshot History" Height="650" Width="720" @@ -12,13 +13,6 @@ WindowBackdropType="Mica" WindowCornerPreference="Round"> - - - - - - - diff --git a/Views/Windows/ScreenshotHistoryWindow.xaml.cs b/Views/Windows/ScreenshotHistoryWindow.xaml.cs index 7a40537..e1456e6 100644 --- a/Views/Windows/ScreenshotHistoryWindow.xaml.cs +++ b/Views/Windows/ScreenshotHistoryWindow.xaml.cs @@ -10,8 +10,6 @@ using PrettyScreenSHOT.Services.Input; using PrettyScreenSHOT.Services.Screenshot; using Wpf.Ui.Controls; -using WpfMessageBoxButton = Wpf.Ui.Controls.MessageBoxButton; -using WpfTextBlock = Wpf.Ui.Controls.TextBlock; namespace PrettyScreenSHOT.Views.Windows { @@ -129,21 +127,21 @@ private async void OnUploadClick(object sender, RoutedEventArgs e) item.CloudProvider = result.ProviderName; System.Windows.Clipboard.SetText(result.Url); var message = string.Format(LocalizationHelper.GetString("History_UploadSuccessMessage"), "\n", result.Url); - System.Windows.MessageBox.Show(message, - LocalizationHelper.GetString("History_UploadSuccess"), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information); + MessageBoxHelper.Show(message, + LocalizationHelper.GetString("History_UploadSuccess"), System.Windows.MessageBoxButton.OK); } else { var errorMsg = result.ErrorMessage ?? LocalizationHelper.GetString("History_Error"); var message = string.Format(LocalizationHelper.GetString("History_UploadErrorMessage"), "\n", errorMsg); - System.Windows.MessageBox.Show(message, - LocalizationHelper.GetString("History_UploadError"), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); + MessageBoxHelper.Show(message, + LocalizationHelper.GetString("History_UploadError"), System.Windows.MessageBoxButton.OK); } } catch (Exception ex) { var message = string.Format(LocalizationHelper.GetString("History_ErrorWithMessage"), ex.Message); - System.Windows.MessageBox.Show(message, LocalizationHelper.GetString("History_Error"), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); + MessageBoxHelper.Show(message, LocalizationHelper.GetString("History_Error"), System.Windows.MessageBoxButton.OK); } } } @@ -154,8 +152,8 @@ private void OnCloudUrlClick(object sender, RoutedEventArgs e) { System.Windows.Clipboard.SetText(item.CloudUrl); var message = string.Format(LocalizationHelper.GetString("History_UrlCopied"), "\n", item.CloudUrl); - System.Windows.MessageBox.Show(message, - LocalizationHelper.GetString("History_CloudUrlTitle"), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information); + MessageBoxHelper.Show(message, + LocalizationHelper.GetString("History_CloudUrlTitle"), System.Windows.MessageBoxButton.OK); } } @@ -181,24 +179,4 @@ private void OnClearFiltersClick(object sender, RoutedEventArgs e) ApplyFilters(); } } - - // Converter dla Visibility - public class NullToVisibilityConverter : IValueConverter - { - public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - bool isInverse = parameter?.ToString() == "Inverse"; - bool isNull = value == null || (value is string str && string.IsNullOrEmpty(str)); - - if (isInverse) - return isNull ? Visibility.Visible : Visibility.Collapsed; - else - return !isNull ? Visibility.Visible : Visibility.Collapsed; - } - - public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } - } } diff --git a/Views/Windows/SettingsWindow.xaml.cs b/Views/Windows/SettingsWindow.xaml.cs index ede0b1c..91ea921 100644 --- a/Views/Windows/SettingsWindow.xaml.cs +++ b/Views/Windows/SettingsWindow.xaml.cs @@ -1,14 +1,12 @@ using System.IO; using System.Windows; -using System.Windows.Forms; using System.Windows.Input; +using Microsoft.Win32; using PrettyScreenSHOT.Helpers; using PrettyScreenSHOT.Services; using PrettyScreenSHOT.Services.Settings; using Wpf.Ui.Appearance; using Wpf.Ui.Controls; -using WpfMessageBoxButton = Wpf.Ui.Controls.MessageBoxButton; -using WpfMessageBoxResult = Wpf.Ui.Controls.MessageBoxResult; namespace PrettyScreenSHOT.Views.Windows { @@ -160,15 +158,15 @@ private void LanguageComboBox_SelectionChanged(object sender, System.Windows.Con private void BrowseButton_Click(object sender, RoutedEventArgs e) { - using (var dialog = new FolderBrowserDialog()) + var dialog = new OpenFolderDialog { - dialog.Description = LocalizationHelper.GetString("Settings_SavePath"); - dialog.SelectedPath = SavePathTextBox.Text; - - if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) - { - SavePathTextBox.Text = dialog.SelectedPath; - } + Title = LocalizationHelper.GetString("Settings_SavePath"), + InitialDirectory = SavePathTextBox.Text + }; + + if (dialog.ShowDialog() == true) + { + SavePathTextBox.Text = dialog.FolderName; } } @@ -196,11 +194,10 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) } catch { - System.Windows.MessageBox.Show( + MessageBoxHelper.Show( LocalizationHelper.GetString("Settings_InvalidPath"), LocalizationHelper.GetString("Settings_SaveError"), - System.Windows.MessageBoxButton.OK, - System.Windows.MessageBoxImage.Error); + System.Windows.MessageBoxButton.OK); return; } } @@ -229,22 +226,20 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) settingsManager.Theme = ThemeComboBox.SelectedItem.ToString() ?? "Dark"; } - System.Windows.MessageBox.Show( + MessageBoxHelper.Show( LocalizationHelper.GetString("Settings_SaveSuccessMessage"), LocalizationHelper.GetString("Settings_SaveSuccess"), - System.Windows.MessageBoxButton.OK, - System.Windows.MessageBoxImage.Information); + System.Windows.MessageBoxButton.OK); this.Close(); } catch (Exception ex) { DebugHelper.LogError("Settings", "Failed to save settings", ex); var message = string.Format(LocalizationHelper.GetString("Settings_ErrorWithMessage"), ex.Message); - System.Windows.MessageBox.Show( + MessageBoxHelper.Show( message, LocalizationHelper.GetString("Settings_SaveError"), - System.Windows.MessageBoxButton.OK, - System.Windows.MessageBoxImage.Error); + System.Windows.MessageBoxButton.OK); } } @@ -268,11 +263,10 @@ private void ThemeComboBox_SelectionChanged(object sender, System.Windows.Contro private void ResetButton_Click(object sender, RoutedEventArgs e) { - var result = System.Windows.MessageBox.Show( + var result = MessageBoxHelper.Show( LocalizationHelper.GetString("Settings_ResetConfirm"), LocalizationHelper.GetString("Editor_Confirm"), - System.Windows.MessageBoxButton.YesNo, - System.Windows.MessageBoxImage.Question); + System.Windows.MessageBoxButton.YesNo); if (result == System.Windows.MessageBoxResult.Yes) { diff --git a/Views/Windows/VideoCaptureWindow.xaml.cs b/Views/Windows/VideoCaptureWindow.xaml.cs index e7a47e7..18b69b8 100644 --- a/Views/Windows/VideoCaptureWindow.xaml.cs +++ b/Views/Windows/VideoCaptureWindow.xaml.cs @@ -81,8 +81,8 @@ private async void StartButton_Click(object sender, RoutedEventArgs e) catch (Exception ex) { DebugHelper.LogError("VideoCapture", "Error starting recording", ex); - System.Windows.MessageBox.Show($"Error starting recording: {ex.Message}", "Error", - System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); + MessageBoxHelper.Show($"Error starting recording: {ex.Message}", "Error", + System.Windows.MessageBoxButton.OK); } } @@ -133,8 +133,8 @@ private async void StopButton_Click(object sender, RoutedEventArgs e) StatusText.Foreground = new System.Windows.Media.SolidColorBrush( System.Windows.Media.Color.FromRgb(76, 175, 80)); // Green - System.Windows.MessageBox.Show($"Video saved to:\n{outputPath}", "Success", - System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information); + MessageBoxHelper.Show($"Video saved to:\n{outputPath}", "Success", + System.Windows.MessageBoxButton.OK); // Reset UI StartButton.IsEnabled = true;