Prechádzať zdrojové kódy

Implemented AnimatedPopUp for dialog view. New option to ask for confirmation upon exit and confirmation dialog when permanently deleting file #171

Ruben 10 mesiacov pred
rodič
commit
718a8cdcc8
38 zmenil súbory, kde vykonal 610 pridanie a 45 odobranie
  1. 2 1
      src/PicView.Avalonia.MacOS/macOSKeybindings.cs
  2. 2 1
      src/PicView.Avalonia.Win32/WindowsKeybindings.cs
  3. 52 0
      src/PicView.Avalonia/Animations/AnimationsHelper.cs
  4. 81 0
      src/PicView.Avalonia/CustomControls/AnimatedPopUp.cs
  5. 36 0
      src/PicView.Avalonia/FileSystem/FileManager.cs
  6. 14 6
      src/PicView.Avalonia/Input/MainKeyboardShortcuts.cs
  7. 4 0
      src/PicView.Avalonia/PicView.Avalonia.csproj
  8. 25 0
      src/PicView.Avalonia/PicViewTheme/Controls/AnimatedPopUp.axaml
  9. 1 0
      src/PicView.Avalonia/PicViewTheme/Index.axaml
  10. 2 2
      src/PicView.Avalonia/Preloading/Preloader.cs
  11. 12 32
      src/PicView.Avalonia/UI/FunctionsHelper.cs
  12. 54 0
      src/PicView.Avalonia/UI/UIHelper.cs
  13. 10 0
      src/PicView.Avalonia/ViewModels/MainViewModel.cs
  14. 24 0
      src/PicView.Avalonia/ViewModels/PupUpViewModel.cs
  15. 21 0
      src/PicView.Avalonia/ViewModels/ViewModelBase.cs
  16. 17 0
      src/PicView.Avalonia/Views/GeneralSettingsView.axaml
  17. 19 0
      src/PicView.Avalonia/Views/KeybindingsView.axaml
  18. 43 0
      src/PicView.Avalonia/Views/UC/PopUps/CloseDialog.axaml
  19. 44 0
      src/PicView.Avalonia/Views/UC/PopUps/CloseDialog.axaml.cs
  20. 48 0
      src/PicView.Avalonia/Views/UC/PopUps/DeleteDialog.axaml
  21. 43 0
      src/PicView.Avalonia/Views/UC/PopUps/DeleteDialog.axaml.cs
  22. 2 1
      src/PicView.Core/Config/AppSettings.cs
  23. 3 0
      src/PicView.Core/Config/Languages/da.json
  24. 3 0
      src/PicView.Core/Config/Languages/de.json
  25. 5 2
      src/PicView.Core/Config/Languages/en.json
  26. 3 0
      src/PicView.Core/Config/Languages/es.json
  27. 3 0
      src/PicView.Core/Config/Languages/fr.json
  28. 3 0
      src/PicView.Core/Config/Languages/it.json
  29. 3 0
      src/PicView.Core/Config/Languages/ko.json
  30. 3 0
      src/PicView.Core/Config/Languages/pl.json
  31. 4 0
      src/PicView.Core/Config/Languages/pt-br.json
  32. 3 0
      src/PicView.Core/Config/Languages/ro.json
  33. 3 0
      src/PicView.Core/Config/Languages/ru.json
  34. 3 0
      src/PicView.Core/Config/Languages/sv.json
  35. 3 0
      src/PicView.Core/Config/Languages/tr.json
  36. 3 0
      src/PicView.Core/Config/Languages/zh-CN.json
  37. 3 0
      src/PicView.Core/Config/Languages/zh-TW.json
  38. 6 0
      src/PicView.Core/Localization/LanguageModel.cs

+ 2 - 1
src/PicView.Avalonia.MacOS/macOSKeybindings.cs

@@ -66,7 +66,8 @@ public static class MacOsKeybindings
                                                 "Cmd+V": "Paste",
                                                 "Cmd+P": "Print",
                                                 "Alt+Z": "ToggleInterface",
-                                                "Delete": "DeleteFile"
+                                                "Delete": "DeleteFile",
+                                                "Shift+Delete": "DeleteFilePermanently"
                                               }
                                               """;
 }

+ 2 - 1
src/PicView.Avalonia.Win32/WindowsKeybindings.cs

@@ -66,7 +66,8 @@ public static class WindowsKeybindings
                                                 "Ctrl+V": "Paste",
                                                 "Ctrl+P": "Print",
                                                 "Alt+Z": "ToggleInterface",
-                                                "Delete": "DeleteFile"
+                                                "Delete": "DeleteFile",
+                                                "Shift+Delete": "DeleteFilePermanently"
                                               }
                                               """;
 }

+ 52 - 0
src/PicView.Avalonia/Animations/AnimationsHelper.cs

@@ -227,5 +227,57 @@ public static class AnimationsHelper
             }
         };
     }
+    
+    public static Animation CenteringAnimation(double fromX, double fromY, double toX, double toY, double speed)
+    {
+        return CenteringAnimation(fromX, fromY, toX, toY, TimeSpan.FromSeconds(speed));
+    }
+    
+    public static Animation CenteringAnimation(double fromX, double fromY, double toX, double toY, TimeSpan duration)
+    {
+        return new Animation
+        {
+            Duration = duration,
+            Easing = new SplineEasing(), // Using SplineEasing for smooth motion
+            FillMode = FillMode.Forward,
+            Children =
+            {
+                new KeyFrame
+                {
+                    Setters =
+                    {
+                        new Setter
+                        {
+                            Property = TranslateTransform.XProperty,
+                            Value = fromX
+                        },
+                        new Setter
+                        {
+                            Property = TranslateTransform.YProperty,
+                            Value = fromY
+                        }
+                    },
+                    Cue = new Cue(0d)
+                },
+                new KeyFrame
+                {
+                    Setters =
+                    {
+                        new Setter
+                        {
+                            Property = TranslateTransform.XProperty,
+                            Value = toX
+                        },
+                        new Setter
+                        {
+                            Property = TranslateTransform.YProperty,
+                            Value = toY
+                        }
+                    },
+                    Cue = new Cue(1d)
+                },
+            }
+        };
+    }
 }
         

+ 81 - 0
src/PicView.Avalonia/CustomControls/AnimatedPopUp.cs

