Browse Source

Avalonia updates

Ruben 1 year ago
parent
commit
3667379dea

+ 3 - 3
src/PicView.Avalonia/DarkTheme/Controls/ListBoxItem.axaml

@@ -6,7 +6,7 @@
         <Setter Property="Background" Value="Transparent" />
         <Setter Property="BorderBrush" Value="Transparent" />
         <Setter Property="BorderThickness" Value="1" />
-        <Setter Property="Margin" Value="5" />
+        <Setter Property="Margin" Value="2,0" />
         <Setter Property="Template">
             <ControlTemplate>
                 <ContentPresenter
@@ -15,11 +15,11 @@
                     HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                     VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                     Background="{StaticResource SecondaryBackgroundColor}"
-                    BorderBrush="{StaticResource SecondaryBorderColor}"
+                    BorderBrush="{StaticResource MainBorderColor}"
                     BorderThickness="1"
                     Content="{TemplateBinding Content}"
                     ContentTemplate="{TemplateBinding ContentTemplate}"
-                    CornerRadius="8" />
+                    CornerRadius="0" />
             </ControlTemplate>
         </Setter>
 

+ 89 - 11
src/PicView.Avalonia/Gallery/GalleryFunctions.cs

@@ -1,5 +1,9 @@
 using System.Diagnostics;
+using Avalonia;
 using Avalonia.Controls;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Layout;
+using PicView.Avalonia.Helpers;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.Config;
@@ -10,6 +14,10 @@ namespace PicView.Avalonia.Gallery
 {
     public static class GalleryFunctions
     {
+        public static bool isFullGalleryOpen { get; private set; }
+        public static bool isBottomGalleryOpen { get; private set; }
+        public static bool isAnyGalleryOpen => isFullGalleryOpen || isBottomGalleryOpen;
+
         public static void RecycleItem(object sender, MainViewModel vm)
         {
 #if DEBUG
@@ -27,22 +35,32 @@ namespace PicView.Avalonia.Gallery
 
             vm.GalleryItems.Remove(galleryItem); // TODO: rewrite file system watcher to delete gallery items
         }
-        
+
         public static async Task ToggleGallery(MainViewModel vm)
         {
             if (vm is null)
             {
                 return;
             }
-            vm.IsGalleryOpen = !vm.IsGalleryOpen;
-            SettingsHelper.Settings.Gallery.IsBottomGalleryShown = false;
+
             if (SettingsHelper.Settings.Gallery.IsBottomGalleryShown)
             {
-                // TODO: Change to bottom gallery view
+                if (isFullGalleryOpen)
+                {
+                    OpenBottomGallery(vm);
+                }
+                else
+                {
+                    OpenFullGallery(vm);
+                }
+                vm.CloseMenuCommand.Execute(null);
+                SetGalleryItemSize(vm);
+                return;
             }
 
+            OpenFullGallery(vm);
             vm.CloseMenuCommand.Execute(null);
-            if (vm.IsGalleryOpen)
+            if (isAnyGalleryOpen)
             {
                 if (!NavigationHelper.CanNavigate(vm))
                 {
@@ -50,10 +68,10 @@ namespace PicView.Avalonia.Gallery
                 }
                 _ = Task.Run(() => GalleryLoad.LoadGallery(vm, Path.GetDirectoryName(vm.ImageIterator.Pics[0])));
             }
-            //WindowHelper.SetSize(this);
+
             await SettingsHelper.SaveSettingsAsync();
         }
-        
+
         public static async Task ToggleBottomGallery(MainViewModel vm)
         {
             if (vm is null)
@@ -62,12 +80,11 @@ namespace PicView.Avalonia.Gallery
             }
             if (SettingsHelper.Settings.Gallery.IsBottomGalleryShown)
             {
-                vm.IsGalleryOpen = false;
-                SettingsHelper.Settings.Gallery.IsBottomGalleryShown = false;
+                OpenBottomGallery(vm);
+                SetGalleryItemSize(vm);
             }
             else
             {
-                vm.IsGalleryOpen = true;
                 SettingsHelper.Settings.Gallery.IsBottomGalleryShown = true;
                 if (!NavigationHelper.CanNavigate(vm))
                 {
@@ -76,8 +93,69 @@ namespace PicView.Avalonia.Gallery
                 _ = Task.Run(() => GalleryLoad.LoadGallery(vm, Path.GetDirectoryName(vm.ImageIterator.Pics[0])));
             }
             vm.CloseMenuCommand.Execute(null);
-            //WindowHelper.SetSize(this);
+
+            await SettingsHelper.SaveSettingsAsync();
+        }
+
+        public static async Task OpenCloseBottomGallery(MainViewModel vm)
+        {
+            if (SettingsHelper.Settings.Gallery.IsBottomGalleryShown)
+            {
+                CloseGallery(vm);
+                SettingsHelper.Settings.Gallery.IsBottomGalleryShown = false;
+                await SettingsHelper.SaveSettingsAsync();
+                return;
+            }
+
+            OpenBottomGallery(vm);
+            SettingsHelper.Settings.Gallery.IsBottomGalleryShown = true;
             await SettingsHelper.SaveSettingsAsync();
+            if (!NavigationHelper.CanNavigate(vm))
+            {
+                return;
+            }
+            vm.CloseMenuCommand.Execute(null);
+            await Task.Run(() => GalleryLoad.LoadGallery(vm, Path.GetDirectoryName(vm.ImageIterator.Pics[0])));
+        }
+
+        public static void OpenBottomGallery(MainViewModel vm)
+        {
+            vm.GalleryVerticalAlignment = VerticalAlignment.Bottom;
+            vm.GalleryOrientation = Orientation.Horizontal;
+            vm.IsGalleryCloseIconVisible = false;
+            isBottomGalleryOpen = true;
+            isFullGalleryOpen = false;
+            vm.IsGalleryOpen = true;
+        }
+
+        public static void OpenFullGallery(MainViewModel vm)
+        {
+            vm.GalleryVerticalAlignment = VerticalAlignment.Stretch;
+            vm.GalleryOrientation = Orientation.Vertical;
+            vm.IsGalleryCloseIconVisible = true;
+            isBottomGalleryOpen = false;
+            isFullGalleryOpen = true;
+            vm.IsGalleryOpen = true;
+        }
+
+        public static void CloseGallery(MainViewModel vm)
+        {
+            isBottomGalleryOpen = false;
+            isFullGalleryOpen = false;
+            vm.IsGalleryOpen = false;
+        }
+
+        public static void SetGalleryItemSize(MainViewModel vm)
+        {
+            if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
+            {
+                return;
+            }
+
+            var screen = ScreenHelper.GetScreen(desktop.MainWindow);
+            var size = isBottomGalleryOpen ? SettingsHelper.Settings.Gallery.BottomGalleryItemSize :
+                SettingsHelper.Settings.Gallery.ExpandedGalleryItemSize;
+            vm.GalleryItemSize = screen.WorkingArea.Height / size;
         }
     }
 }