@@ -0,0 +1,81 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Metadata;
+using Avalonia.Controls.Primitives;
+using Avalonia.Input;
+using PicView.Avalonia.Animations;
+using PicView.Avalonia.UI;
+
+namespace PicView.Avalonia.CustomControls;
+
+[TemplatePart("PART_Overlay", typeof(Panel))]
+[TemplatePart("PART_Border", typeof(Border))]
+public class AnimatedPopUp : ContentControl
+{
+    private Panel? _partOverlay;
+    private Border? _partBorder;
+    
+    public static readonly AvaloniaProperty<bool> ClickingOutSideClosesProperty =
+        AvaloniaProperty.Register<CopyButton, bool>(nameof(ClickingOutSideCloses));
+        
+    public bool ClickingOutSideCloses
+    {
+        get => (bool)GetValue(ClickingOutSideClosesProperty)!;
+        set => SetValue(ClickingOutSideClosesProperty, value);
+    }
+
+    protected override Type StyleKeyOverride => typeof(AnimatedPopUp);
+
+    protected AnimatedPopUp()
+    {
+        Loaded += async delegate
+        {
+            await AnimatedOpening();
+        };
+    }
+    
+    protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+    {
+        base.OnApplyTemplate(e);
+        _partOverlay = e.NameScope.Find<Panel>("PART_Overlay");
+        _partBorder = e.NameScope.Find<Border>("PART_Border");
+            
+        _partOverlay.Opacity = 0;
+        _partBorder.Opacity = 0;
+            
+        // Handle click outside to close
+        _partOverlay.PointerPressed += async delegate
+        {
+            if (!ClickingOutSideCloses)
+            {
+                return;
+            }
+            if (!_partBorder.IsPointerOver)
+            {
+                await AnimatedClosing();
+            }
+        };
+    }
+    
+    public async Task AnimatedOpening()
+    {
+        UIHelper.IsDialogOpen = true;
+        var fadeIn = AnimationsHelper.OpacityAnimation(0, 1, 0.3);
+        var centering = AnimationsHelper.CenteringAnimation(50, 100, 0, 0, 0.3);
+        await Task.WhenAll(fadeIn.RunAsync(_partOverlay), fadeIn.RunAsync(_partBorder), centering.RunAsync(_partBorder));
+    }
+    
+    public async Task AnimatedClosing()
+    {
+        UIHelper.IsDialogOpen = false;
+        var fadeIn = AnimationsHelper.OpacityAnimation(1, 0, 0.3);
+        var centering = AnimationsHelper.CenteringAnimation(0, 0, 50, 100, 0.3);
+        await Task.WhenAll(fadeIn.RunAsync(_partOverlay), fadeIn.RunAsync(_partBorder), centering.RunAsync(_partBorder));
+        UIHelper.GetMainView.MainGrid.Children.Remove(this);
+    }
+    
+    public void KeyDownHandler(object? sender, KeyEventArgs e)
+    {
+        RaiseEvent(e);
+    }
+}

+ 36 - 0
src/PicView.Avalonia/FileSystem/FileManager.cs

@@ -0,0 +1,36 @@
+using PicView.Avalonia.UI;
+using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.Views.UC.PopUps;
+using PicView.Core.FileHandling;
+using PicView.Core.Localization;
+
+namespace PicView.Avalonia.FileSystem;
+
+public static class FileManager
+{
+    public static async Task DeleteFile(bool recycle, MainViewModel vm)
+    {
+        if (vm.FileInfo is null)
+        {
+            return;
+        }
+        
+        var errorMsg = string.Empty;
+        
+        if(!recycle)
+        {
+            var prompt = $"{TranslationHelper.GetTranslation("DeleteFilePermanently")}";
+            var deleteDialog = new DeleteDialog(prompt, vm.FileInfo.FullName);
+            UIHelper.GetMainView.MainGrid.Children.Add(deleteDialog);
+        }
+        else
+        {
+            errorMsg = await Task.FromResult(FileDeletionHelper.DeleteFileWithErrorMsg(vm.FileInfo.FullName, recycle));
+        }
+
+        if (!string.IsNullOrEmpty(errorMsg))
+        {
+            await TooltipHelper.ShowTooltipMessageAsync(errorMsg, true);
+        }
+    }
+}

+ 14 - 6
src/PicView.Avalonia/Input/MainKeyboardShortcuts.cs

@@ -2,6 +2,7 @@
 using System.Runtime.InteropServices;
 using Avalonia.Input;
 using PicView.Avalonia.Crop;
+using PicView.Avalonia.CustomControls;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.Views.UC;
 
@@ -73,10 +74,6 @@ public static class MainKeyboardShortcuts
                 await FunctionsHelper.ShowStartUpMenu();
                 return;
 #endif
-            
-            case Key.Escape:
-                await FunctionsHelper.Close().ConfigureAwait(false);
-                return;
 
             case Key.LeftShift:
             case Key.RightShift:
@@ -126,7 +123,19 @@ public static class MainKeyboardShortcuts
         
         if (CropFunctions.IsCropping)
         {
-            await UIHelper.GetMainView.MainGrid.Children.OfType<CropControl>().First().KeyDownHandler(null,e);
+            await UIHelper.GetMainView.MainGrid.Children.OfType<CropControl>().FirstOrDefault().KeyDownHandler(null,e);
+            return;
+        }
+
+        if (UIHelper.IsDialogOpen)
+        {
+            UIHelper.GetMainView.MainGrid.Children.OfType<AnimatedPopUp>().FirstOrDefault().KeyDownHandler(null,e);
+            return;
+        }
+
+        if (e.Key == Key.Escape)
+        {
+            await FunctionsHelper.Close().ConfigureAwait(false);
             return;
         }
 
@@ -142,7 +151,6 @@ public static class MainKeyboardShortcuts
             }
             // Execute the associated action
             await func.Invoke().ConfigureAwait(false);
-            ClearKeyDownModifiers();
         }
     }
 

+ 4 - 0
src/PicView.Avalonia/PicView.Avalonia.csproj

@@ -84,6 +84,10 @@
       <DependentUpon>SingleImageResizeView.axaml</DependentUpon>
       <SubType>Code</SubType>
     </Compile>
+    <Compile Update="Views\UC\PopUps\DeleteDialog.axaml.cs">
+      <DependentUpon>DeleteDialog.axaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
   </ItemGroup>
 
   

+ 25 - 0
src/PicView.Avalonia/PicViewTheme/Controls/AnimatedPopUp.axaml

@@ -0,0 +1,25 @@
+<ResourceDictionary
+    x:ClassModifier="internal"
+    xmlns="https://github.com/avaloniaui"
+    xmlns:customControls="clr-namespace:PicView.Avalonia.CustomControls"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+    <ControlTheme TargetType="customControls:AnimatedPopUp" x:Key="{x:Type customControls:AnimatedPopUp}">
+        <Setter Property="Template">
+            <ControlTemplate>
+                <Panel Background="#A8000000" x:Name="PART_Overlay">
+                    <Border
+                        Background="{DynamicResource MainBackgroundColor}"
+                        BorderBrush="{DynamicResource MainBorderColor}"
+                        BorderThickness="1"
+                        CornerRadius="8"
+                        HorizontalAlignment="Center"
+                        Padding="{TemplateBinding Padding}"
+                        VerticalAlignment="Center"
+                        x:Name="PART_Border">
+                        <ContentPresenter Content="{TemplateBinding Content}" />
+                    </Border>
+                </Panel>
+            </ControlTemplate>
+        </Setter>
+    </ControlTheme>
+</ResourceDictionary>

+ 1 - 0
src/PicView.Avalonia/PicViewTheme/Index.axaml

@@ -7,6 +7,7 @@
                 <ResourceInclude Source="ResourceDictionaries/Variables.axaml" />
                 <ResourceInclude Source="Icons.axaml" />
 
+                <ResourceInclude Source="Controls/AnimatedPopUp.axaml" />
                 <ResourceInclude Source="Controls/AutoScrollViewer.axaml" />
                 <ResourceInclude Source="Controls/Border.axaml" />
                 <ResourceInclude Source="Controls/Button.axaml" />

+ 2 - 2
src/PicView.Avalonia/Preloading/Preloader.cs

@@ -9,13 +9,13 @@ namespace PicView.Avalonia.Preloading;
 
 public sealed class PreLoader : IAsyncDisposable
 {
+    
 #if DEBUG
 
     // ReSharper disable once ConvertToConstant.Local
     private static readonly bool ShowAddRemove = true;
-
-
 #endif
+    
     private readonly PreLoaderConfig _config = new();
 
     private readonly ConcurrentDictionary<int, PreLoadValue> _preLoadList = new();

+ 12 - 32
src/PicView.Avalonia/UI/FunctionsHelper.cs

@@ -107,6 +107,7 @@ public static class FunctionsHelper
 
             // File functions
             "DeleteFile" => DeleteFile,
+            "DeleteFilePermanently" => DeleteFilePermanently,
             "Rename" => Rename,
             "ShowFileProperties" => ShowFileProperties,
 
@@ -416,38 +417,11 @@ public static class FunctionsHelper
     
     public static async Task Close()
     {
-        if (UIHelper.IsAnyMenuOpen(Vm))
-        {
-            UIHelper.CloseMenus(Vm);
-            return;
-        }
-
-        if (CropFunctions.IsCropping)
-        {
-            CropFunctions.CloseCropControl(Vm);
-            return;
-        }
-
-        if (Navigation.Slideshow.IsRunning)
-        {
-            Navigation.Slideshow.StopSlideshow(Vm);
-            return;
-        }
-
-        if (SettingsHelper.Settings.WindowProperties.Fullscreen)
-        {
-            await WindowFunctions.MaximizeRestore();
-            return;
-        }
-        if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
+        if (Vm is null)
         {
             return;
         }
-        await Dispatcher.UIThread.InvokeAsync(() =>
-        {
-            // TODO: Make it a setting to close the window
-            desktop.MainWindow?.Close();
-        });
+        await UIHelper.Close(Vm);
     }
     
     public static async Task Center()
@@ -633,12 +607,18 @@ public static class FunctionsHelper
         {
             return;
         }
-        var errorMsg = await Task.FromResult(FileDeletionHelper.DeleteFileWithErrorMsg(Vm.FileInfo?.FullName, true));
 
-        if (!string.IsNullOrEmpty(errorMsg))
+        await FileManager.DeleteFile(true, Vm);
+    }
+    
+    public static async Task DeleteFilePermanently()
+    {
+        if (Vm is null)
         {
-            await TooltipHelper.ShowTooltipMessageAsync(errorMsg, true);
+            return;
         }
+
+        await FileManager.DeleteFile(false, Vm);
     }
 
     public static async Task Rename()

+ 54 - 0
src/PicView.Avalonia/UI/UIHelper.cs

@@ -3,17 +3,24 @@ using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Layout;
 using Avalonia.Threading;
+using PicView.Avalonia.Crop;
 using PicView.Avalonia.Gallery;
+using PicView.Avalonia.Navigation;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.Views;
 using PicView.Avalonia.Views.UC;
 using PicView.Avalonia.Views.UC.Menus;
+using PicView.Avalonia.Views.UC.PopUps;
+using PicView.Avalonia.WindowBehavior;
+using PicView.Core.Config;
 using PicView.Core.Gallery;
 
 namespace PicView.Avalonia.UI;
 public static class UIHelper
 {
     #region GetControls
+    
+    public static bool IsDialogOpen { get; set; }
 
     public static MainView? GetMainView { get; private set; }
     public static Control? GetTitlebar { get; private set; }
@@ -180,6 +187,53 @@ public static class UIHelper
 
 
     #endregion Navigation
+    
+    #region Dialogs
+    
+    public static async Task Close(MainViewModel vm)
+    {
+        if (IsAnyMenuOpen(vm))
+        {
+            CloseMenus(vm);
+            return;
+        }
+
+        if (CropFunctions.IsCropping)
+        {
+            CropFunctions.CloseCropControl(vm);
+            return;
+        }
+
+        if (Slideshow.IsRunning)
+        {
+            Slideshow.StopSlideshow(vm);
+            return;
+        }
+
+        if (SettingsHelper.Settings.WindowProperties.Fullscreen)
+        {
+            await WindowFunctions.MaximizeRestore();
+            return;
+        }
+        if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
+        {
+            return;
+        }
+
+        await Dispatcher.UIThread.InvokeAsync(() =>
+        {
+            if (SettingsHelper.Settings.UIProperties.ShowConfirmationOnEsc)
+            {
+                GetMainView.MainGrid.Children.Add(new CloseDialog());
+            }
+            else
+            {
+                desktop.MainWindow?.Close();
+            }
+        });
+    } 
+
+    #endregion
 
 
 }

+ 10 - 0
src/PicView.Avalonia/ViewModels/MainViewModel.cs

@@ -593,6 +593,16 @@ public class MainViewModel : ViewModelBase
             SettingsHelper.Settings.UIProperties.OpenInSameWindow = value;
         }
     } = SettingsHelper.Settings.UIProperties.OpenInSameWindow;
+    
+    public bool IsShowingConfirmationOnEsc
+    {
+        get;
+        set
+        {
+            this.RaiseAndSetIfChanged(ref field, value);
+            SettingsHelper.Settings.UIProperties.ShowConfirmationOnEsc = value;
+        }
+    } = SettingsHelper.Settings.UIProperties.ShowConfirmationOnEsc;
 
     public bool IsEditableTitlebarOpen
     {

+ 24 - 0
src/PicView.Avalonia/ViewModels/PupUpViewModel.cs

@@ -0,0 +1,24 @@
+using System.Reactive;
+using ReactiveUI;
+
+namespace PicView.Avalonia.ViewModels;
+
+public class PopUpViewModel : ReactiveObject
+{
+    public bool IsOpen
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
+
+    // Command to toggle popup
+    public ReactiveCommand<Unit, Unit> TogglePopupCommand { get; }
+
+    public PopUpViewModel()
+    {
+        TogglePopupCommand = ReactiveCommand.Create(() =>
+        {
+            IsOpen = !IsOpen;
+        });
+    }
+}

+ 21 - 0
src/PicView.Avalonia/ViewModels/ViewModelBase.cs

@@ -19,6 +19,7 @@ public class ViewModelBase : ReactiveObject
         Reload = TranslationHelper.Translation.Reload;
         Print = TranslationHelper.Translation.Print;
         DeleteFile = TranslationHelper.Translation.DeleteFile;
+        PermanentlyDelete = TranslationHelper.Translation.PermanentlyDelete;
         Save = TranslationHelper.Translation.Save;
         CopyFile = TranslationHelper.Translation.CopyFile;
         NewWindow = TranslationHelper.Translation.NewWindow;
@@ -253,10 +254,24 @@ public class ViewModelBase : ReactiveObject
         Start = TranslationHelper.Translation.Start;
         Thumbnail = TranslationHelper.Translation.Thumbnail;
         WidthAndHeight = TranslationHelper.Translation.WidthAndHeight;
+        CloseWindowPrompt = TranslationHelper.Translation.CloseWindowPrompt;
+        ShowConfirmationOnEsc = TranslationHelper.Translation.ShowConfirmationOnEsc;
     }
 
     #region Strings
     