+ 18 - 0
src/PicView.Avalonia/Gallery/GalleryNavigation.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Avalonia;
+using Avalonia.Controls;
+
+namespace PicView.Avalonia.Gallery;
+
+public static class GalleryNavigation
+{
+    public static void CenterScrollToSelectedItem(ListBox listBox, ListBoxItem selectedItem)
+    {
+        var p = selectedItem.TranslatePoint(new Point(), listBox);
+        listBox.Scroll.Offset = new Vector(-selectedItem.Bounds.X, -selectedItem.Bounds.Y);
+    }
+}

+ 13 - 18
src/PicView.Avalonia/Helpers/FunctionsHelper.cs

@@ -12,7 +12,6 @@ using PicView.Core.Config;
 using PicView.Core.FileHandling;
 using PicView.Core.Localization;
 using PicView.Core.ProcessHandling;
-using ReactiveUI;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 
@@ -37,7 +36,7 @@ public static class FunctionsHelper
             return;
         }
 
-        if (Vm.IsGalleryOpen)
+        if (GalleryFunctions.isFullGalleryOpen)
         {
             // TODO - Implement gallery navigation
             return;
@@ -57,7 +56,7 @@ public static class FunctionsHelper
             return;
         }
 
-        if (Vm.IsGalleryOpen)
+        if (GalleryFunctions.isFullGalleryOpen)
         {
             // TODO - Implement gallery navigation
             return;
@@ -77,7 +76,7 @@ public static class FunctionsHelper
             return;
         }
 
-        if (Vm.IsGalleryOpen)
+        if (GalleryFunctions.isFullGalleryOpen)
         {
             // TODO - Implement gallery navigation
             return;
@@ -97,7 +96,7 @@ public static class FunctionsHelper
             return;
         }
 
-        if (Vm.IsGalleryOpen)
+        if (GalleryFunctions.isFullGalleryOpen)
         {
             // TODO - Implement gallery navigation
             return;
@@ -117,7 +116,7 @@ public static class FunctionsHelper
             return;
         }
 
-        if (Vm.IsGalleryOpen)
+        if (GalleryFunctions.isFullGalleryOpen)
         {
             // TODO - Implement gallery navigation
             return;
@@ -153,7 +152,7 @@ public static class FunctionsHelper
             return;
         }
 
-        if (Vm.IsGalleryOpen)
+        if (GalleryFunctions.isFullGalleryOpen)
         {
             return;
         }