+    public string? CloseWindowPrompt
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
+    
+    public string? ShowConfirmationOnEsc
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
+    
     public string? WidthAndHeight
     {
         get;
@@ -1306,6 +1321,12 @@ public class ViewModelBase : ReactiveObject
         get;
         set => this.RaiseAndSetIfChanged(ref field, value);
     }
+    
+    public string? PermanentlyDelete
+    {
+        get;
+        set => this.RaiseAndSetIfChanged(ref field, value);
+    }
 
     public string? Save
     {

+ 17 - 0
src/PicView.Avalonia/Views/GeneralSettingsView.axaml

@@ -97,6 +97,23 @@
                                            Mode=OneWay}" />
             </ToggleButton>
 
+            <ToggleButton
+                Background="Transparent"
+                BorderThickness="0"
+                Classes="altHover"
+                IsChecked="{CompiledBinding IsShowingConfirmationOnEsc}"
+                Margin="0,0,0,10"
+                Width="300">
+                <TextBlock
+                    Classes="txt"
+                    Foreground="{StaticResource SecondaryTextColor}"
+                    Margin="0"
+                    MaxWidth="240"
+                    Padding="0,1,5,0"
+                    Text="{CompiledBinding ShowConfirmationOnEsc,
+                                           Mode=OneWay}" />
+            </ToggleButton>
+
         </StackPanel>
     </Panel>
 </UserControl>

+ 19 - 0
src/PicView.Avalonia/Views/KeybindingsView.axaml

@@ -968,6 +968,25 @@
                 Width="140" />
         </StackPanel>
 
+        <StackPanel Margin="15,0,10,10" Orientation="Horizontal">
+            <TextBlock
+                Classes="txt"
+                FontFamily="/Assets/Fonts/Roboto-Bold.ttf#Roboto"
+                Text="{CompiledBinding PermanentlyDelete}"
+                Width="170" />
+            <customControls:KeybindTextBox
+                Classes="hover TStyle"
+                MethodName="DeleteFilePermanently"
+                ToolTip.Tip="{CompiledBinding ChangeKeybindingTooltip}"
+                Width="140" />
+            <customControls:KeybindTextBox
+                Alt="True"
+                Classes="hover TStyle"
+                MethodName="DeleteFilePermanently"
+                ToolTip.Tip="{CompiledBinding ChangeKeybindingTooltip}"
+                Width="140" />
+        </StackPanel>
+
         <StackPanel Margin="15,5,10,10" Orientation="Horizontal">
             <TextBlock
                 Classes="txt"

+ 43 - 0
src/PicView.Avalonia/Views/UC/PopUps/CloseDialog.axaml

@@ -0,0 +1,43 @@
+<customControls:AnimatedPopUp
+    ClickingOutSideCloses="False"
+    Padding="20"
+    d:DesignHeight="450"
+    d:DesignWidth="800"
+    mc:Ignorable="d"
+    x:Class="PicView.Avalonia.Views.UC.PopUps.CloseDialog"
+    x:DataType="viewModels:MainViewModel"
+    xmlns="https://github.com/avaloniaui"
+    xmlns:customControls="clr-namespace:PicView.Avalonia.CustomControls"
+    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    xmlns:viewModels="clr-namespace:PicView.Avalonia.ViewModels"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+    <Panel Background="Transparent">
+        <TextBlock
+            Classes="txt"
+            FontSize="14"
+            HorizontalAlignment="Center"
+            Text="{CompiledBinding CloseWindowPrompt}"
+            VerticalAlignment="Top" />
+        <StackPanel
+            HorizontalAlignment="Right"
+            Margin="0,35,0,0"
+            Orientation="Horizontal"
+            VerticalAlignment="Bottom">
+            <Button
+                Classes="BorderStyle altHover mainBtn"
+                Margin="0,0,10,0"
+                Padding="30,0"
+                x:Name="CancelButton">
+                <TextBlock Classes="txt" Text="{CompiledBinding Cancel}" />
+            </Button>
+            <Button
+                Background="{DynamicResource AccentColor}"
+                Classes="BorderStyle accentHover mainBtn"
+                Padding="30,0"
+                x:Name="CloseButton">
+                <TextBlock Classes="txt" Text="{CompiledBinding Close}" />
+            </Button>
+        </StackPanel>
+    </Panel>
+</customControls:AnimatedPopUp>

+ 44 - 0
src/PicView.Avalonia/Views/UC/PopUps/CloseDialog.axaml.cs

@@ -0,0 +1,44 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using PicView.Avalonia.CustomControls;
+
+namespace PicView.Avalonia.Views.UC.PopUps;
+
+public partial class CloseDialog : AnimatedPopUp
+{
+    public CloseDialog()
+    {
+        InitializeComponent();
+        CancelButton.Click += async delegate
+        {
+            await AnimatedClosing();
+        };
+        CloseButton.Click += delegate
+        {
+            if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
+            {
+                return;
+            }
+            desktop.MainWindow?.Close();
+        };
+        
+        Focus();
+        
+        KeyDown += (_, e) =>
+        {
+            switch (e.Key)
+            {
+                case Key.Enter:
+                    CloseButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
+                    break;
+                case Key.Escape:
+                    CancelButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
+                    break;
+            }
+            e.Handled = true;
+        };
+    }
+}

+ 48 - 0
src/PicView.Avalonia/Views/UC/PopUps/DeleteDialog.axaml

@@ -0,0 +1,48 @@
+<customControls:AnimatedPopUp
+    ClickingOutSideCloses="True"
+    Padding="20"
+    d:DesignHeight="450"
+    d:DesignWidth="800"
+    mc:Ignorable="d"
+    x:Class="PicView.Avalonia.Views.UC.PopUps.DeleteDialog"
+    x:DataType="viewModels:MainViewModel"
+    xmlns="https://github.com/avaloniaui"
+    xmlns:customControls="clr-namespace:PicView.Avalonia.CustomControls"
+    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    xmlns:viewModels="clr-namespace:PicView.Avalonia.ViewModels"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+    <StackPanel Background="Transparent">
+        <TextBlock
+            Classes="txt"
+            FontFamily="/Assets/Fonts/Roboto-Medium.ttf#Roboto"
+            FontSize="14"
+            MaxWidth="200"
+            x:Name="PromptText" />
+        <TextBlock
+            Classes="txt"
+            Margin="0,6,0,0"
+            MaxWidth="200"
+            x:Name="PromptFileName" />
+        <StackPanel
+            HorizontalAlignment="Right"
+            Margin="0,30,0,0"
+            Orientation="Horizontal"
+            VerticalAlignment="Bottom">
+            <Button
+                Classes="BorderStyle altHover mainBtn"
+                Margin="0,0,10,0"
+                Padding="30,0"
+                x:Name="CancelButton">
+                <TextBlock Classes="txt" Text="{CompiledBinding Cancel}" />
+            </Button>
+            <Button
+                Background="{DynamicResource AccentColor}"
+                Classes="BorderStyle accentHover mainBtn"
+                Padding="30,0"
+                x:Name="ConfirmButton">
+                <TextBlock Classes="txt" Text="{CompiledBinding DeleteFile}" />
+            </Button>
+        </StackPanel>
+    </StackPanel>
+</customControls:AnimatedPopUp>

+ 43 - 0
src/PicView.Avalonia/Views/UC/PopUps/DeleteDialog.axaml.cs

@@ -0,0 +1,43 @@
+using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using PicView.Avalonia.CustomControls;
+using PicView.Core.FileHandling;
+
+namespace PicView.Avalonia.Views.UC.PopUps;
+
+public partial class DeleteDialog : AnimatedPopUp
+{
+    public DeleteDialog(string prompt, string file)
+    {
+        InitializeComponent();
+        Loaded += delegate
+        {
+            PromptText.Text = prompt;
+            PromptFileName.Text = Path.GetFileName(file) + "?";
+            CancelButton.Click += async delegate { await AnimatedClosing(); };
+            ConfirmButton.Click += async delegate
+            {
+                FileDeletionHelper.DeleteFileWithErrorMsg(file, false);
+                await AnimatedClosing();
+            };
+
+            Focus();
+
+            KeyDown += (_, e) =>
+            {
+                switch (e.Key)
+                {
+                    case Key.Enter:
+                        ConfirmButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
+                        break;
+                    case Key.Escape:
+                        CancelButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
+                        break;
+                }
+
+                e.Handled = true;
+            };
+        };
+    }
+}

+ 2 - 1
src/PicView.Core/Config/AppSettings.cs

@@ -2,7 +2,7 @@
 
 public record AppSettings
 {
-    public double Version { get; set; } = 1.2;
+    public double Version { get; set; } = 1.3;
     public WindowProperties? WindowProperties { get; set; }
     public UIProperties? UIProperties { get; set; }
     public Theme? Theme { get; set; }
@@ -38,6 +38,7 @@ public record UIProperties
     public int BgColorChoice { get; set; } = 0;
     public double SlideShowTimer { get; set; } = 5000;
     public bool OpenInSameWindow { get; set; } = false;
+    public bool ShowConfirmationOnEsc { get; set; } = false;
 }
 
 public record Theme

+ 3 - 0
src/PicView.Core/Config/Languages/da.json

@@ -51,6 +51,7 @@
   "Close": "Luk",
   "CloseApp": "Lukker hele programmet",
   "CloseGallery": "Luk galleri",
+  "CloseWindowPrompt": "Ønsker du at lukke vinduet?",
   "CloudyWeather": "Overskyet vejr",
   "ColorPickerTool": "Farvelægningsværktøj",
   "ColorPickerToolTooltip": "Vælg en farve fra billedet",
@@ -243,6 +244,7 @@
   "PencilSketch": "Blyantskitse",
   "PercentComplete": "% gennemført...",
   "Percentage": "Procent",
+  "PermanentlyDelete": "Slet permanent",
   "PhotometricInterpretation": "Fotometrisk fortolkning",
   "Pivot": "Omdrejning",
   "Pixelate": "Pixeler",
@@ -310,6 +312,7 @@
   "ShowBottomGallery": "Vis nederste galleri",
   "ShowBottomGalleryWhenUiIsHidden": "Vis nederste galleri, når brugergrænsefladen er skjult",
   "ShowBottomToolbar": "Vis værktøjslinjen i bunden",
+  "ShowConfirmationOnEsc": "Vis bekræftelsesdialog, når 'Esc' trykkes",
   "ShowFadeInButtonsOnHover": "Vis skjulte knapper, når musen er i kanterne i programmet",
   "ShowFileSavingDialog": "Vis gem fil dialogen",
   "ShowImageGallery": "Vis billedgalleri",

+ 3 - 0
src/PicView.Core/Config/Languages/de.json

@@ -51,6 +51,7 @@
   "Close": "Schließen",
   "CloseApp": "Gesamte Anwendung schließen",
   "CloseGallery": "Galerie schließen",
+  "CloseWindowPrompt": "Möchten Sie das Fenster schließen?",
   "CloudyWeather": "Bewölktes Wetter",
   "ColorPickerTool": "Farbauswahl-Werkzeug",
   "ColorPickerToolTooltip": "Farbe aus Bild auswählen",
@@ -243,6 +244,7 @@
   "PencilSketch": "Bleistiftskizze",
   "PercentComplete": "% vollständig...",
   "Percentage": "Prozentsatz",
+  "PermanentlyDelete": "Endgültig löschen",
   "PhotometricInterpretation": "Photometrische Interpretation",
   "Pivot": "Drehpunkt",
   "Pixelate": "Verpixeln",
@@ -310,6 +312,7 @@
   "ShowBottomGallery": "Untere Galerie anzeigen",
   "ShowBottomGalleryWhenUiIsHidden": "Untere Galerie anzeigen, wenn die Benutzeroberfläche ausgeblendet ist",
   "ShowBottomToolbar": "Untere Symbolleiste anzeigen",
+  "ShowConfirmationOnEsc": "Bestätigungsdialog anzeigen, wenn 'Esc' gedrückt wird",
   "ShowFadeInButtonsOnHover": "Fade-in-Schaltflächen bei Mauszeiger anzeigen",
   "ShowFileSavingDialog": "Dateispeicherdialog anzeigen",
   "ShowImageGallery": "Bildergalerie anzeigen",

+ 5 - 2
src/PicView.Core/Config/Languages/en.json

@@ -51,6 +51,7 @@
   "Close": "Close",
   "CloseApp": "Close the whole application",
   "CloseGallery": "Close gallery",