@@ -170,7 +169,7 @@ public static class FunctionsHelper
             return;
         }
 
-        if (Vm.IsGalleryOpen)
+        if (GalleryFunctions.isFullGalleryOpen)
         {
             return;
         }
@@ -187,7 +186,7 @@ public static class FunctionsHelper
             return;
         }
 
-        if (Vm.IsGalleryOpen)
+        if (GalleryFunctions.isFullGalleryOpen)
         {
             // TODO - Implement gallery navigation
             return;
@@ -311,6 +310,11 @@ public static class FunctionsHelper
         await GalleryFunctions.ToggleBottomGallery(Vm).ConfigureAwait(false);
     }
 
+    public static async Task OpenCloseBottomGallery()
+    {
+        await GalleryFunctions.OpenCloseBottomGallery(Vm).ConfigureAwait(false);
+    }
+
     public static Task AutoFitWindow()
     {
         throw new NotImplementedException();
@@ -333,10 +337,6 @@ public static class FunctionsHelper
 
     public static Task Fullscreen()
     {
-#if DEBUG
-        // Show Avalonia DevTools in DEBUG mode
-        return Task.CompletedTask;
-#endif
         throw new NotImplementedException();
     }
 
@@ -460,11 +460,6 @@ public static class FunctionsHelper
         {
             return;
         }
-
-        if (Vm.IsGalleryOpen)
-        {
-            return;
-        }
         if (!NavigationHelper.CanNavigate(Vm))
         {
             return;

+ 11 - 2
src/PicView.Avalonia/Helpers/StartUpHelper.cs

@@ -1,6 +1,7 @@
 using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Controls.Primitives;
+using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Keybindings;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.Views;
@@ -82,8 +83,16 @@ public static class StartUpHelper
         if (vm.GalleryItemSize <= 0)
         {
             var screen = ScreenHelper.GetScreen(desktop.MainWindow);
-            // ReSharper disable once PossibleLossOfFraction
-            vm.GalleryItemSize = screen.WorkingArea.Height / 10;
+            var size = Math.Min(SettingsHelper.Settings.Gallery.BottomGalleryItemSize,
+                SettingsHelper.Settings.Gallery.ExpandedGalleryItemSize);
+            vm.GalleryItemSize = screen.WorkingArea.Height / size;
+        }
+
+        if (SettingsHelper.Settings.Gallery.IsBottomGalleryShown)
+        {
+            _ = Task.Run(() => GalleryLoad.LoadGallery(vm, Path.GetDirectoryName(vm.ImageIterator.Pics[0])));
+            GalleryFunctions.OpenBottomGallery(vm);
+            WindowHelper.SetSize(vm);
         }
 
         vm.IsLoading = false;

+ 3 - 1
src/PicView.Avalonia/Helpers/WindowHelper.cs

@@ -2,6 +2,7 @@
 using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Threading;
+using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.Calculations;
@@ -244,7 +245,7 @@ public static class WindowHelper
         var uiBottomSize =
             SettingsHelper.Settings.UIProperties.ShowInterface || SettingsHelper.Settings.UIProperties.ShowBottomNavBar
                 ? 28 : 0;
-        var galleryHeight = vm.IsBottomGalleryShown ? 100 : 0;
+        var galleryHeight = GalleryFunctions.isBottomGalleryOpen ? vm.GalleryItemSize + 36 : 0;
         if (Dispatcher.UIThread.CheckAccess())
         {
             desktopMinWidth = desktop.MainWindow.MinWidth;
@@ -286,6 +287,7 @@ public static class WindowHelper
         vm.TitleMaxWidth = size.TitleMaxWidth;
         vm.ImageWidth = size.Width;
         vm.ImageHeight = size.Height;
+        vm.ImageMargin = new Thickness(0, 0, 0, size.Margin);
     }
 
     #endregion SetSize

+ 9 - 1
src/PicView.Avalonia/Keybindings/MainKeyboardShortcuts.cs

@@ -36,12 +36,20 @@ public static class MainKeyboardShortcuts
         {
             return;
         }
-        
+
         CtrlDown = e.KeyModifiers == KeyModifiers.Control;
         AltDown = e.KeyModifiers is KeyModifiers.Alt or KeyModifiers.Meta;
         ShiftDown = e.KeyModifiers == KeyModifiers.Shift;
         switch (e.Key)
         {
+            case Key.F12:
+#if DEBUG
+                // Show Avalonia DevTools in DEBUG mode
+                return;
+#else
+                break;
+#endif
+
             case Key.LeftShift:
             case Key.RightShift:
             case Key.LeftCtrl:

+ 56 - 28
src/PicView.Avalonia/ViewModels/MainViewModel.cs

@@ -1,11 +1,4 @@
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.Globalization;
-using System.Reactive;
-using System.Reactive.Disposables;
-using System.Runtime.InteropServices;
-using System.Windows.Input;
-using Avalonia;
+using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Controls.Primitives;
@@ -13,7 +6,6 @@ using Avalonia.Input;
 using Avalonia.Media.Imaging;
 using Avalonia.Threading;
 using ImageMagick;
-using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Helpers;
 using PicView.Avalonia.Models;
 using PicView.Avalonia.Navigation;
@@ -26,6 +18,12 @@ using PicView.Core.Localization;
 using PicView.Core.Navigation;
 using PicView.Core.ProcessHandling;
 using ReactiveUI;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Reactive;
+using System.Reactive.Disposables;
+using System.Windows.Input;
+using Avalonia.Layout;
 using static PicView.Core.Gallery.GalleryThumbInfo;
 using ImageViewer = PicView.Avalonia.Views.ImageViewer;
 
@@ -39,6 +37,8 @@ namespace PicView.Avalonia.ViewModels
 
         private readonly IPlatformSpecificService? _platformService;
 
+        #region Gallery
+
         private ObservableCollection<GalleryThumbHolder> _galleryItems;
 
         public ObservableCollection<GalleryThumbHolder> GalleryItems
@@ -55,6 +55,40 @@ namespace PicView.Avalonia.ViewModels
             set => this.RaiseAndSetIfChanged(ref _selectedGalleryItem, value);
         }
 
+        private VerticalAlignment _galleryVerticalAlignment;
+
+        public VerticalAlignment GalleryVerticalAlignment
+        {
+            get => _galleryVerticalAlignment;
+            set => this.RaiseAndSetIfChanged(ref _galleryVerticalAlignment, value);
+        }
+
+        private Orientation _galleryOrientation;
+
+        public Orientation GalleryOrientation
+        {
+            set => this.RaiseAndSetIfChanged(ref _galleryOrientation, value);
+            get => _galleryOrientation;
+        }
+
+        private bool _isGalleryCloseIconVisible;
+
+        public bool IsGalleryCloseIconVisible
+        {
+            get => _isGalleryCloseIconVisible;
+            set => this.RaiseAndSetIfChanged(ref _isGalleryCloseIconVisible, value);
+        }
+
+        private double _galleryItemSize;
+
+        public double GalleryItemSize
+        {
+            get => _galleryItemSize;
+            set => this.RaiseAndSetIfChanged(ref _galleryItemSize, value);
+        }
+
+        #endregion Gallery
+
         #region Commands
 
         public ICommand? ExitCommand { get; }
@@ -87,7 +121,7 @@ namespace PicView.Avalonia.ViewModels
         public ICommand? RenameCommand { get; }
         public ICommand? NewWindowCommand { get; }
         public ICommand? DuplicateFileCommand { get; }
-        
+
         public ICommand? ToggleLoopingCommand { get; }
         public ICommand? RotateLeftCommand { get; }
         public ICommand? RotateRightCommand { get; }
@@ -135,9 +169,9 @@ namespace PicView.Avalonia.ViewModels
         public ICommand? ToggleScrollCommand { get; }
 
         public ICommand? ToggleSubdirectoriesCommand { get; }
-        
+
         public ICommand? SetGalleryItemSizeCommand { get; }
-        
+
         public ICommand? SetBottomGalleryItemSizeCommand { get; }
 
         #endregion Commands
@@ -438,20 +472,6 @@ namespace PicView.Avalonia.ViewModels
             }
         }
 