+  "CloseWindowPrompt": "Do you wish to close the window?",
   "CloudyWeather": "Cloudy weather",
   "ColorPickerTool": "Color Picker Tool",
   "ColorPickerToolTooltip": "Pick color from image",
@@ -243,6 +244,7 @@
   "PencilSketch": "Pencil Sketch",
   "PercentComplete": "% complete...",
   "Percentage": "Percentage",
+  "PermanentlyDelete": "Permanently delete",
   "PhotometricInterpretation": "Photometric interpretation",
   "Pivot": "Pivot",
   "Pixelate": "Pixelate",
@@ -311,6 +313,7 @@
   "ShowBottomGallery": "Show bottom gallery",
   "ShowBottomGalleryWhenUiIsHidden": "Show bottom gallery when UI is hidden",
   "ShowBottomToolbar": "Show bottom toolbar",
+  "ShowConfirmationOnEsc": "Show confirmation dialog when pressing 'Esc'",
   "ShowFadeInButtonsOnHover": "Show fade-in buttons on mouse hover",
   "ShowFileSavingDialog": "Show file saving dialog",
   "ShowImageGallery": "Show image gallery",
@@ -377,8 +380,8 @@
   "WindowManagement": "Window management",
   "WindowScaling": "Window scaling",
   "Zoom": "Zoom",
-  "ZoomIn": "Zoom In",
-  "ZoomOut": "Zoom Out",
+  "ZoomIn": "Zoom in",
+  "ZoomOut": "Zoom out",
   "_1Star": "1 star rating",
   "_2Star": "2 star rating",
   "_3Star": "3 star rating",

+ 3 - 0
src/PicView.Core/Config/Languages/es.json

@@ -51,6 +51,7 @@
   "Close": "Cerrar",
   "CloseApp": "Cierra la aplicación por completo",
   "CloseGallery": "Cerrar galería",
+  "CloseWindowPrompt": "¿Desea cerrar la ventana?",
   "CloudyWeather": "Tiempo nublado",
   "ColorPickerTool": "Cuentagotas",
   "ColorPickerToolTooltip": "Elegir color desde imagen",
@@ -242,6 +243,7 @@
   "PencilSketch": "Dibujo a lápiz",
   "PercentComplete": "% completado...",
   "Percentage": "Porcentaje",
+  "PermanentlyDelete": "Eliminar permanentemente",
   "PhotometricInterpretation": "Interpretación fotométrica",
   "Pivot": "Perspectiva",
   "Pixelate": "Pixelado",
@@ -309,6 +311,7 @@
   "ShowBottomGallery": "Mostrar galería inferior",
   "ShowBottomGalleryWhenUiIsHidden": "Mostrar galería inferior cuando la interfaz de usuario está oculta",
   "ShowBottomToolbar": "Mostrar barra de herramientas inferior",
+  "ShowConfirmationOnEsc": "Mostrar cuadro de confirmación al presionar 'Esc'",
   "ShowFadeInButtonsOnHover": "Mostrar botones de desvanecimiento al pasar el ratón",
   "ShowFileSavingDialog": "Mostrar el cuadro de diálogo de guardar archivo",
   "ShowImageGallery": "Mostrar galería de imáagenes",

+ 3 - 0
src/PicView.Core/Config/Languages/fr.json

@@ -51,6 +51,7 @@
   "Close": "Fermer",
   "CloseApp": "Quitter l'application",
   "CloseGallery": "Fermer la galerie",
+  "CloseWindowPrompt": "Souhaitez-vous fermer la fenêtre ?",
   "CloudyWeather": "Temps nuageux",
   "ColorPickerTool": "Outil de sélection de couleur",
   "ColorPickerToolTooltip": "Choisir la couleur de l'image",
@@ -243,6 +244,7 @@
   "PencilSketch": "Croquis au crayon",
   "PercentComplete": "% achevée...",
   "Percentage": "Pourcentage",
+  "PermanentlyDelete": "Supprimer définitivement",
   "PhotometricInterpretation": "Interprétation photométrique",
   "Pivot": "Pivot",
   "Pixelate": "Pixéliser",
@@ -310,6 +312,7 @@
   "ShowBottomGallery": "Afficher la galerie inférieure",
   "ShowBottomGalleryWhenUiIsHidden": "Afficher la galerie inférieure lorsque l'interface utilisateur est masquée",
   "ShowBottomToolbar": "Afficher la barre d'outils inférieure",
+  "ShowConfirmationOnEsc": "Afficher la boîte de confirmation lors de l'appui sur 'Esc'",
   "ShowFadeInButtonsOnHover": "Afficher les boutons en fondu au survol de la souris",
   "ShowFileSavingDialog": "Afficher la boîte de dialogue d'enregistrement de fichier",
   "ShowImageGallery": "Afficher la galerie d'images",

+ 3 - 0
src/PicView.Core/Config/Languages/it.json

@@ -51,6 +51,7 @@
   "Close": "Chiudere",
   "CloseApp": "Chiudi l'intera applicazione",
   "CloseGallery": "Chiudi la galleria",
+  "CloseWindowPrompt": "Vuoi chiudere la finestra?",
   "CloudyWeather": "Tempo nuvoloso",
   "ColorPickerTool": "Strumento di selezione del colore",
   "ColorPickerToolTooltip": "Scegli il colore dall'immagine",
@@ -243,6 +244,7 @@
   "PencilSketch": "Schizzo a matita",
   "PercentComplete": "% completo...",
   "Percentage": "Percentuale",
+  "PermanentlyDelete": "Elimina definitivamente",
   "PhotometricInterpretation": "Interpretazione fotometrica",
   "Pivot": "Volto",
   "Pixelate": "Pixelare",
@@ -310,6 +312,7 @@
   "ShowBottomGallery": "Mostra galleria inferiore",
   "ShowBottomGalleryWhenUiIsHidden": "Mostra galleria inferiore quando l'interfaccia utente è nascosta",
   "ShowBottomToolbar": "Mostra la barra degli strumenti inferiore",
+  "ShowConfirmationOnEsc": "Mostra la finestra di conferma quando premi 'Esc'",
   "ShowFadeInButtonsOnHover": "Mostra pulsanti in dissolvenza al passaggio del mouse",
   "ShowFileSavingDialog": "Mostra finestra di salvataggio file",
   "ShowImageGallery": "Mostra galleria immagini",

+ 3 - 0
src/PicView.Core/Config/Languages/ko.json

@@ -51,6 +51,7 @@
   "Close": "닫기",
   "CloseApp": "전체 응용 프로그램 닫기",
   "CloseGallery": "갤러리 닫기",
+  "CloseWindowPrompt": "창을 닫으시겠습니까?",
   "CloudyWeather": "흐린 날씨",
   "ColorPickerTool": "색 선택 도구",
   "ColorPickerToolTooltip": "이미지에서 색 선택",
@@ -243,6 +244,7 @@
   "PencilSketch": "연필 스케치",
   "PercentComplete": "% 완료...",
   "Percentage": "백분율",