-        private double _galleryItemSize;
-        public double GalleryItemSize
-        {
-            get => _galleryItemSize;
-            set => this.RaiseAndSetIfChanged(ref _galleryItemSize, value);
-        }
-        
-        private double _bottomGalleryItemSize;
-        public double BottomGalleryItemSize
-        {
-            get => _bottomGalleryItemSize;
-            set => this.RaiseAndSetIfChanged(ref _bottomGalleryItemSize, value);
-        }
-
         #region strings
 
         private string? _getFlipped;
@@ -942,6 +962,14 @@ namespace PicView.Avalonia.ViewModels
             set => this.RaiseAndSetIfChanged(ref _titleMaxWidth, value);
         }
 
+        private Thickness _imageMargin;
+
+        public Thickness ImageMargin
+        {
+            get => _imageMargin;
+            set => this.RaiseAndSetIfChanged(ref _imageMargin, value);
+        }
+
         #endregion Size
 
         #region Zoom
@@ -1668,7 +1696,7 @@ namespace PicView.Avalonia.ViewModels
 
             ToggleGalleryCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleGallery);
 
-            ToggleBottomGalleryCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleBottomGallery);
+            ToggleBottomGalleryCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.OpenCloseBottomGallery);
 
             #endregion Gallery Commands
 
@@ -1689,7 +1717,7 @@ namespace PicView.Avalonia.ViewModels
             ChangeTopMostCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.SetTopMost);
 
             ToggleSubdirectoriesCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleSubdirectories);
-            
+
             ToggleLoopingCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleLooping);
 
             #endregion Settings commands

+ 90 - 77
src/PicView.Avalonia/Views/GalleryView.axaml

@@ -1,12 +1,12 @@
 <UserControl
-    mc:Ignorable="d"
     x:Class="PicView.Avalonia.Views.GalleryView"
-    x:DataType="viewModels:MainViewModel"
     xmlns="https://github.com/avaloniaui"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     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">
+    x:DataType="viewModels:MainViewModel"
+    mc:Ignorable="d">
     <Design.DataContext>
         <viewModels:MainViewModel />
     </Design.DataContext>
@@ -20,176 +20,208 @@
                     <MenuItem Header="Adjust size">
                         <MenuItem.Icon>
                             <Path
+                                Width="12"
+                                Height="12"
                                 Data="{StaticResource ImageGeometry}"
                                 Fill="{StaticResource MainIconColor}"
-                                Height="12"
-                                Stretch="Fill"
-                                Width="12" />
+                                Stretch="Fill" />
                         </MenuItem.Icon>
                     </MenuItem>
                     <Separator />
                     <MenuItem Command="{CompiledBinding ToggleGalleryCommand}" Header="{CompiledBinding Close}">
                         <MenuItem.Icon>
                             <Path
+                                Width="12"
+                                Height="12"
                                 Data="{StaticResource CloseGeometry}"
                                 Fill="{StaticResource MainIconColor}"
-                                Height="12"
-                                Stretch="Fill"
-                                Width="12" />
+                                Stretch="Fill" />
                         </MenuItem.Icon>
                     </MenuItem>
                 </ContextMenu>
             </Panel.ContextMenu>
+
+            <Button
+                Width="50"
+                Height="60"
+                HorizontalAlignment="Right"
+                VerticalAlignment="Top"
+                BorderThickness="1,0,0,0"
+                Classes="ButtonBorder altHover"
+                Command="{CompiledBinding ToggleGalleryCommand}"
+                CornerRadius="0,0,0,45"
+                DockPanel.Dock="Right"
+                IsVisible="{CompiledBinding IsGalleryCloseIconVisible}"
+                ZIndex="99">
+                <Path
+                    Width="23"
+                    Height="23"
+                    Margin="7,0,0,11"
+                    Data="{StaticResource CloseGeometry}"
+                    Fill="{StaticResource MainIconColor}"
+                    Stretch="Fill" />
+            </Button>
+
             <ListBox
+                x:Name="GalleryListBox"
+                Padding="0"
                 AutoScrollToSelectedItem="True"
                 Background="Transparent"
                 BorderThickness="0"
+                IsVisible="{CompiledBinding !!GalleryItems.Count}"
                 ItemsSource="{CompiledBinding GalleryItems}"
-                Margin="0,40,0,0"
                 PointerWheelChanged="GalleryListBox_OnPointerWheelChanged"
                 ScrollViewer.IsScrollInertiaEnabled="True"
                 ScrollViewer.VerticalScrollBarVisibility="Disabled"
-                SelectedItem="{CompiledBinding SelectedGalleryItem}"
-                x:Name="GalleryListBox">
+                SelectedItem="{CompiledBinding SelectedGalleryItem}">
                 <ListBox.ItemsPanel>
                     <ItemsPanelTemplate>
-                        <WrapPanel Orientation="Vertical" />
+                        <WrapPanel Orientation="{CompiledBinding GalleryOrientation}" />
                     </ItemsPanelTemplate>
                 </ListBox.ItemsPanel>
                 <ListBox.ItemTemplate>
                     <DataTemplate>
                         <Border
+                            Height="{Binding #GalleryListBox.((viewModels:MainViewModel)DataContext).GalleryItemSize}"
                             Background="Transparent"
                             BorderThickness="1"
                             CornerRadius="8"
-                            Height="{CompiledBinding ThumbNailSize}"
                             PointerPressed="InputElement_OnPointerPressed"
                             ToolTip.HorizontalOffset="0"
                             ToolTip.Placement="TopEdgeAlignedLeft"
                             ToolTip.VerticalOffset="0">
-                            <Image Source="{CompiledBinding GetSource}" Stretch="UniformToFill" />
+                            <Image
+                                Height="{Binding #GalleryListBox.((viewModels:MainViewModel)DataContext).GalleryItemSize}"
+                                Source="{CompiledBinding GetSource}"
+                                Stretch="UniformToFill" />
                             <ToolTip.Tip>
                                 <StackPanel>
                                     <TextBlock