+  "PermanentlyDelete": "영구 삭제",
   "PhotometricInterpretation": "측광 해석",
   "Pivot": "중심점",
   "Pixelate": "픽셀 레이트",
@@ -311,6 +313,7 @@
   "ShowBottomGallery": "하단 갤러리 표시",
   "ShowBottomGalleryWhenUiIsHidden": "UI를 숨겼을 때 하단 갤러리 표시",
   "ShowBottomToolbar": "하단 도구 모음 표시",
+  "ShowConfirmationOnEsc": "'Esc'를 누를 때 확인 대화 상자를 표시",
   "ShowFadeInButtonsOnHover": "마우스 오버 시 페이드인 버튼 표시",
   "ShowFileSavingDialog": "파일 저장 대화상자 표시",
   "ShowImageGallery": "이미지 갤러리 표시",

+ 3 - 0
src/PicView.Core/Config/Languages/pl.json

@@ -51,6 +51,7 @@
   "Close": "Zamknij",
   "CloseApp": "Zamyka aplikację",
   "CloseGallery": "Zamknij galerię",
+  "CloseWindowPrompt": "Czy chcesz zamknąć okno?",
   "CloudyWeather": "Pochmurno",
   "ColorPickerTool": "Narzędzie wyboru koloru",
   "ColorPickerToolTooltip": "Wybierz kolor ze zdjęcia",
@@ -243,6 +244,7 @@
   "PencilSketch": "Szkic ołówkiem",
   "PercentComplete": "% ukończono...",
   "Percentage": "Procent",
+  "PermanentlyDelete": "Usuń trwale",
   "PhotometricInterpretation": "Interpretacja fotometryczna",
   "Pivot": "Pivot",
   "Pixelate": "Pikselizacja",
@@ -310,6 +312,7 @@
   "ShowBottomGallery": "Pokaż dolną galerię",
   "ShowBottomGalleryWhenUiIsHidden": "Pokaż dolną galerię: gdy UI jest ukryte",
   "ShowBottomToolbar": "Pokaż dolny pasek narzędzi",
+  "ShowConfirmationOnEsc": "Pokaż okno potwierdzenia po naciśnięciu 'Esc'",
   "ShowFadeInButtonsOnHover": "마우스 오버 시 페이드인 버튼 표시",
   "ShowFileSavingDialog": "Pokaż okno zapisywania pliku",
   "ShowImageGallery": "Pokaż galerię zdjęć",

+ 4 - 0
src/PicView.Core/Config/Languages/pt-br.json

@@ -51,6 +51,7 @@
   "Close": "Fechar",
   "CloseApp": "Fechar o aplicativo",
   "CloseGallery": "Fechar galeria",
+  "CloseWindowPrompt": "Deseja fechar a janela?",
   "CloudyWeather": "Nublado",
   "ColorPickerTool": "Ferramenta de seleção de cores",
   "ColorPickerToolTooltip": "Escolha a cor da imagem",
@@ -93,6 +94,7 @@
   "DirectionalBlur": "Desfoque direcional",
   "DisableFadeInButtonsOnHover": "Desativar botões de transição ao pousar ponteiro do mouse",
   "DiskSize": "Tamanho do disco",
+  "DoYouWishToCloseWindow": "Pencereyi kapatmak istiyor musunuz?",
   "DoubleClick": "Duplo clique",
   "Down": "Para baixo",
   "Dpi": "DPI",
@@ -243,6 +245,7 @@
   "PencilSketch": "Esboço a lápis",
   "PercentComplete": "% terminado...",
   "Percentage": "Porcentagem",
+  "PermanentlyDelete": "Excluir permanentemente",
   "PhotometricInterpretation": "Interpretação fotométrica",
   "Pivot": "Pivô",
   "Pixelate": "Pixelada",
@@ -311,6 +314,7 @@
   "ShowBottomGallery": "Mostrar a galeria inferior",
   "ShowBottomGalleryWhenUiIsHidden": "Mostrar a galeria inferior quando a interface do usuário estiver oculta",
   "ShowBottomToolbar": "Mostrar a barra de ferramentas inferior",
+  "ShowConfirmationOnEsc": "Mostrar aviso de fechar janela?",
   "ShowFadeInButtonsOnHover": "Mostrar botões de transição ao passar o ponteiro",
   "ShowFileSavingDialog": "Mostrar diálogo de salvamento de arquivos",
   "ShowImageGallery": "Mostrar galeria de imagens",

+ 3 - 0
src/PicView.Core/Config/Languages/ro.json

@@ -51,6 +51,7 @@
   "Close": "Închidere",
   "CloseApp": "Închide întreaga aplicație",
   "CloseGallery": "Închide galeria",
+  "CloseWindowPrompt": "Doriți să închideți fereastra?",
   "CloudyWeather": "Vreme înnorată",
   "ColorPickerTool": "Selector de culoare",
   "ColorPickerToolTooltip": "Alegere culoare din imagine",
@@ -243,6 +244,7 @@
   "PencilSketch": "Schiță cu creionul",
   "PercentComplete": "% finalizat...",
   "Percentage": "Procentaj",
+  "PermanentlyDelete": "Șterge definitiv",
   "PhotometricInterpretation": "Interpretare fotometrică",
   "Pivot": "Pivot",
   "Pixelate": "Pixelare",
@@ -310,6 +312,7 @@
   "ShowBottomGallery": "Afișează galeria de jos",
   "ShowBottomGalleryWhenUiIsHidden": "Afișează galeria de jos când interfața utilizatorului este ascunsă",
   "ShowBottomToolbar": "Afișează bara de instrumente de jos",
+  "ShowConfirmationOnEsc": "Afișează dialogul de confirmare când apăsați 'Esc'",
   "ShowFadeInButtonsOnHover": "Afișează butoanele fade-in la trecerea mouse-ului",
   "ShowFileSavingDialog": "Afișează dialogul de salvare fișier",
   "ShowImageGallery": "Arată galeria de imagini",

+ 3 - 0
src/PicView.Core/Config/Languages/ru.json

@@ -51,6 +51,7 @@
   "Close": "Закрыть",
   "CloseApp": "Закрыть приложение",
   "CloseGallery": "Закрыть галерею",
+  "CloseWindowPrompt": "Вы хотите закрыть окно?",
   "CloudyWeather": "Облачная погода",
   "ColorPickerTool": "Инструмент выбора цвета",
   "ColorPickerToolTooltip": "Выберите цвет из изображения",
@@ -243,6 +244,7 @@
   "PencilSketch": "Карандашный набросок",
   "PercentComplete": "% завершено...",
   "Percentage": "Процент",
+  "PermanentlyDelete": "Удалить навсегда",
   "PhotometricInterpretation": "Фотометрическая интерпретация",
   "Pivot": "Вращение",
   "Pixelate": "Пикселизация",