+                                        Margin="0,0,0,2"
                                         Classes="txt"
                                         FontFamily="/Assets/Fonts/Roboto-Bold.ttf#Roboto"
                                         FontSize="14"
-                                        Margin="0,0,0,2"
                                         Text="{CompiledBinding FileName}" />
                                     <TextBlock
-                                        Classes="txt"
                                         Margin="0,0,0,2"
+                                        Classes="txt"
                                         Text="{CompiledBinding FileLocation}" />
                                     <TextBlock
-                                        Classes="txt"
                                         Margin="0,0,0,2"
+                                        Classes="txt"
                                         Text="{CompiledBinding FileSize}" />
                                     <TextBlock Classes="txt" Text="{CompiledBinding FileDate}" />
                                 </StackPanel>
                             </ToolTip.Tip>
                             <Border.ContextMenu>
                                 <ContextMenu>
-                                    <MenuItem Header="{CompiledBinding Print}">
+                                    <MenuItem Header="{CompiledBinding #GalleryListBox.((viewModels:MainViewModel)DataContext).Print}">
                                         <MenuItem.Icon>
                                             <Path
+                                                Width="12"
+                                                Height="12"
                                                 Data="{StaticResource PrintGeometry}"
                                                 Fill="{StaticResource MainIconColor}"
-                                                Height="12"
-                                                Stretch="Fill"
-                                                Width="12" />
+                                                Stretch="Fill" />
                                         </MenuItem.Icon>
                                     </MenuItem>
-                                    <MenuItem Header="{CompiledBinding OpenWith}">
+                                    <MenuItem Header="{CompiledBinding #GalleryListBox.((viewModels:MainViewModel)DataContext).OpenWith}">
                                         <MenuItem.Icon>
                                             <Path
+                                                Width="12"
+                                                Height="12"
                                                 Data="{StaticResource OpenWithGeometry}"
                                                 Fill="{StaticResource MainIconColor}"
-                                                Height="12"
-                                                Stretch="Fill"
-                                                Width="12" />
+                                                Stretch="Fill" />
                                         </MenuItem.Icon>
                                     </MenuItem>
-                                    <MenuItem Header="{CompiledBinding ShowInFolder}">
+                                    <MenuItem Header="{CompiledBinding #GalleryListBox.((viewModels:MainViewModel)DataContext).ShowInFolder}">
                                         <MenuItem.Icon>
                                             <Path
+                                                Width="12"
+                                                Height="12"
                                                 Data="{StaticResource ShowInFolderGeometry}"
                                                 Fill="{StaticResource MainIconColor}"
-                                                Height="12"
-                                                Stretch="Fill"
-                                                Width="12" />
+                                                Stretch="Fill" />
                                         </MenuItem.Icon>
                                     </MenuItem>
                                     <Separator />
-                                    <MenuItem Header="{CompiledBinding SetAsWallpaper}">
+                                    <MenuItem Header="{CompiledBinding #GalleryListBox.((viewModels:MainViewModel)DataContext).SetAsWallpaper}">
                                         <MenuItem.Icon>
                                             <Path
+                                                Width="12"
+                                                Height="12"
                                                 Data="{StaticResource PanoramaGeometry}"
                                                 Fill="{StaticResource MainIconColor}"
-                                                Height="12"
-                                                Stretch="Fill"
-                                                Width="12" />
+                                                Stretch="Fill" />
                                         </MenuItem.Icon>
                                     </MenuItem>
-                                    <MenuItem Header="{CompiledBinding SetAsLockScreenImage}">
+                                    <MenuItem Header="{CompiledBinding #GalleryListBox.((viewModels:MainViewModel)DataContext).SetAsLockScreenImage}">
                                         <MenuItem.Icon>
                                             <Path
+                                                Width="12"
+                                                Height="12"
                                                 Data="{StaticResource PanoramaGeometry}"
                                                 Fill="{StaticResource MainIconColor}"
-                                                Height="12"
-                                                Stretch="Fill"
-                                                Width="12" />
+                                                Stretch="Fill" />
                                         </MenuItem.Icon>
                                     </MenuItem>
                                     <Separator />
-                                    <MenuItem Header="{CompiledBinding CopyFile}">
+                                    <MenuItem Header="{CompiledBinding #GalleryListBox.((viewModels:MainViewModel)DataContext).CopyFile}">
                                         <MenuItem.Icon>
                                             <Path
+                                                Width="12"
+                                                Height="12"
                                                 Data="{StaticResource CopyGeometry}"
                                                 Fill="{StaticResource MainIconColor}"
-                                                Height="12"
-                                                Stretch="Fill"
-                                                Width="12" />
+                                                Stretch="Fill" />
                                         </MenuItem.Icon>
                                     </MenuItem>
-                                    <MenuItem Header="{CompiledBinding CopyImage}">
+                                    <MenuItem Header="{CompiledBinding #GalleryListBox.((viewModels:MainViewModel)DataContext).CopyImage}">
                                         <MenuItem.Icon>
                                             <Path
+                                                Width="12"
+                                                Height="12"
                                                 Data="{StaticResource CopyGeometry}"
                                                 Fill="{StaticResource MainIconColor}"
-                                                Height="12"
-                                                Stretch="Fill"
-                                                Width="12" />
+                                                Stretch="Fill" />
                                         </MenuItem.Icon>
                                     </MenuItem>
-                                    <MenuItem Header="{CompiledBinding CopyBase64}">
+                                    <MenuItem>
+                                        <MenuItem.Header>
+                                            <TextBlock>
+                                                <Run Text="{CompiledBinding #GalleryListBox.((viewModels:MainViewModel)DataContext).Copy}" />
+                                                <Run Text=" + base64" />
+                                            </TextBlock>
+                                        </MenuItem.Header>
                                         <MenuItem.Icon>
                                             <Path
+                                                Width="12"
+                                                Height="12"
                                                 Data="{StaticResource CopyGeometry}"
                                                 Fill="{StaticResource MainIconColor}"
-                                                Height="12"
-                                                Stretch="Fill"
-                                                Width="12" />
+                                                Stretch="Fill" />
                                         </MenuItem.Icon>
                                     </MenuItem>
                                     <Separator />
-                                    <MenuItem Header="{CompiledBinding FileCut}">
+                                    <MenuItem Header="{CompiledBinding #GalleryListBox.((viewModels:MainViewModel)DataContext).FileCut}">
                                         <MenuItem.Icon>
                                             <Path
+                                                Width="12"
+                                                Height="12"
                                                 Data="{StaticResource CutGeometry}"
                                                 Fill="{StaticResource MainIconColor}"
-                                                Height="12"
-                                                Stretch="Fill"
-                                                Width="12" />
+                                                Stretch="Fill" />
                                         </MenuItem.Icon>
                                     </MenuItem>
-                                    <MenuItem Click="RecycleItem" Header="{CompiledBinding Delete}">
+                                    <MenuItem Click="RecycleItem" Header="{CompiledBinding #GalleryListBox.((viewModels:MainViewModel)DataContext).DeleteFile}">
                                         <MenuItem.Icon>
                                             <Path
+                                                Width="12"
+                                                Height="12"
                                                 Data="{StaticResource RecycleGeometry}"
                                                 Fill="{StaticResource MainIconColor}"
-                                                Height="12"
-                                                Stretch="Fill"
-                                                Width="12" />
+                                                Stretch="Fill" />
                                         </MenuItem.Icon>
                                     </MenuItem>
                                 </ContextMenu>
@@ -198,25 +230,6 @@
                     </DataTemplate>
                 </ListBox.ItemTemplate>
             </ListBox>
-            <Button
-                BorderThickness="1,0,0,0"
-                Classes="ButtonBorder altHover"
-                Command="{CompiledBinding ToggleGalleryCommand}"
-                CornerRadius="0,0,0,45"
-                DockPanel.Dock="Right"
-                Height="60"
-                HorizontalAlignment="Right"
-                VerticalAlignment="Top"
-                Width="50"
-                ZIndex="99">
-                <Path
-                    Data="{StaticResource CloseGeometry}"
-                    Fill="{StaticResource MainIconColor}"
-                    Height="23"
-                    Margin="7,0,0,11"
-                    Stretch="Fill"
-                    Width="23" />
-            </Button>
         </Panel>
     </Border>
 </UserControl>

+ 5 - 1
src/PicView.Avalonia/Views/GalleryView.axaml.cs

@@ -91,7 +91,11 @@ public partial class GalleryView : UserControl
         {
             return;
         }
-        _ = FunctionsHelper.ToggleGallery();
+
+        if (GalleryFunctions.isFullGalleryOpen)
+        {
+           await GalleryFunctions.ToggleGallery(vm);
+        }
 
 #if DEBUG
         Debug.Assert(sender != null, nameof(sender) + " != null");

+ 1 - 0
src/PicView.Avalonia/Views/ImageViewer.axaml

@@ -18,6 +18,7 @@
         <LayoutTransformControl x:Name="ImageLayoutTransformControl">
             <ScrollViewer
                 x:Name="ImageScrollViewer"
+                Margin="{CompiledBinding ImageMargin}"
                 Focusable="False"
                 ScrollChanged="ImageScrollViewer_OnScrollChanged"
                 VerticalScrollBarVisibility="{Binding ToggleScrollBarVisibility}">