@@ -310,6 +312,7 @@
   "ShowBottomGallery": "Показать нижнюю галерею",
   "ShowBottomGalleryWhenUiIsHidden": "Показывать нижнюю галерею при скрытом интерфейсе",
   "ShowBottomToolbar": "Показать нижнюю панель инструментов",
+  "ShowConfirmationOnEsc": "Показывать диалог подтверждения при нажатии 'Esc'",
   "ShowFadeInButtonsOnHover": "Показать кнопки с эффектом плавного появления при наведении мыши",
   "ShowFileSavingDialog": "Показать диалоговое окно сохранения файла",
   "ShowImageGallery": "Показать галерею изображений",

+ 3 - 0
src/PicView.Core/Config/Languages/sv.json

@@ -52,6 +52,7 @@
   "Close": "Stäng",
   "CloseApp": "Stäng programmet",
   "CloseGallery": "Stäng galleriet",
+  "CloseWindowPrompt": "Vill du stänga fönstret?",
   "CloudyWeather": "Molnigt",
   "ColorPickerTool": "Färgprov",
   "ColorPickerToolTooltip": "Ta färgprov i bilden",
@@ -244,6 +245,7 @@
   "PencilSketch": "Blyertsskiss",
   "PercentComplete": "% färdig...",
   "Percentage": "Procent",
+  "PermanentlyDelete": "Ta bort permanent",
   "PhotometricInterpretation": "Fotometrisk tolkning",
   "Pivot": "Rotera",
   "Pixelate": "Pixla",
@@ -312,6 +314,7 @@
   "ShowBottomGallery": "Visa nedre galleriet",
   "ShowBottomGalleryWhenUiIsHidden": "Visa nedre galleriet när användargränssnittet är dolt",
   "ShowBottomToolbar": "Visa nedre verktygsfält",
+  "ShowConfirmationOnEsc": "Visa bekräftelsedialog när 'Esc' trycks",
   "ShowFadeInButtonsOnHover": "Visa dolda knappar när musen är i kanterna av programmet",
   "ShowFileSavingDialog": "Visa spara fil-dialog",
   "ShowImageGallery": "Visa bildgalleri",

+ 3 - 0
src/PicView.Core/Config/Languages/tr.json

@@ -51,6 +51,7 @@
   "Close": "Kapat",
   "CloseApp": "Tüm uygulamayı kapat",
   "CloseGallery": "Galeriyi kapat",
+  "CloseWindowPrompt": "Pencereyi kapatmak istiyor musunuz?",
   "CloudyWeather": "Bulutlu hava",
   "ColorPickerTool": "Renk Seçme Aracı",
   "ColorPickerToolTooltip": "Resimden renk seç",
@@ -243,6 +244,7 @@
   "PencilSketch": "Kurşun Kalem Çizimi",
   "PercentComplete": "% tamamlandı...",
   "Percentage": "Yüzde",
+  "PermanentlyDelete": "Kalıcı olarak sil",
   "PhotometricInterpretation": "Fotometrik yorumlama",
   "Pivot": "Eksen",
   "Pixelate": "Pikselleştir",
@@ -311,6 +313,7 @@
   "ShowBottomGallery": "Alt galeriyi göster",
   "ShowBottomGalleryWhenUiIsHidden": "Arayüz gizlendiğinde alt galeriyi göster",
   "ShowBottomToolbar": "Alt araç çubuğunu göster",
+  "ShowConfirmationOnEsc": "ESC'yi basarak pencereyi kapatmak istiyor musunuz?",
   "ShowFadeInButtonsOnHover": "Farenin üzerine gelindiğinde soluklaşan düğmeleri göster",
   "ShowFileSavingDialog": "Dosya kaydetme penceresini göster",
   "ShowImageGallery": "Resim galerisini göster",

+ 3 - 0
src/PicView.Core/Config/Languages/zh-CN.json

@@ -51,6 +51,7 @@
   "Close": "关闭",
   "CloseApp": "关闭本应用程序",
   "CloseGallery": "关闭相册",
+  "CloseWindowPrompt": "您想关闭窗口吗?",
   "CloudyWeather": "多云",
   "ColorPickerTool": "取色工具",
   "ColorPickerToolTooltip": "从图片中选取颜色",
@@ -243,6 +244,7 @@
   "PencilSketch": "铅笔素描",
   "PercentComplete": "% 已完成…",
   "Percentage": "百分比",
+  "PermanentlyDelete": "永久删除",
   "PhotometricInterpretation": "光度学解释",
   "Pivot": "翻转",
   "Pixelate": "像素化",
@@ -310,6 +312,7 @@
   "ShowBottomGallery": "查看底部图",
   "ShowBottomGalleryWhenUiIsHidden": "当用户界面隐藏时显示底部图库",
   "ShowBottomToolbar": "查看底部工具栏",
+  "ShowConfirmationOnEsc": "按下 'Esc' 时显示确认对话框",
   "ShowFadeInButtonsOnHover": "將鼠標懸停時顯示淡入按鈕",
   "ShowFileSavingDialog": "查看文件保存对话框",
   "ShowImageGallery": "显示图片相册",

+ 3 - 0
src/PicView.Core/Config/Languages/zh-TW.json

@@ -51,6 +51,7 @@
   "Close": "關閉",
   "CloseApp": "關閉本應用程式",
   "CloseGallery": "關閉相簿",
+  "CloseWindowPrompt": "您想關閉窗口嗎?",
   "CloudyWeather": "多雲",
   "ColorPickerTool": "取色工具",
   "ColorPickerToolTooltip": "從圖片中選取顏色",
@@ -244,6 +245,7 @@
   "PencilSketch": "鉛筆素描",
   "PercentComplete": "% 已完成…",
   "Percentage": "百分比",
+  "PermanentlyDelete": "永久刪除",
   "PhotometricInterpretation": "光度解釋",
   "Pink": "粉紅",
   "Pivot": "翻轉",
@@ -313,6 +315,7 @@
   "ShowBottomGallery": "查看底部圖",
   "ShowBottomGalleryWhenUiIsHidden": "當使用者介面隱藏時顯示底部圖庫",
   "ShowBottomToolbar": "查看底部工具列",
+  "ShowConfirmationOnEsc": "按下 'Esc' 時顯示確認對話框",
   "ShowFadeInButtonsOnHover": "將滑鼠懸停時顯示淡入按鈕",
   "ShowFileSavingDialog": "顯示檔案儲存對話方塊",
   "ShowImageGallery": "顯示圖片相簿",

+ 6 - 0
src/PicView.Core/Localization/LanguageModel.cs

@@ -393,4 +393,10 @@ public record LanguageModel
     public string? GoBackBy100Images { get; set; }
     
     public string? WidthAndHeight { get; set; }
+    
+    public string? CloseWindowPrompt { get; set; }
+    
+    public string? ShowConfirmationOnEsc { get; set; }
+    
+    public string? PermanentlyDelete { get; set; }
 }