+ 1 - 4
src/PicView.Avalonia/Views/MainView.axaml

@@ -425,9 +425,6 @@
     </UserControl.ContextMenu>
     <Panel x:Name="MainGrid">
         <ContentControl Content="{CompiledBinding CurrentView}" />
-        <views:GalleryView
-            Width="{CompiledBinding $parent.Bounds.Width}"
-            Height="{CompiledBinding $parent.Bounds.Height}"
-            IsVisible="{CompiledBinding IsGalleryOpen}" />
+        <views:GalleryView VerticalAlignment="{CompiledBinding GalleryVerticalAlignment}" IsVisible="{CompiledBinding IsGalleryOpen}" />
     </Panel>
 </UserControl>

+ 20 - 4
src/PicView.Core/Calculations/ImageSizeCalculationHelper.cs

@@ -1,14 +1,17 @@
-using System.Runtime.InteropServices;
+using PicView.Core.Config;
+using System.Runtime.InteropServices;
 
 namespace PicView.Core.Calculations;
 
 public static class ImageSizeCalculationHelper
 {
-    public struct ImageSize(double width, double height, double titleMaxWidth)
+    public struct ImageSize(double width, double height, double titleMaxWidth, double margin)
     {
         public double TitleMaxWidth { get; private set; } = titleMaxWidth;
         public double Width { get; private set; } = width;
         public double Height { get; private set; } = height;
+
+        public double Margin { get; private set; } = margin;
     }
 
     public static double GetInterfaceSize()
@@ -38,11 +41,12 @@ public static class ImageSizeCalculationHelper
     {
         if (width <= 0 || height <= 0 || rotationAngle > 360 || rotationAngle < 0)
         {
-            return new ImageSize(0, 0, 0);
+            return new ImageSize(0, 0, 0, 0);
         }
 
         double aspectRatio;
         double maxWidth, maxHeight;
+        var margin = 0d;
 
         var borderSpaceHeight = fullscreen ? 0 : uiTopSize + uiBottomSize + galleryHeight;
         var borderSpaceWidth = fullscreen ? 0 : padding;
@@ -63,6 +67,18 @@ public static class ImageSizeCalculationHelper
                 : Math.Min(containerHeight - galleryHeight, height);
         }
 
+        if (SettingsHelper.Settings.Gallery.IsBottomGalleryShown)
+        {
+            if (!SettingsHelper.Settings.UIProperties.ShowInterface && !SettingsHelper.Settings.Gallery.ShowBottomGalleryInHiddenUI)
+            {
+                margin = 0;
+            }
+            else
+            {
+                margin = galleryHeight > 0 ? galleryHeight : 0;
+            }
+        }
+
         // aspect ratio calculation
         switch (rotationAngle)
         {
@@ -91,7 +107,7 @@ public static class ImageSizeCalculationHelper
         var titleMaxWidth = GetTitleMaxWidth(rotationAngle, xWidth, xHeight, monitorMinWidth, monitorMinHeight,
             monitorWidth, monitorHeight, interfaceSize, autoFit, containerWidth, scrollEnabled);
 
-        return new ImageSize(xWidth, xHeight, titleMaxWidth);
+        return new ImageSize(xWidth, xHeight, titleMaxWidth, margin);
     }
 
     public static double GetTitleMaxWidth(double rotationAngle, double width, double height, double monitorMinWidth,

+ 1 - 15
src/PicView.Core/Gallery/GalleryThumbInfo.cs

@@ -43,20 +43,6 @@ public class GalleryThumbInfo
         /// </summary>
         public string FileDate { get; set; }
 
-        public string Print => TranslationHelper.GetTranslation("Print");
-        public string OpenWith => TranslationHelper.GetTranslation("OpenWith");
-        public string ShowInFolder => TranslationHelper.GetTranslation("ShowInFolder");
-
-        public string SetAsWallpaper => TranslationHelper.GetTranslation("SetAsWallpaper");
-        public string SetAsLockScreenImage => TranslationHelper.GetTranslation("SetAsLockScreenImage");
-
-        public string CopyImage => TranslationHelper.GetTranslation("CopyImage");
-        public string CopyFile => TranslationHelper.GetTranslation("CopyFile");
-        public string CopyBase64 => $"{TranslationHelper.GetTranslation("Copy")} base64";
-
-        public string FileCut => TranslationHelper.GetTranslation("FileCut");
-        public string Delete => TranslationHelper.GetTranslation("DeleteFile");
-
         /// <summary>
         /// Gets or sets the source of the thumbnail.
         /// </summary>
@@ -76,7 +62,7 @@ public class GalleryThumbInfo
                 }
             }
         }
-        
+
         public double ThumbNailSize { get; set; }
 
         /// <summary>